diff --git a/DEPS b/DEPS index 124107f..0f11c16 100644 --- a/DEPS +++ b/DEPS
@@ -133,7 +133,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': '9b86955c65aab21ccc921116eb3cb38aa85ea417', + 'skia_revision': '2b8b06e79309f7d6441d0251e1bca0d81a7c1713', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -145,15 +145,15 @@ # 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': 'f1e3609c24ce71b70a748da65573d0cf17cbab09', + 'angle_revision': '0a1eeb80641a30db9b27bafc78e0fcfd6ac792c1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': 'a7a375565cdb8161657f696fc3e55a757edccafa', + 'swiftshader_revision': '8ef6d1fe29cc891de7ea1b191e48c83429a3b137', # 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': '6f838880122660f1ae62b52a7cc11d840a1c2f81', + 'pdfium_revision': '3475b482fefaed065d634f235140f5b7e9b6df01', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -252,7 +252,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'spv_tools_revision': '2947e88f793824cf62ffb44f6e99a20f8054c388', + 'spv_tools_revision': 'e935dac9ef8a01fdb6d0a4b7898563e6f62d1081', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -272,7 +272,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'quiche_revision': '7eef071bd3d6738a167533695485c559310435bf', + 'quiche_revision': '8eb45e950572f179000f13d707d6392619e929cb', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ios_webkit # and whatever else without interference from each other. @@ -802,7 +802,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'fa6ebdcd266e6b1161d30ce500149c151c8da206', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'ccf1a17964ab7200e4c4d16e8c17483b4fb17520', 'condition': 'checkout_linux', }, @@ -827,7 +827,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '42db0b42abadb3dea03f6ff8d76fcea6f21003fb', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '417f2332fcf4aaebee260e98046d850833bf0487', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -1348,7 +1348,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '6f0b34abee8dba611c253738d955c59f703c147a', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '2ebf5239782bf6b46d4aa812f34fa9f9e5a02be9', + Var('webrtc_git') + '/src.git' + '@' + '5fc28b11a029b22c341c59dac8e766c178b02d95', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1389,7 +1389,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@02f2aec134517824b0a6fe01d2ed476d729a3a8e', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@58d7304e63dcc83715e89df078494f75acc4b257', 'condition': 'checkout_src_internal', },
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 565329d..279ae36b 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -848,11 +848,11 @@ 'build/android/gyp/dexsplitter.pydeps', 'build/android/gyp/dex.pydeps', 'build/android/gyp/dist_aar.pydeps', - 'build/android/gyp/emma_instr.pydeps', 'build/android/gyp/filter_zip.pydeps', 'build/android/gyp/gcc_preprocess.pydeps', 'build/android/gyp/generate_linker_version_script.pydeps', 'build/android/gyp/ijar.pydeps', + 'build/android/gyp/jacoco_instr.pydeps', 'build/android/gyp/java_cpp_enum.pydeps', 'build/android/gyp/java_cpp_strings.pydeps', 'build/android/gyp/javac.pydeps',
diff --git a/WATCHLISTS b/WATCHLISTS index dc0ed30f..941dc21 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -787,6 +787,9 @@ 'filepath': 'chrome/browser/ui/webui/chromeos/|'\ 'chrome/browser/resources/chromeos/', }, + 'chromevox': { + 'filepath': 'chromevox', + }, 'clang_update': { 'filepath': 'tools/clang/scripts/update.py' }, @@ -1976,10 +1979,7 @@ 'kbabbitt@microsoft.com', 'nektar@chromium.org'], 'blink_animation': ['alexis.menard@intel.com', - 'blink-reviews-animation@chromium.org', - 'ericwilligers@chromium.org', - 'rjwright@chromium.org', - 'shans@chromium.org'], + 'blink-reviews-animation@chromium.org'], 'blink_app_banner': ['mlamouri+watch-blink@chromium.org'], 'blink_audio': ['hongchan@chromium.org', 'rtoy@chromium.org'], @@ -2209,6 +2209,7 @@ 'chromeos_power': ['derat+watch@chromium.org'], 'chromeos_timezone': ['alemate+watch@chromium.org'], 'chromeos_webui': ['alemate+watch@chromium.org'], + 'chromevox': ['anastasi+watch@google.com'], 'clang_update': ['dcheng@chromium.org', 'dmikurube+clang@chromium.org', 'eugenis+clang@chromium.org', @@ -2500,7 +2501,8 @@ 'vakh+watch@chromium.org'], 'screen_orientation': ['mlamouri+watch-screen-orientation@chromium.org'], 'security': ['security-watchlist@chromium.org'], - 'select_to_speak': ['katie+watch@chromium.org'], + 'select_to_speak': ['katie+watch@chromium.org', + 'anastasi+watch@google.com'], 'send_tab_to_self': ['hansberry+watch-send_tab_to_self@chromium.org', 'jeffreycohen+watch-send_tab_to_self@chromium.org', 'jlklein+watch-send_tab_to_self@chromium.org',
diff --git a/ash/session/multiprofiles_intro_dialog.cc b/ash/session/multiprofiles_intro_dialog.cc index 51258ab..796e48c 100644 --- a/ash/session/multiprofiles_intro_dialog.cc +++ b/ash/session/multiprofiles_intro_dialog.cc
@@ -43,7 +43,7 @@ } bool MultiprofilesIntroDialog::Accept() { - std::move(on_accept_).Run(true, never_show_again_checkbox_->checked()); + std::move(on_accept_).Run(true, never_show_again_checkbox_->GetChecked()); return true; }
diff --git a/ash/session/teleport_warning_dialog.cc b/ash/session/teleport_warning_dialog.cc index 4fbaf050..5d5f88a 100644 --- a/ash/session/teleport_warning_dialog.cc +++ b/ash/session/teleport_warning_dialog.cc
@@ -52,7 +52,7 @@ } bool TeleportWarningDialog::Accept() { - std::move(on_accept_).Run(true, never_show_again_checkbox_->checked()); + std::move(on_accept_).Run(true, never_show_again_checkbox_->GetChecked()); return true; }
diff --git a/ash/shelf/login_shelf_view.cc b/ash/shelf/login_shelf_view.cc index 33014b4..deef79b 100644 --- a/ash/shelf/login_shelf_view.cc +++ b/ash/shelf/login_shelf_view.cc
@@ -16,7 +16,6 @@ #include "ash/login/ui/lock_screen.h" #include "ash/public/cpp/ash_constants.h" #include "ash/public/cpp/login_constants.h" -#include "ash/public/interfaces/kiosk_app_info.mojom.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/root_window_controller.h" #include "ash/session/session_controller_impl.h"
diff --git a/ash/system/message_center/notifier_settings_view.cc b/ash/system/message_center/notifier_settings_view.cc index 21a077d..a56752f8 100644 --- a/ash/system/message_center/notifier_settings_view.cc +++ b/ash/system/message_center/notifier_settings_view.cc
@@ -332,8 +332,8 @@ checkbox_->SetChecked(checked); } -bool NotifierSettingsView::NotifierButton::checked() const { - return checkbox_->checked(); +bool NotifierSettingsView::NotifierButton::GetChecked() const { + return checkbox_->GetChecked(); } void NotifierSettingsView::NotifierButton::ButtonPressed( @@ -343,7 +343,7 @@ // The checkbox state has already changed at this point, but we'll update // the state on NotifierSettingsView::ButtonPressed() too, so here change // back to the previous state. - checkbox_->SetChecked(!checkbox_->checked()); + checkbox_->SetChecked(!checkbox_->GetChecked()); Button::NotifyClick(event); } @@ -611,9 +611,9 @@ return; NotifierButton* button = *iter; - button->SetChecked(!button->checked()); + button->SetChecked(!button->GetChecked()); Shell::Get()->message_center_controller()->SetNotifierEnabled( - button->notifier_id(), button->checked()); + button->notifier_id(), button->GetChecked()); Shell::Get()->message_center_controller()->RequestNotifierSettingsUpdate(); }
diff --git a/ash/system/message_center/notifier_settings_view.h b/ash/system/message_center/notifier_settings_view.h index 7a570ad..464bc5b 100644 --- a/ash/system/message_center/notifier_settings_view.h +++ b/ash/system/message_center/notifier_settings_view.h
@@ -61,7 +61,7 @@ void UpdateIconImage(const gfx::ImageSkia& icon); void SetChecked(bool checked); - bool checked() const; + bool GetChecked() const; const message_center::NotifierId& notifier_id() const { return notifier_id_; }
diff --git a/base/metrics/field_trial_param_associator.h b/base/metrics/field_trial_param_associator.h index b35e2cc5..17c2b3c7 100644 --- a/base/metrics/field_trial_param_associator.h +++ b/base/metrics/field_trial_param_associator.h
@@ -12,6 +12,7 @@ #include "base/base_export.h" #include "base/memory/singleton.h" #include "base/metrics/field_trial.h" +#include "base/metrics/field_trial_params.h" #include "base/synchronization/lock.h" namespace base { @@ -23,9 +24,6 @@ FieldTrialParamAssociator(); ~FieldTrialParamAssociator(); - // Key-value mapping type for field trial parameters. - typedef std::map<std::string, std::string> FieldTrialParams; - // Retrieve the singleton. static FieldTrialParamAssociator* GetInstance();
diff --git a/base/metrics/field_trial_params.cc b/base/metrics/field_trial_params.cc index f01db0f..0680d50 100644 --- a/base/metrics/field_trial_params.cc +++ b/base/metrics/field_trial_params.cc
@@ -11,22 +11,21 @@ namespace base { -bool AssociateFieldTrialParams( - const std::string& trial_name, - const std::string& group_name, - const std::map<std::string, std::string>& params) { +bool AssociateFieldTrialParams(const std::string& trial_name, + const std::string& group_name, + const FieldTrialParams& params) { return base::FieldTrialParamAssociator::GetInstance() ->AssociateFieldTrialParams(trial_name, group_name, params); } bool GetFieldTrialParams(const std::string& trial_name, - std::map<std::string, std::string>* params) { + FieldTrialParams* params) { return base::FieldTrialParamAssociator::GetInstance()->GetFieldTrialParams( trial_name, params); } bool GetFieldTrialParamsByFeature(const base::Feature& feature, - std::map<std::string, std::string>* params) { + FieldTrialParams* params) { if (!base::FeatureList::IsEnabled(feature)) return false; @@ -39,7 +38,7 @@ std::string GetFieldTrialParamValue(const std::string& trial_name, const std::string& param_name) { - std::map<std::string, std::string> params; + FieldTrialParams params; if (GetFieldTrialParams(trial_name, ¶ms)) { auto it = params.find(param_name); if (it != params.end())
diff --git a/base/metrics/field_trial_params.h b/base/metrics/field_trial_params.h index e5a7f8e0..b2e838f 100644 --- a/base/metrics/field_trial_params.h +++ b/base/metrics/field_trial_params.h
@@ -14,14 +14,16 @@ struct Feature; +// Key-value mapping type for field trial parameters. +typedef std::map<std::string, std::string> FieldTrialParams; + // Associates the specified set of key-value |params| with the field trial // specified by |trial_name| and |group_name|. Fails and returns false if the // specified field trial already has params associated with it or the trial // is already active (group() has been called on it). Thread safe. -BASE_EXPORT bool AssociateFieldTrialParams( - const std::string& trial_name, - const std::string& group_name, - const std::map<std::string, std::string>& params); +BASE_EXPORT bool AssociateFieldTrialParams(const std::string& trial_name, + const std::string& group_name, + const FieldTrialParams& params); // Retrieves the set of key-value |params| for the specified field trial, based // on its selected group. If the field trial does not exist or its selected @@ -29,9 +31,8 @@ // does not modify |params|. Calling this function will result in the field // trial being marked as active if found (i.e. group() will be called on it), // if it wasn't already. Thread safe. -BASE_EXPORT bool GetFieldTrialParams( - const std::string& trial_name, - std::map<std::string, std::string>* params); +BASE_EXPORT bool GetFieldTrialParams(const std::string& trial_name, + FieldTrialParams* params); // Retrieves the set of key-value |params| for the field trial associated with // the specified |feature|. A feature is associated with at most one field @@ -40,9 +41,8 @@ // returns false and does not modify |params|. Calling this function will // result in the associated field trial being marked as active if found (i.e. // group() will be called on it), if it wasn't already. Thread safe. -BASE_EXPORT bool GetFieldTrialParamsByFeature( - const base::Feature& feature, - std::map<std::string, std::string>* params); +BASE_EXPORT bool GetFieldTrialParamsByFeature(const base::Feature& feature, + FieldTrialParams* params); // Retrieves a specific parameter value corresponding to |param_name| for the // specified field trial, based on its selected group. If the field trial does
diff --git a/base/task/OWNERS b/base/task/OWNERS index c32490a..42f0e57 100644 --- a/base/task/OWNERS +++ b/base/task/OWNERS
@@ -1,6 +1,9 @@ fdoray@chromium.org gab@chromium.org robliao@chromium.org +alexclarke@chromium.org +altimin@chromium.org +skyosti@lchromium.org # TEAM: scheduler-dev@chromium.org -# COMPONENT: Internals>ThreadPool +# COMPONENT: Internals>TaskScheduling
diff --git a/base/task/sequence_manager/OWNERS b/base/task/sequence_manager/OWNERS index ac6eae86..2ef3011 100644 --- a/base/task/sequence_manager/OWNERS +++ b/base/task/sequence_manager/OWNERS
@@ -3,4 +3,4 @@ skyostil@chromium.org # TEAM: scheduler-dev@chromium.org -# Component: Blink>Scheduling +# Component: Internals>SequenceManager
diff --git a/base/test/data/pe_image/pe_image_test_arm64.dll b/base/test/data/pe_image/pe_image_test_arm64.dll new file mode 100755 index 0000000..27b8337 --- /dev/null +++ b/base/test/data/pe_image/pe_image_test_arm64.dll Binary files differ
diff --git a/base/win/pe_image_unittest.cc b/base/win/pe_image_unittest.cc index 9f810da7..302c872 100644 --- a/base/win/pe_image_unittest.cc +++ b/base/win/pe_image_unittest.cc
@@ -88,18 +88,41 @@ return true; } +base::FilePath GetPEImageTestPath() { + base::FilePath pe_image_test_path; + EXPECT_TRUE(PathService::Get(DIR_TEST_DATA, &pe_image_test_path)); + pe_image_test_path = pe_image_test_path.Append(FILE_PATH_LITERAL("pe_image")); +#if defined(ARCH_CPU_ARM64) + pe_image_test_path = + pe_image_test_path.Append(FILE_PATH_LITERAL("pe_image_test_arm64.dll")); +#elif defined(ARCH_CPU_X86_64) + pe_image_test_path = + pe_image_test_path.Append(FILE_PATH_LITERAL("pe_image_test_64.dll")); +#elif defined(ARCH_CPU_X86) + pe_image_test_path = + pe_image_test_path.Append(FILE_PATH_LITERAL("pe_image_test_32.dll")); +#else +#error This platform is not supported. +#endif + return pe_image_test_path; +} + } // namespace // Tests that we are able to enumerate stuff from a PE file, and that // the actual number of items found matches an expected value. TEST(PEImageTest, EnumeratesPE) { - base::FilePath pe_image_test_path; - ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &pe_image_test_path)); - pe_image_test_path = pe_image_test_path.Append(FILE_PATH_LITERAL("pe_image")); + base::FilePath pe_image_test_path = GetPEImageTestPath(); -#if defined(ARCH_CPU_64_BITS) - pe_image_test_path = - pe_image_test_path.Append(FILE_PATH_LITERAL("pe_image_test_64.dll")); +#if defined(ARCH_CPU_ARM64) + const int sections = 7; + const int imports_dlls = 3; + const int delay_dlls = 2; + const int exports = 3; + const int imports = 72; + const int delay_imports = 2; + const int relocs = 740; +#elif defined(ARCH_CPU_64_BITS) const int sections = 6; const int imports_dlls = 2; const int delay_dlls = 2; @@ -108,8 +131,6 @@ const int delay_imports = 2; const int relocs = 976; #else - pe_image_test_path = - pe_image_test_path.Append(FILE_PATH_LITERAL("pe_image_test_32.dll")); const int sections = 5; const int imports_dlls = 2; const int delay_dlls = 2; @@ -173,17 +194,7 @@ // Tests that we can locate a forwarded export. TEST(PEImageTest, ForwardedExport) { - base::FilePath pe_image_test_path; - ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &pe_image_test_path)); - pe_image_test_path = pe_image_test_path.Append(FILE_PATH_LITERAL("pe_image")); - -#if defined(ARCH_CPU_64_BITS) - pe_image_test_path = - pe_image_test_path.Append(FILE_PATH_LITERAL("pe_image_test_64.dll")); -#else - pe_image_test_path = - pe_image_test_path.Append(FILE_PATH_LITERAL("pe_image_test_32.dll")); -#endif + base::FilePath pe_image_test_path = GetPEImageTestPath(); ScopedNativeLibrary module(pe_image_test_path);
diff --git a/build/android/buildhooks/BUILD.gn b/build/android/buildhooks/BUILD.gn index 0ccd4ce..bb75c12 100644 --- a/build/android/buildhooks/BUILD.gn +++ b/build/android/buildhooks/BUILD.gn
@@ -2,11 +2,11 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//build/config/android/rules.gni") import("//build/config/android/config.gni") +import("//build/config/android/rules.gni") java_library("build_hooks_java") { - emma_never_instrument = true + jacoco_never_instrument = true java_files = [ "java/org/chromium/build/BuildHooks.java" ] # Make all targets pull in the try-with-resources support files. @@ -35,7 +35,7 @@ build_hooks_android_impl = "java/org/chromium/build/BuildHooksAndroidImpl.java" android_library("build_hooks_android_java") { - emma_never_instrument = true + jacoco_never_instrument = true java_files = [ "java/org/chromium/build/BuildHooksAndroid.java", build_hooks_android_impl, @@ -49,7 +49,7 @@ # This default implementation is used if an android_apk target doesn't # specify a different implementation via build_hooks_android_impl_deps. android_library("build_hooks_android_impl_java") { - emma_never_instrument = true + jacoco_never_instrument = true java_files = [ build_hooks_android_impl ] deps = [ ":build_hooks_android_java",
diff --git a/build/android/bytecode/BUILD.gn b/build/android/bytecode/BUILD.gn index bff74be..51fff21 100644 --- a/build/android/bytecode/BUILD.gn +++ b/build/android/bytecode/BUILD.gn
@@ -7,7 +7,7 @@ assert(current_toolchain == default_toolchain) java_binary("java_bytecode_rewriter") { - emma_never_instrument = true + jacoco_never_instrument = true java_files = [ "java/org/chromium/bytecode/AssertionEnablerClassAdapter.java", "java/org/chromium/bytecode/ByteCodeProcessor.java",
diff --git a/build/android/gyp/emma_instr.py b/build/android/gyp/emma_instr.py deleted file mode 100755 index 008a6cc..0000000 --- a/build/android/gyp/emma_instr.py +++ /dev/null
@@ -1,273 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2013 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Instruments classes and jar files. - -This script corresponds to the 'emma_instr' action in the java build process. -Depending on whether emma_instrument is set, the 'emma_instr' action will either -call the instrument command or the copy command. - -Possible commands are: -- instrument_jar: Accepts a jar and instruments it using emma.jar. -- copy: Called when EMMA coverage is not enabled. This allows us to make - this a required step without necessarily instrumenting on every build. - Also removes any stale coverage files. -""" - -from __future__ import print_function - -import collections -import json -import optparse -import os -import shutil -import sys -import tempfile - -from util import build_utils - - -def _AddCommonOptions(option_parser): - """Adds common options to |option_parser|.""" - option_parser.add_option('--input-path', - help=('Path to input file(s). Either the classes ' - 'directory, or the path to a jar.')) - option_parser.add_option('--output-path', - help=('Path to output final file(s) to. Either the ' - 'final classes directory, or the directory in ' - 'which to place the instrumented/copied jar.')) - option_parser.add_option('--coverage-file', - help='File to create with coverage metadata.') - option_parser.add_option('--sources-list-file', - help='File to create with the list of sources.') - - -def _AddInstrumentOptions(option_parser): - """Adds options related to instrumentation to |option_parser|.""" - _AddCommonOptions(option_parser) - option_parser.add_option('--source-dirs', - help='Space separated list of source directories. ' - 'source-files should not be specified if ' - 'source-dirs is specified') - option_parser.add_option('--source-files', - help='Space separated list of source files. ' - 'source-dirs should not be specified if ' - 'source-files is specified') - option_parser.add_option('--java-sources-file', - help='File containing newline-separated .java paths') - option_parser.add_option('--src-root', - help='Root of the src repository.') - option_parser.add_option('--emma-jar', - help='Path to emma.jar.') - option_parser.add_option( - '--filter-string', default='', - help=('Filter string consisting of a list of inclusion/exclusion ' - 'patterns separated with whitespace and/or comma.')) - - -def _RunCopyCommand(_command, options, _, option_parser): - """Copies the jar from input to output locations. - - Also removes any old coverage/sources file. - - Args: - command: String indicating the command that was received to trigger - this function. - options: optparse options dictionary. - args: List of extra args from optparse. - option_parser: optparse.OptionParser object. - - Returns: - An exit code. - """ - if not (options.input_path and options.output_path and - options.coverage_file and options.sources_list_file): - option_parser.error('All arguments are required.') - - if os.path.exists(options.coverage_file): - os.remove(options.coverage_file) - if os.path.exists(options.sources_list_file): - os.remove(options.sources_list_file) - - shutil.copy(options.input_path, options.output_path) - - -def _GetSourceDirsFromSourceFiles(source_files): - """Returns list of directories for the files in |source_files|. - - Args: - source_files: List of source files. - - Returns: - List of source directories. - """ - return list(set(os.path.dirname(source_file) for source_file in source_files)) - - -def _CreateSourcesListFile(source_dirs, sources_list_file, src_root): - """Adds all normalized source directories to |sources_list_file|. - - Args: - source_dirs: List of source directories. - sources_list_file: File into which to write the JSON list of sources. - src_root: Root which sources added to the file should be relative to. - - Returns: - An exit code. - """ - src_root = os.path.abspath(src_root) - relative_sources = [] - for s in source_dirs: - abs_source = os.path.abspath(s) - if abs_source[:len(src_root)] != src_root: - print('Error: found source directory not under repository root: %s %s' % - (abs_source, src_root)) - return 1 - rel_source = os.path.relpath(abs_source, src_root) - - relative_sources.append(rel_source) - - with open(sources_list_file, 'w') as f: - json.dump(relative_sources, f) - - -def _RunInstrumentCommand(_command, options, _, option_parser): - """Instruments jar files using EMMA. - - Args: - command: String indicating the command that was received to trigger - this function. - options: optparse options dictionary. - args: List of extra args from optparse. - option_parser: optparse.OptionParser object. - - Returns: - An exit code. - """ - if not (options.input_path and options.output_path and - options.coverage_file and options.sources_list_file and - (options.source_files or options.source_dirs or - options.java_sources_file) and - options.src_root and options.emma_jar): - option_parser.error('All arguments are required.') - - if os.path.exists(options.coverage_file): - os.remove(options.coverage_file) - temp_dir = tempfile.mkdtemp() - try: - cmd = ['java', '-cp', options.emma_jar, - 'emma', 'instr', - '-ip', options.input_path, - '-ix', options.filter_string, - '-d', temp_dir, - '-out', options.coverage_file, - '-m', 'fullcopy'] - build_utils.CheckOutput(cmd) - - # File is not generated when filter_string doesn't match any files. - if not os.path.exists(options.coverage_file): - build_utils.Touch(options.coverage_file) - - temp_jar_dir = os.path.join(temp_dir, 'lib') - jars = os.listdir(temp_jar_dir) - if len(jars) != 1: - print('Error: multiple output files in: %s' % (temp_jar_dir)) - return 1 - - # Delete output_path first to avoid modifying input_path in the case where - # input_path is a hardlink to output_path. http://crbug.com/571642 - if os.path.exists(options.output_path): - os.unlink(options.output_path) - shutil.move(os.path.join(temp_jar_dir, jars[0]), options.output_path) - finally: - shutil.rmtree(temp_dir) - - if options.source_dirs: - source_dirs = build_utils.ParseGnList(options.source_dirs) - else: - source_files = [] - if options.source_files: - source_files += build_utils.ParseGnList(options.source_files) - if options.java_sources_file: - source_files.extend( - build_utils.ReadSourcesList(options.java_sources_file)) - source_dirs = _GetSourceDirsFromSourceFiles(source_files) - - # TODO(GYP): In GN, we are passed the list of sources, detecting source - # directories, then walking them to re-establish the list of sources. - # This can obviously be simplified! - _CreateSourcesListFile(source_dirs, options.sources_list_file, - options.src_root) - - return 0 - - -CommandFunctionTuple = collections.namedtuple( - 'CommandFunctionTuple', ['add_options_func', 'run_command_func']) -VALID_COMMANDS = { - 'copy': CommandFunctionTuple(_AddCommonOptions, - _RunCopyCommand), - 'instrument_jar': CommandFunctionTuple(_AddInstrumentOptions, - _RunInstrumentCommand), -} - - -class CommandOptionParser(optparse.OptionParser): - """Wrapper class for OptionParser to help with listing commands.""" - - def __init__(self, *args, **kwargs): - """Creates a CommandOptionParser. - - Args: - commands_dict: A dictionary mapping command strings to an object defining - - add_options_func: Adds options to the option parser - - run_command_func: Runs the command itself. - example: An example command. - everything else: Passed to optparse.OptionParser contructor. - """ - self.commands_dict = kwargs.pop('commands_dict', {}) - self.example = kwargs.pop('example', '') - if not 'usage' in kwargs: - kwargs['usage'] = 'Usage: %prog <command> [options]' - optparse.OptionParser.__init__(self, *args, **kwargs) - - #override - def get_usage(self): - normal_usage = optparse.OptionParser.get_usage(self) - command_list = self.get_command_list() - example = self.get_example() - return self.expand_prog_name(normal_usage + example + command_list) - - #override - def get_command_list(self): - if self.commands_dict.keys(): - return '\nCommands:\n %s\n' % '\n '.join( - sorted(self.commands_dict.keys())) - return '' - - def get_example(self): - if self.example: - return '\nExample:\n %s\n' % self.example - return '' - - -def main(): - option_parser = CommandOptionParser(commands_dict=VALID_COMMANDS) - argv = sys.argv - - if len(argv) < 2 or argv[1] not in option_parser.commands_dict: - # Parse args first, if this is '--help', optparse will print help and exit - option_parser.parse_args(argv) - option_parser.error('Invalid command.') - - cmd = option_parser.commands_dict[argv[1]] - cmd.add_options_func(option_parser) - options, args = option_parser.parse_args(argv) - return cmd.run_command_func(argv[1], options, args, option_parser) - - -if __name__ == '__main__': - sys.exit(main())
diff --git a/build/android/gyp/jacoco_instr.py b/build/android/gyp/jacoco_instr.py new file mode 100755 index 0000000..cd37838 --- /dev/null +++ b/build/android/gyp/jacoco_instr.py
@@ -0,0 +1,150 @@ +#!/usr/bin/env python +# +# Copyright 2013 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Instruments classes and jar files. + +This script corresponds to the 'jacoco_instr' action in the java build process. +Depending on whether jacoco_instrument is set, the 'jacoco_instr' action will +call the instrument command which accepts a jar and instruments it using +jacococli.jar. + +""" + +from __future__ import print_function + +import argparse +import json +import os +import shutil +import sys +import tempfile + +from util import build_utils + + +def _AddArguments(parser): + """Adds arguments related to instrumentation to parser. + + Args: + parser: ArgumentParser object. + """ + parser.add_argument( + '--input-path', + required=True, + help=('Path to input file(s). Either the classes ' + 'directory, or the path to a jar.')) + parser.add_argument( + '--output-path', + required=True, + help=('Path to output final file(s) to. Either the ' + 'final classes directory, or the directory in ' + 'which to place the instrumented/copied jar.')) + parser.add_argument( + '--sources-list-file', + required=True, + help='File to create with the list of sources.') + parser.add_argument( + '--java-sources-file', + required=True, + help='File containing newline-separated .java paths') + parser.add_argument( + '--jacococli-jar', required=True, help='Path to jacococli.jar.') + + +def _GetSourceDirsFromSourceFiles(source_files): + """Returns list of directories for the files in |source_files|. + + Args: + source_files: List of source files. + + Returns: + List of source directories. + """ + return list(set(os.path.dirname(source_file) for source_file in source_files)) + + +def _CreateSourcesListFile(source_dirs, sources_list_file, src_root): + """Adds all normalized source directories to |sources_list_file|. + + Args: + source_dirs: List of source directories. + sources_list_file: File into which to write the JSON list of sources. + src_root: Root which sources added to the file should be relative to. + + Returns: + An exit code. + """ + src_root = os.path.abspath(src_root) + relative_sources = [] + for s in source_dirs: + abs_source = os.path.abspath(s) + if abs_source[:len(src_root)] != src_root: + print('Error: found source directory not under repository root: %s %s' % + (abs_source, src_root)) + return 1 + rel_source = os.path.relpath(abs_source, src_root) + + relative_sources.append(rel_source) + + with open(sources_list_file, 'w') as f: + json.dump(relative_sources, f) + + +def _RunInstrumentCommand(parser): + """Instruments jar files using Jacoco. + + Args: + parser: ArgumentParser object. + + Returns: + An exit code. + """ + args = parser.parse_args() + + temp_dir = tempfile.mkdtemp() + try: + cmd = [ + 'java', '-jar', args.jacococli_jar, 'instrument', args.input_path, + '--dest', temp_dir + ] + + build_utils.CheckOutput(cmd) + + jars = os.listdir(temp_dir) + if len(jars) != 1: + print('Error: multiple output files in: %s' % (temp_dir)) + return 1 + + # Delete output_path first to avoid modifying input_path in the case where + # input_path is a hardlink to output_path. http://crbug.com/571642 + if os.path.exists(args.output_path): + os.unlink(args.output_path) + shutil.move(os.path.join(temp_dir, jars[0]), args.output_path) + finally: + shutil.rmtree(temp_dir) + + source_files = [] + if args.java_sources_file: + source_files.extend(build_utils.ReadSourcesList(args.java_sources_file)) + source_dirs = _GetSourceDirsFromSourceFiles(source_files) + + # TODO(GYP): In GN, we are passed the list of sources, detecting source + # directories, then walking them to re-establish the list of sources. + # This can obviously be simplified! + _CreateSourcesListFile(source_dirs, args.sources_list_file, + build_utils.DIR_SOURCE_ROOT) + + return 0 + + +def main(): + parser = argparse.ArgumentParser() + _AddArguments(parser) + _RunInstrumentCommand(parser) + + +if __name__ == '__main__': + sys.exit(main())
diff --git a/build/android/gyp/emma_instr.pydeps b/build/android/gyp/jacoco_instr.pydeps similarity index 64% rename from build/android/gyp/emma_instr.pydeps rename to build/android/gyp/jacoco_instr.pydeps index 88f752a0..d64c4f1 100644 --- a/build/android/gyp/emma_instr.pydeps +++ b/build/android/gyp/jacoco_instr.pydeps
@@ -1,7 +1,7 @@ # Generated by running: -# build/print_python_deps.py --root build/android/gyp --output build/android/gyp/emma_instr.pydeps build/android/gyp/emma_instr.py +# build/print_python_deps.py --root build/android/gyp --output build/android/gyp/jacoco_instr.pydeps build/android/gyp/jacoco_instr.py ../../gn_helpers.py -emma_instr.py +jacoco_instr.py util/__init__.py util/build_utils.py util/md5_check.py
diff --git a/build/android/incremental_install/BUILD.gn b/build/android/incremental_install/BUILD.gn index 3093c3a..fb75d79 100644 --- a/build/android/incremental_install/BUILD.gn +++ b/build/android/incremental_install/BUILD.gn
@@ -15,6 +15,6 @@ "java/org/chromium/incrementalinstall/Reflect.java", "java/org/chromium/incrementalinstall/SecondInstrumentation.java", ] - emma_never_instrument = true + jacoco_never_instrument = true no_build_hooks = true }
diff --git a/build/android/pylib/device/commands/BUILD.gn b/build/android/pylib/device/commands/BUILD.gn index 480db1e8..d9e4bbb 100644 --- a/build/android/pylib/device/commands/BUILD.gn +++ b/build/android/pylib/device/commands/BUILD.gn
@@ -11,7 +11,7 @@ } android_library("chromium_commands_java") { - emma_never_instrument = true + jacoco_never_instrument = true java_files = [ "java/src/org/chromium/android/commands/unzip/Unzip.java" ] dex_path = "$root_build_dir/lib.java/chromium_commands.dex.jar" data = [
diff --git a/build/android/pylib/junit/junit_test_instance.py b/build/android/pylib/junit/junit_test_instance.py index f258cbd..e5dc2a7 100644 --- a/build/android/pylib/junit/junit_test_instance.py +++ b/build/android/pylib/junit/junit_test_instance.py
@@ -14,7 +14,7 @@ self._android_manifest_path = args.android_manifest_path self._coverage_dir = args.coverage_dir self._debug_socket = args.debug_socket - self._jacoco = args.jacoco + self._coverage_on_the_fly = args.coverage_on_the_fly self._package_filter = args.package_filter self._package_name = args.package_name self._resource_zips = args.resource_zips @@ -44,8 +44,8 @@ return self._coverage_dir @property - def jacoco(self): - return self._jacoco + def coverage_on_the_fly(self): + return self._coverage_on_the_fly @property def debug_socket(self):
diff --git a/build/android/pylib/local/device/local_device_instrumentation_test_run.py b/build/android/pylib/local/device/local_device_instrumentation_test_run.py index 9b9a2a8..e8aad67b 100644 --- a/build/android/pylib/local/device/local_device_instrumentation_test_run.py +++ b/build/android/pylib/local/device/local_device_instrumentation_test_run.py
@@ -427,8 +427,9 @@ flags_to_add = [] test_timeout_scale = None if self._test_instance.coverage_directory: - coverage_basename = '%s.ec' % ('%s_group' % test[0]['method'] - if isinstance(test, list) else test['method']) + coverage_basename = '%s.exec' % ('%s_group' % test[0]['method'] + if isinstance(test, list) else + test['method']) extras['coverage'] = 'true' coverage_directory = os.path.join( device.GetExternalStoragePath(), 'chrome', 'test', 'coverage')
diff --git a/build/android/pylib/local/machine/local_machine_junit_test_run.py b/build/android/pylib/local/machine/local_machine_junit_test_run.py index 6d2d3c8..2b6cc8d 100644 --- a/build/android/pylib/local/machine/local_machine_junit_test_run.py +++ b/build/android/pylib/local/machine/local_machine_junit_test_run.py
@@ -96,7 +96,7 @@ os.makedirs(self._test_instance.coverage_dir) elif not os.path.isdir(self._test_instance.coverage_dir): raise Exception('--coverage-dir takes a directory, not file path.') - if self._test_instance.jacoco: + if self._test_instance.coverage_on_the_fly: jacoco_coverage_file = os.path.join( self._test_instance.coverage_dir, '%s.exec' % self._test_instance.suite) @@ -107,9 +107,9 @@ jvm_args.append( jacoco_args.format(jacoco_agent_path, jacoco_coverage_file)) else: - jvm_args.append('-Demma.coverage.out.file=%s' % os.path.join( + jvm_args.append('-Djacoco-agent.destfile=%s' % os.path.join( self._test_instance.coverage_dir, - '%s.ec' % self._test_instance.suite)) + '%s.exec' % self._test_instance.suite)) if jvm_args: command.extend(['--jvm-args', '"%s"' % ' '.join(jvm_args)])
diff --git a/build/android/test_runner.py b/build/android/test_runner.py index 9a6a935f..eb516acb 100755 --- a/build/android/test_runner.py +++ b/build/android/test_runner.py
@@ -397,7 +397,7 @@ '--coverage-dir', type=os.path.realpath, help='Directory in which to place all generated ' - 'EMMA coverage files.') + 'Jacoco coverage files.') parser.add_argument( '--delete-stale-data', action='store_true', dest='delete_stale_data', @@ -509,8 +509,9 @@ parser = parser.add_argument_group('junit arguments') parser.add_argument( - '--jacoco', action='store_true', - help='Generate jacoco report.') + '--coverage-on-the-fly', + action='store_true', + help='Generate coverage data by Jacoco on-the-fly instrumentation.') parser.add_argument( '--coverage-dir', type=os.path.realpath, help='Directory to store coverage info.') @@ -1040,9 +1041,9 @@ parser.error('--use-webview-provider and --enable-concurrent-adb cannot ' 'be used together') - if (getattr(args, 'jacoco', False) and - not getattr(args, 'coverage_dir', '')): - parser.error('--jacoco requires --coverage-dir') + if (getattr(args, 'coverage_on_the_fly', False) + and not getattr(args, 'coverage_dir', '')): + parser.error('--coverage-on-the-fly requires --coverage-dir') if (hasattr(args, 'debug_socket') or (hasattr(args, 'wait_for_java_debugger') and
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn index d8c49c5..7063da0 100644 --- a/build/config/BUILDCONFIG.gn +++ b/build/config/BUILDCONFIG.gn
@@ -431,7 +431,6 @@ "//build/config/compiler:default_stack_frames", "//build/config/compiler:default_symbols", "//build/config/compiler:export_dynamic", - "//build/config/compiler:fatal_linker_warnings_win", "//build/config/compiler:no_exceptions", "//build/config/compiler:no_rtti", "//build/config/compiler:runtime_library",
diff --git a/build/config/android/config.gni b/build/config/android/config.gni index fe25637..a0ab2e8 100644 --- a/build/config/android/config.gni +++ b/build/config/android/config.gni
@@ -188,14 +188,9 @@ # Set to false to disable the Errorprone compiler use_errorprone_java_compiler = true - # Enables EMMA Java code coverage. Instruments classes during build to - # produce .ec files during runtime - emma_coverage = false - - # EMMA filter string consisting of a list of inclusion/exclusion patterns - # separated with whitespace and/or comma. Only has effect if - # emma_coverage==true - emma_filter = "" + # Enables Jacoco Java code coverage. Instruments classes during build to + # produce .exec files during runtime + jacoco_coverage = false # Disables process isolation when building _incremental targets. # Required for Android M+ due to SELinux policies (stronger sandboxing).
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni index dc4893f..f1f0c2d6 100644 --- a/build/config/android/internal_rules.gni +++ b/build/config/android/internal_rules.gni
@@ -760,7 +760,7 @@ if (defined(invoker.proguard_enabled) && invoker.proguard_enabled) { executable_args += [ "--enable-java-deobfuscation" ] } - if (emma_coverage) { + if (jacoco_coverage) { # Set a default coverage output directory (can be overridden by user # passing the same flag). _rebased_coverage_dir = @@ -1161,10 +1161,10 @@ } args += [ "--classpath=@FileArg($_rebased_build_config:deps_info:java_runtime_classpath)" ] - if (emma_coverage) { + if (jacoco_coverage) { args += [ "--classpath", - rebase_path("//third_party/android_sdk/public/tools/lib/emma.jar", + rebase_path("//third_party/jacoco/lib/jacocoagent.jar", root_build_dir), "--noverify", ] @@ -1493,7 +1493,7 @@ } } - template("emma_instr") { + template("jacoco_instr") { action_with_pydeps(target_name) { forward_variables_from(invoker, [ @@ -1502,45 +1502,30 @@ "testonly", ]) - _coverage_file = "$target_out_dir/${target_name}.em" _source_dirs_listing_file = "$target_out_dir/${target_name}_sources.txt" - _emma_jar = "${android_sdk_root}/tools/lib/emma.jar" + _jacococli_jar = "//third_party/jacoco/lib/jacococli.jar" - script = "//build/android/gyp/emma_instr.py" + script = "//build/android/gyp/jacoco_instr.py" inputs = invoker.java_files + [ - _emma_jar, + _jacococli_jar, invoker.input_jar_path, ] outputs = [ - _coverage_file, _source_dirs_listing_file, invoker.output_jar_path, ] args = [ - "instrument_jar", "--input-path", rebase_path(invoker.input_jar_path, root_build_dir), "--output-path", rebase_path(invoker.output_jar_path, root_build_dir), - "--coverage-file", - rebase_path(_coverage_file, root_build_dir), "--sources-list-file", rebase_path(_source_dirs_listing_file, root_build_dir), - "--src-root", - rebase_path("//", root_build_dir), - "--emma-jar", - rebase_path(_emma_jar, root_build_dir), + "--java-sources-file", + rebase_path(invoker.java_sources_file, root_build_dir), + "--jacococli-jar", + rebase_path(_jacococli_jar, root_build_dir), ] - _rebased_java_sources_file = - rebase_path(invoker.java_sources_file, root_build_dir) - args += [ "--java-sources-file=$_rebased_java_sources_file" ] - - if (emma_filter != "") { - args += [ - "--filter-string", - emma_filter, - ] - } } } @@ -1554,7 +1539,8 @@ # enable_build_hooks: # enable_build_hooks_android: # supports_android: - # emma_instrument: + # jacoco_instrument: Use Jacoco-instrumented classes to generate Java + # coverage data. # jar_excluded_patterns: Optional list of .class file patterns to exclude # from the final .jar file. # jar_included_patterns: OPtional list of .class file patterns to include @@ -1590,7 +1576,7 @@ _enable_thread_annotations = false _desugar = defined(invoker.supports_android) && invoker.supports_android - _emma_instrument = invoker.emma_instrument + _jacoco_instrument = invoker.jacoco_instrument _enable_split_compat = defined(invoker.split_compat_class_names) _enable_class_deps_output = defined(invoker.enable_class_deps_output) @@ -1783,13 +1769,13 @@ _previous_output_jar = _filter_output_jar } - if (_emma_instrument) { - # Emma must run after desugar (or else desugar sometimes fails). - _emma_target = "${target_name}__emma" - _emma_input_jar = _previous_output_jar - _emma_output_jar = "$target_out_dir/$target_name-instrumented.jar" + if (_jacoco_instrument) { + # Jacoco must run after desugar (or else desugar sometimes fails). + _jacoco_target = "${target_name}__jacoco" + _jacoco_input_jar = _previous_output_jar + _jacoco_output_jar = "$target_out_dir/$target_name-instrumented.jar" - emma_instr(_emma_target) { + jacoco_instr(_jacoco_target) { deps = _deps if (defined(invoker.deps)) { deps += invoker.deps @@ -1801,13 +1787,13 @@ "java_sources_file", ]) - input_jar_path = _emma_input_jar - output_jar_path = _emma_output_jar + input_jar_path = _jacoco_input_jar + output_jar_path = _jacoco_output_jar } _deps = [] - _deps = [ ":$_emma_target" ] - _previous_output_jar = _emma_output_jar + _deps = [ ":$_jacoco_target" ] + _previous_output_jar = _jacoco_output_jar } _output_jar_target = "${target_name}__copy" @@ -3174,9 +3160,9 @@ # provided, this is determined automatically, based on the location of # the source files (i.e. anything under third_party/ is not # Chromium-specific unless it is in a 'chromium' sub-directory). - # emma_never_instrument: Optional. If provided, whether to forbid - # instrumentation with the Emma coverage processor. If not provided, - # this is controlled by the global emma_coverage build arg variable + # jacoco_never_instrument: Optional. If provided, whether to forbid + # instrumentation with the Jacoco coverage processor. If not provided, + # this is controlled by the global jacoco_coverage build arg variable # and only used for non-test Chromium code. # include_android_sdk: Optional. Whether or not the android SDK dep # should be added to deps. Defaults to true for non-system libraries @@ -3399,13 +3385,15 @@ } if (defined(_final_jar_path)) { - _emma_instrument = emma_coverage && _chromium_code && _java_files != [] && - (!defined(invoker.testonly) || !invoker.testonly) - if (defined(invoker.emma_never_instrument)) { - _emma_instrument = !invoker.emma_never_instrument && _emma_instrument + _jacoco_instrument = + jacoco_coverage && _chromium_code && _java_files != [] && + (!defined(invoker.testonly) || !invoker.testonly) + if (defined(invoker.jacoco_never_instrument)) { + _jacoco_instrument = + !invoker.jacoco_never_instrument && _jacoco_instrument } - if (_emma_instrument) { - _accumulated_deps += [ "//third_party/android_sdk:emma_device_java" ] + if (_jacoco_instrument) { + _accumulated_deps += [ "//third_party/jacoco:jacocoagent_java" ] } } @@ -3688,8 +3676,8 @@ enable_build_hooks_android = _enable_build_hooks_android build_config = _build_config input_jar_path = _unprocessed_jar_path - emma_instrument = _emma_instrument - if (_emma_instrument) { + jacoco_instrument = _jacoco_instrument + if (_jacoco_instrument) { java_files = _java_files java_sources_file = _java_sources_file }
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index 351ae1f..5fa99b8d 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -2683,7 +2683,7 @@ "base_module_target", "chromium_code", "classpath_deps", - "emma_never_instrument", + "jacoco_never_instrument", "enable_class_deps_output", "java_files", "javac_args", @@ -3266,7 +3266,7 @@ "dexlayout_profile", "dist_ijar_path", "dont_load_shared_libraries", - "emma_never_instrument", + "jacoco_never_instrument", "enable_chromium_linker_tests", "enable_multidex", "final_apk_path", @@ -3385,7 +3385,7 @@ "data", "data_deps", "deps", - "emma_never_instrument", + "jacoco_never_instrument", "enable_chromium_linker_tests", "enable_multidex", "generate_buildconfig_java",
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index f10fd1e..7cd20e3 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -1236,6 +1236,9 @@ if (treat_warnings_as_errors) { cflags += [ "/WX" ] } + if (fatal_linker_warnings) { + ldflags = [ "/WX" ] + } cflags += [ # Warnings permanently disabled: @@ -1500,14 +1503,6 @@ } } -config("fatal_linker_warnings_win") { - # TODO(thakis): Move this back into default_warnings once - # https://crbug.com/958955 is resolved. - if (is_win && fatal_linker_warnings) { - ldflags = [ "/WX" ] - } -} - # chromium_code --------------------------------------------------------------- # # Toggles between higher and lower warnings for code that is (or isn't)
diff --git a/buildtools/checkdeps/checkdeps_test.py b/buildtools/checkdeps/checkdeps_test.py index 6442d5bd..8d0588d 100755 --- a/buildtools/checkdeps/checkdeps_test.py +++ b/buildtools/checkdeps/checkdeps_test.py
@@ -20,14 +20,14 @@ def setUp(self): self.deps_checker = checkdeps.DepsChecker( being_tested=True, - base_directory=os.path.join(os.path.dirname(__file__), os.path.pardir)) + base_directory=os.path.join(os.path.dirname(__file__), '..', '..')) def ImplTestRegularCheckDepsRun(self, ignore_temp_rules, skip_tests): self.deps_checker._ignore_temp_rules = ignore_temp_rules self.deps_checker._skip_tests = skip_tests self.deps_checker.CheckDirectory( os.path.join(self.deps_checker.base_directory, - 'checkdeps/testdata')) + 'buildtools/checkdeps/testdata')) problems = self.deps_checker.results_formatter.GetResults() if skip_tests: @@ -56,13 +56,13 @@ if ignore_temp_rules: VerifySubstringsInProblems('testdata/allowed/test.h', - ['-checkdeps/testdata/disallowed', + ['-buildtools/checkdeps/testdata/disallowed', 'temporarily_allowed.h', '-third_party/explicitly_disallowed', 'Because of no rule applying']) else: VerifySubstringsInProblems('testdata/allowed/test.h', - ['-checkdeps/testdata/disallowed', + ['-buildtools/checkdeps/testdata/disallowed', '-third_party/explicitly_disallowed', 'Because of no rule applying']) @@ -80,7 +80,7 @@ if not skip_tests: VerifySubstringsInProblems('allowed/not_a_test.cc', - ['-checkdeps/testdata/disallowed']) + ['-buildtools/checkdeps/testdata/disallowed']) def testRegularCheckDepsRun(self): self.ImplTestRegularCheckDepsRun(False, False) @@ -99,7 +99,7 @@ self.deps_checker.results_formatter = results.CountViolationsFormatter() self.deps_checker.CheckDirectory( os.path.join(self.deps_checker.base_directory, - 'checkdeps/testdata')) + 'buildtools/checkdeps/testdata')) return self.deps_checker.results_formatter.GetResults() def testCountViolations(self): @@ -111,17 +111,17 @@ def testCountViolationsWithRelativePath(self): self.deps_checker.results_formatter = results.CountViolationsFormatter() self.deps_checker.CheckDirectory( - os.path.join('checkdeps', 'testdata', 'allowed')) + os.path.join('buildtools', 'checkdeps', 'testdata', 'allowed')) self.failUnlessEqual('4', self.deps_checker.results_formatter.GetResults()) def testTempRulesGenerator(self): self.deps_checker.results_formatter = results.TemporaryRulesFormatter() self.deps_checker.CheckDirectory( os.path.join(self.deps_checker.base_directory, - 'checkdeps/testdata/allowed')) + 'buildtools/checkdeps/testdata/allowed')) temp_rules = self.deps_checker.results_formatter.GetResults() - expected = [u' "!checkdeps/testdata/disallowed/bad.h",', - u' "!checkdeps/testdata/disallowed/teststuff/bad.h",', + expected = [u' "!buildtools/checkdeps/testdata/disallowed/bad.h",', + u' "!buildtools/checkdeps/testdata/disallowed/teststuff/bad.h",', u' "!third_party/explicitly_disallowed/bad.h",', u' "!third_party/no_rule/bad.h",'] self.failUnlessEqual(expected, temp_rules) @@ -134,36 +134,36 @@ def testCheckAddedIncludesAllGood(self): problems = self.deps_checker.CheckAddedCppIncludes( - [['checkdeps/testdata/allowed/test.cc', - ['#include "checkdeps/testdata/allowed/good.h"', - '#include "checkdeps/testdata/disallowed/allowed/good.h"'] + [['buildtools/checkdeps/testdata/allowed/test.cc', + ['#include "buildtools/checkdeps/testdata/allowed/good.h"', + '#include "buildtools/checkdeps/testdata/disallowed/allowed/good.h"'] ]]) self.failIf(problems) def testCheckAddedIncludesManyGarbageLines(self): garbage_lines = ["My name is Sam%d\n" % num for num in range(50)] problems = self.deps_checker.CheckAddedCppIncludes( - [['checkdeps/testdata/allowed/test.cc', garbage_lines]]) + [['buildtools/checkdeps/testdata/allowed/test.cc', garbage_lines]]) self.failIf(problems) def testCheckAddedIncludesNoRule(self): problems = self.deps_checker.CheckAddedCppIncludes( - [['checkdeps/testdata/allowed/test.cc', + [['buildtools/checkdeps/testdata/allowed/test.cc', ['#include "no_rule_for_this/nogood.h"'] ]]) self.failUnless(problems) def testCheckAddedIncludesSkippedDirectory(self): problems = self.deps_checker.CheckAddedCppIncludes( - [['checkdeps/testdata/disallowed/allowed/skipped/test.cc', + [['buildtools/checkdeps/testdata/disallowed/allowed/skipped/test.cc', ['#include "whatever/whocares.h"'] ]]) self.failIf(problems) def testCheckAddedIncludesTempAllowed(self): problems = self.deps_checker.CheckAddedCppIncludes( - [['checkdeps/testdata/allowed/test.cc', - ['#include "checkdeps/testdata/disallowed/temporarily_allowed.h"'] + [['buildtools/checkdeps/testdata/allowed/test.cc', + ['#include "buildtools/checkdeps/testdata/disallowed/temporarily_allowed.h"'] ]]) self.failUnless(problems) @@ -179,11 +179,11 @@ # once the bug is fixed, but succeed (with a temporary allowance) # if the bug is in place. problems = self.deps_checker.CheckAddedCppIncludes( - [['checkdeps/testdata/allowed/test.cc', - ['#include "/checkdeps/testdata/disallowed/temporarily_allowed.h"'] + [['buildtools/checkdeps/testdata/allowed/test.cc', + ['#include "buildtools/checkdeps/testdata/disallowed/temporarily_allowed.h"'] ], - ['checkdeps/testdata/disallowed/foo_unittest.cc', - ['#include "checkdeps/testdata/bongo/temp_allowed_for_tests.h"'] + ['buildtools/checkdeps/testdata/disallowed/foo_unittest.cc', + ['#include "buildtools/checkdeps/testdata/bongo/temp_allowed_for_tests.h"'] ]]) # With the bug in place, there would be two problems reported, and # the second would be for foo_unittest.cc. @@ -192,7 +192,7 @@ def testTraversalIsOrdered(self): dirs_traversed = [] - for rules, filenames in self.deps_checker.GetAllRulesAndFiles(): + for rules, filenames in self.deps_checker.GetAllRulesAndFiles(dir_name='buildtools'): self.failUnlessEqual(type(filenames), list) self.failUnlessEqual(filenames, sorted(filenames)) if filenames: @@ -203,38 +203,37 @@ def testCheckPartialImportsAreAllowed(self): problems = self.deps_checker.CheckAddedProtoImports( - [['checkdeps/testdata/test.proto', + [['buildtools/checkdeps/testdata/test.proto', ['import "no_rule_for_this/nogood.proto"'] ]]) self.failIf(problems) def testCheckAddedFullPathImportsAllowed(self): - # NOTE: Base directory is buildtools. problems = self.deps_checker.CheckAddedProtoImports( - [['checkdeps/testdata/test.proto', - ['import "checkdeps/testdata/allowed/good.proto"', - 'import "checkdeps/testdata/disallowed/sub_folder/good.proto"'] + [['buildtools/checkdeps/testdata/test.proto', + ['import "buildtools/checkdeps/testdata/allowed/good.proto"', + 'import "buildtools/checkdeps/testdata/disallowed/sub_folder/good.proto"'] ]]) self.failIf(problems) def testCheckAddedFullPathImportsDisallowed(self): problems = self.deps_checker.CheckAddedProtoImports( - [['checkdeps/testdata/test.proto', - ['import "checkdeps/testdata/disallowed/bad.proto"'] + [['buildtools/checkdeps/testdata/test.proto', + ['import "buildtools/checkdeps/testdata/disallowed/bad.proto"'] ]]) self.failUnless(problems) def testCheckAddedFullPathImportsManyGarbageLines(self): garbage_lines = ["My name is Sam%d\n" % num for num in range(50)] problems = self.deps_checker.CheckAddedProtoImports( - [['checkdeps/testdata/test.proto', + [['buildtools/checkdeps/testdata/test.proto', garbage_lines]]) self.failIf(problems) def testCheckAddedIncludesNoRuleFullPath(self): problems = self.deps_checker.CheckAddedProtoImports( - [['checkdeps/testdata/test.proto', - ['import "../tools/some.proto"'] + [['buildtools/checkdeps/testdata/test.proto', + ['import "tools/some.proto"'] ]]) self.failUnless(problems)
diff --git a/buildtools/checkdeps/java_checker.py b/buildtools/checkdeps/java_checker.py index f59b776..cc6b234 100644 --- a/buildtools/checkdeps/java_checker.py +++ b/buildtools/checkdeps/java_checker.py
@@ -74,7 +74,7 @@ return False def _PrescanFiles(self, added_classset): - for root, dirs, files in os.walk(self._base_directory): + for root, dirs, files in os.walk(self._base_directory.encode('utf-8')): # Skip unwanted subdirectories. TODO(husky): it would be better to do # this via the skip_child_includes flag in DEPS files. Maybe hoist this # prescan logic into checkdeps.py itself?
diff --git a/buildtools/checkdeps/testdata/DEPS b/buildtools/checkdeps/testdata/DEPS index 0b2cb5b5..2220b57 100644 --- a/buildtools/checkdeps/testdata/DEPS +++ b/buildtools/checkdeps/testdata/DEPS
@@ -1,6 +1,6 @@ include_rules = [ - "-checkdeps/testdata/disallowed", - "+checkdeps/testdata/allowed", + "-buildtools/checkdeps/testdata/disallowed", + "+buildtools/checkdeps/testdata/allowed", "-third_party/explicitly_disallowed", ] skip_child_includes = [
diff --git a/buildtools/checkdeps/testdata/allowed/DEPS b/buildtools/checkdeps/testdata/allowed/DEPS index cd47796..148bd2f 100644 --- a/buildtools/checkdeps/testdata/allowed/DEPS +++ b/buildtools/checkdeps/testdata/allowed/DEPS
@@ -1,12 +1,12 @@ include_rules = [ - "+checkdeps/testdata/disallowed/allowed", - "!checkdeps/testdata/disallowed/temporarily_allowed.h", + "+buildtools/checkdeps/testdata/disallowed/allowed", + "!buildtools/checkdeps/testdata/disallowed/temporarily_allowed.h", "+third_party/allowed_may_use", ] specific_include_rules = { ".*_unittest\.cc": [ - "+checkdeps/testdata/disallowed/teststuff", - "!checkdeps/testdata/bongo/temp_allowed_for_tests.h", + "+buildtools/checkdeps/testdata/disallowed/teststuff", + "!buildtools/checkdeps/testdata/bongo/temp_allowed_for_tests.h", ] }
diff --git a/buildtools/checkdeps/testdata/allowed/foo_unittest.cc b/buildtools/checkdeps/testdata/allowed/foo_unittest.cc index 28a660b4..eab25d1 100644 --- a/buildtools/checkdeps/testdata/allowed/foo_unittest.cc +++ b/buildtools/checkdeps/testdata/allowed/foo_unittest.cc
@@ -2,4 +2,4 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "checkdeps/testdata/disallowed/teststuff/good.h" +#include "buildtools/checkdeps/testdata/disallowed/teststuff/good.h"
diff --git a/buildtools/checkdeps/testdata/allowed/not_a_test.cc b/buildtools/checkdeps/testdata/allowed/not_a_test.cc index 56f1fef..07ed9cd 100644 --- a/buildtools/checkdeps/testdata/allowed/not_a_test.cc +++ b/buildtools/checkdeps/testdata/allowed/not_a_test.cc
@@ -2,4 +2,4 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "checkdeps/testdata/disallowed/teststuff/bad.h" +#include "buildtools/checkdeps/testdata/disallowed/teststuff/bad.h"
diff --git a/buildtools/checkdeps/testdata/allowed/test.h b/buildtools/checkdeps/testdata/allowed/test.h index 411b431..fb542a62 100644 --- a/buildtools/checkdeps/testdata/allowed/test.h +++ b/buildtools/checkdeps/testdata/allowed/test.h
@@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "checkdeps/testdata/allowed/good.h" -#include "checkdeps/testdata/disallowed/bad.h" -#include "checkdeps/testdata/disallowed/allowed/good.h" -#include "checkdeps/testdata/disallowed/temporarily_allowed.h" +#include "buildtools/checkdeps/testdata/allowed/good.h" +#include "buildtools/checkdeps/testdata/disallowed/bad.h" +#include "buildtools/checkdeps/testdata/disallowed/allowed/good.h" +#include "buildtools/checkdeps/testdata/disallowed/temporarily_allowed.h" #include "third_party/explicitly_disallowed/bad.h" #include "third_party/allowed_may_use/good.h" #include "third_party/no_rule/bad.h"
diff --git a/buildtools/checkdeps/testdata/disallowed/allowed/test.h b/buildtools/checkdeps/testdata/disallowed/allowed/test.h index 363db43..40bc1fb0 100644 --- a/buildtools/checkdeps/testdata/disallowed/allowed/test.h +++ b/buildtools/checkdeps/testdata/disallowed/allowed/test.h
@@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "checkdeps/testdata/allowed/good.h" +#include "buildtools/checkdeps/testdata/allowed/good.h" // Always allowed to include self and parents. -#include "checkdeps/testdata/disallowed/good.h" -#include "checkdeps/testdata/disallowed/allowed/good.h" +#include "buildtools/checkdeps/testdata/disallowed/good.h" +#include "buildtools/checkdeps/testdata/disallowed/allowed/good.h" #include "third_party/explicitly_disallowed/bad.h" #include "third_party/allowed_may_use/bad.h" #include "third_party/no_rule/bad.h"
diff --git a/buildtools/checkdeps/testdata/disallowed/foo_unittest.cc b/buildtools/checkdeps/testdata/disallowed/foo_unittest.cc index f9ab3c9..cdf295ca 100644 --- a/buildtools/checkdeps/testdata/disallowed/foo_unittest.cc +++ b/buildtools/checkdeps/testdata/disallowed/foo_unittest.cc
@@ -7,4 +7,4 @@ // bug where we were taking shallow copies of rules when generating // rules for subdirectories, so all rule objects were getting the same // dictionary for specific rules. -#include "checkdeps/testdata/disallowed/temp_allowed_for_tests.h" +#include "buildtools/checkdeps/testdata/disallowed/temp_allowed_for_tests.h"
diff --git a/buildtools/checkdeps/testdata/disallowed/test.h b/buildtools/checkdeps/testdata/disallowed/test.h index 4334a35..4af2bd9 100644 --- a/buildtools/checkdeps/testdata/disallowed/test.h +++ b/buildtools/checkdeps/testdata/disallowed/test.h
@@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "checkdeps/testdata/allowed/good.h" +#include "buildtools/checkdeps/testdata/allowed/good.h" // Always allowed to include self. -#include "checkdeps/testdata/disallowed/good.h" -#include "checkdeps/testdata/disallowed/allowed/good.h" +#include "buildtools/checkdeps/testdata/disallowed/good.h" +#include "buildtools/checkdeps/testdata/disallowed/allowed/good.h" #include "third_party/explicitly_disallowed/bad.h" // Only allowed for code under allowed/. #include "third_party/allowed_may_use/bad.h"
diff --git a/buildtools/checkdeps/testdata/noparent/test.h b/buildtools/checkdeps/testdata/noparent/test.h index 9245e12..2f0dbbf2 100644 --- a/buildtools/checkdeps/testdata/noparent/test.h +++ b/buildtools/checkdeps/testdata/noparent/test.h
@@ -3,7 +3,7 @@ // found in the LICENSE file. // Disallowed because noparent removes the +allowed from the parent dir. -#include "checkdeps/testdata/allowed/bad.h" +#include "buildtools/checkdeps/testdata/allowed/bad.h" // Same-directory includes are still allowed. -#include "checkdeps/testdata/noparent/self.h" +#include "buildtools/checkdeps/testdata/noparent/self.h"
diff --git a/cc/animation/animation_host.cc b/cc/animation/animation_host.cc index c538c1b6..c40e3542 100644 --- a/cc/animation/animation_host.cc +++ b/cc/animation/animation_host.cc
@@ -47,6 +47,19 @@ } } +bool TickAnimationsIf(AnimationHost::AnimationsList animations, + base::TimeTicks monotonic_time, + bool (*predicate)(const Animation&)) { + bool did_tick = false; + for (auto& it : animations) { + if (predicate(*it)) { + it->Tick(monotonic_time); + did_tick = true; + } + } + return did_tick; +} + } // namespace std::unique_ptr<AnimationHost> AnimationHost::CreateMainInstance() { @@ -356,19 +369,6 @@ return true; } -bool TickAnimationsIf(AnimationHost::AnimationsList animations, - base::TimeTicks monotonic_time, - bool (*predicate)(const Animation&)) { - bool did_tick = false; - for (auto& it : animations) { - if (predicate(*it)) { - it->Tick(monotonic_time); - did_tick = true; - } - } - return did_tick; -} - bool AnimationHost::TickAnimations(base::TimeTicks monotonic_time, const ScrollTree& scroll_tree, bool is_active_tree) {
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index 6e867d5..7878cd09 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -904,6 +904,7 @@ bundle_data("chrome_framework_helpers") { sources = [ + "$root_out_dir/app_mode_loader", "$root_out_dir/chrome_crashpad_handler", ] @@ -912,6 +913,7 @@ ] public_deps = [ + "//chrome/app_shim:app_mode_loader", "//components/crash/content/app:chrome_crashpad_handler", ] @@ -924,8 +926,6 @@ bundle_data("chrome_framework_resources") { sources = [ - "$root_out_dir/app_mode_loader.app", - # This image is used to badge the lock icon in the # authentication dialogs, such as those used for installation # from disk image and Keystone promotion (if so enabled). It @@ -943,7 +943,7 @@ public_deps = [ ":packed_resources", - "//chrome/app_shim:app_mode_loader", + "//chrome/app_shim:app_mode_loader_plist_bundle_data", ] if (is_chrome_branded) {
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index 91b6867..3e705be8 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -882,6 +882,7 @@ "java/src/org/chromium/chrome/browser/nfc/BeamController.java", "java/src/org/chromium/chrome/browser/nfc/BeamProvider.java", "java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateController.java", + "java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateProviderHolder.java", "java/src/org/chromium/chrome/browser/night_mode/NightModeMetrics.java", "java/src/org/chromium/chrome/browser/night_mode/NightModeStateProvider.java", "java/src/org/chromium/chrome/browser/night_mode/NightModeUtils.java",
diff --git a/chrome/android/chrome_junit_test_java_sources.gni b/chrome/android/chrome_junit_test_java_sources.gni index 81b9fb4..65b5527b 100644 --- a/chrome/android/chrome_junit_test_java_sources.gni +++ b/chrome/android/chrome_junit_test_java_sources.gni
@@ -113,6 +113,8 @@ "junit/src/org/chromium/chrome/browser/notifications/NotificationTriggerBackgroundTaskTest.java", "junit/src/org/chromium/chrome/browser/notifications/NotificationTriggerSchedulerTest.java", "junit/src/org/chromium/chrome/browser/notifications/channels/ChannelDefinitionsTest.java", + "junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateControllerTest.java", + "junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateProviderHolderTest.java", "junit/src/org/chromium/chrome/browser/ntp/TitleUtilTest.java", "junit/src/org/chromium/chrome/browser/ntp/cards/ContentSuggestionsUnitTestUtils.java", "junit/src/org/chromium/chrome/browser/ntp/cards/InnerNodeTest.java",
diff --git a/chrome/android/features/tab_ui/BUILD.gn b/chrome/android/features/tab_ui/BUILD.gn index 4dea80a..abf0a89 100644 --- a/chrome/android/features/tab_ui/BUILD.gn +++ b/chrome/android/features/tab_ui/BUILD.gn
@@ -41,7 +41,7 @@ "java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java", "java/src/org/chromium/chrome/browser/tasks/tab_management/TabListModel.java", "java/src/org/chromium/chrome/browser/tasks/tab_management/TabListRecyclerView.java", - "java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementModuleImpl.java", + "java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java", "java/src/org/chromium/chrome/browser/tasks/tab_management/TabProperties.java", "java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripToolbarCoordinator.java", "java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripToolbarViewProperties.java",
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementModule.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegate.java similarity index 71% rename from chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementModule.java rename to chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegate.java index 71c26ca..73914af 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementModule.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegate.java
@@ -8,11 +8,14 @@ import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ThemeColorProvider; +import org.chromium.components.module_installer.ModuleInterface; /** * Interface to get access to components concerning tab management. */ -public interface TabManagementModule { +@ModuleInterface(module = "tab_management", + impl = "org.chromium.chrome.browser.tasks.tab_management.TabManagementDelegateImpl") +public interface TabManagementDelegate { GridTabSwitcher createGridTabSwitcher(ChromeActivity activity); TabGroupUi createTabGroupUi(ViewGroup parentView, ThemeColorProvider themeColorProvider); }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementModuleImpl.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java similarity index 92% rename from chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementModuleImpl.java rename to chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java index c15dcfe..d3d3b0c 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementModuleImpl.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java
@@ -17,8 +17,8 @@ /** * Impl class that will resolve components for tab management. */ -@UsedByReflection("TabManagementModuleProvider.java") -public class TabManagementModuleImpl implements TabManagementModule { +@UsedByReflection("TabManagementModule") +public class TabManagementDelegateImpl implements TabManagementDelegate { @Override public GridTabSwitcher createGridTabSwitcher(ChromeActivity activity) { if (ChromeFeatureList.isInitialized()) {
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementModuleProvider.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementModuleProvider.java index 718b195b..54a50d3 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementModuleProvider.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementModuleProvider.java
@@ -8,30 +8,19 @@ import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.metrics.UmaSessionStats; -import org.chromium.components.module_installer.ModuleInstaller; - /** * Provider class for TabManagementModule. */ public class TabManagementModuleProvider { public static final String SYNTHETIC_TRIAL_POSTFIX = "SyntheticTrial"; - private static final String TAB_MANAGEMENT_MODULE_IMPL_CLASS_NAME = - "org.chromium.chrome.browser.tasks.tab_management.TabManagementModuleImpl"; - /** - * Returns fallback or real {@link TabManagementModule} implementation depending on whether - * the module is installed. + * Returns {@link TabManagementDelegate} implementation if the module is installed. null, + * otherwise. */ - public static @Nullable TabManagementModule getTabManagementModule() { - TabManagementModule tabManagementModule; - try { - tabManagementModule = - (TabManagementModule) Class.forName(TAB_MANAGEMENT_MODULE_IMPL_CLASS_NAME) - .newInstance(); - } catch (ClassNotFoundException | InstantiationException | IllegalAccessException - | IllegalArgumentException e) { - ModuleInstaller.installDeferred("tab_ui"); + public static @Nullable TabManagementDelegate getDelegate() { + if (!TabManagementModule.isInstalled()) { + TabManagementModule.installDeferred(); if (ChromeFeatureList.isInitialized()) { UmaSessionStats.registerSyntheticFieldTrial( ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID + SYNTHETIC_TRIAL_POSTFIX, @@ -54,6 +43,6 @@ "Downloaded_Control"); } } - return tabManagementModule; + return TabManagementModule.getImpl(); } }
diff --git a/chrome/android/features/tab_ui/tab_management_java_sources.gni b/chrome/android/features/tab_ui/tab_management_java_sources.gni index 3a4223e6..cafcde2 100644 --- a/chrome/android/features/tab_ui/tab_management_java_sources.gni +++ b/chrome/android/features/tab_ui/tab_management_java_sources.gni
@@ -6,7 +6,7 @@ "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcher.java", "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/SilenceLintErrors.java", "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUi.java", - "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementModule.java", + "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegate.java", "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementModuleProvider.java", ]
diff --git a/chrome/android/java/res/drawable/checkerboard_background.xml b/chrome/android/java/res/drawable/checkerboard_background.xml index d16fa3a..f7a1eb4 100644 --- a/chrome/android/java/res/drawable/checkerboard_background.xml +++ b/chrome/android/java/res/drawable/checkerboard_background.xml
@@ -7,25 +7,25 @@ <item> <shape android:shape="rectangle"> <solid android:color="@android:color/white" /> - <size android:height="10dp" android:width="10dp"/> + <size android:height="4dp" android:width="4dp"/> </shape> </item> - <item android:top="0dp" android:left="10dp"> + <item android:top="0dp" android:left="4dp"> <shape android:shape="rectangle"> <solid android:color="@color/modern_grey_200"/> - <size android:height="10dp" android:width="10dp"/> + <size android:height="4dp" android:width="4dp"/> </shape> </item> - <item android:top="10dp" android:left="0dp"> + <item android:top="4dp" android:left="0dp"> <shape android:shape="rectangle"> <solid android:color="@color/modern_grey_200"/> - <size android:height="10dp" android:width="10dp"/> + <size android:height="4dp" android:width="4dp"/> </shape> </item> - <item android:top="10dp" android:left="10dp"> + <item android:top="4dp" android:left="4dp"> <shape android:shape="rectangle"> <solid android:color="@android:color/white" /> - <size android:height="10dp" android:width="10dp"/> + <size android:height="4dp" android:width="4dp"/> </shape> </item> </layer-list>
diff --git a/chrome/android/java/res/layout/context_menu_divider.xml b/chrome/android/java/res/layout/context_menu_divider.xml new file mode 100644 index 0000000..a1dd372 --- /dev/null +++ b/chrome/android/java/res/layout/context_menu_divider.xml
@@ -0,0 +1,13 @@ +<?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. --> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingBottom="@dimen/revamped_context_menu_divider_padding"> + + + <!-- TODO(sinansahin): divider_preference can be renamed to horizontal_divider --> + <include layout="@layout/divider_preference" /> +</FrameLayout> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/revamped_context_menu.xml b/chrome/android/java/res/layout/revamped_context_menu.xml index e306c1e93..340bf2e 100644 --- a/chrome/android/java/res/layout/revamped_context_menu.xml +++ b/chrome/android/java/res/layout/revamped_context_menu.xml
@@ -13,7 +13,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" - android:layout_margin="24dp" + android:layout_marginStart="@dimen/revamped_context_menu_lateral_margin" + android:layout_marginEnd="@dimen/revamped_context_menu_lateral_margin" + android:layout_marginTop="@dimen/revamped_context_menu_vertical_margin" + android:layout_marginBottom="@dimen/revamped_context_menu_vertical_margin" android:background="@drawable/popup_bg_tinted" android:divider="@null" /> </FrameLayout> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/revamped_context_menu_header.xml b/chrome/android/java/res/layout/revamped_context_menu_header.xml index 70365568..8633ca8 100644 --- a/chrome/android/java/res/layout/revamped_context_menu_header.xml +++ b/chrome/android/java/res/layout/revamped_context_menu_header.xml
@@ -5,46 +5,71 @@ <!-- We used nested LinearLayouts here because it was harder to align the text vertically with the center of the image using a single RelativeLayout. A ConstraintLayout could be a better - choice here, but it isn't available to us, yet --> + choice here, but it isn't available to us, yet. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" - android:paddingTop="12dp" - android:paddingBottom="12dp" - android:paddingStart="16dp" - android:paddingEnd="16dp" > + android:paddingStart="@dimen/revamped_context_menu_list_lateral_padding" + android:paddingEnd="@dimen/revamped_context_menu_list_lateral_padding" + android:paddingTop="@dimen/revamped_context_menu_header_vertical_padding" + android:paddingBottom="@dimen/revamped_context_menu_header_vertical_padding"> - <ImageView - android:id="@+id/menu_header_image" - android:layout_width="@dimen/revamped_context_menu_header_image_max_size" - android:layout_height="@dimen/revamped_context_menu_header_image_max_size" - android:layout_gravity="top|start" - android:src="@drawable/checkerboard_background" - android:scaleType="fitCenter" - android:importantForAccessibility="no" /> + <FrameLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginEnd="16dp"> + + <!-- Circle background for when we have a favicon or monogram --> + <View + android:id="@+id/circle_background" + android:background="@drawable/tile_view_icon_background_modern" + android:layout_width="@dimen/revamped_context_menu_header_circle_bg_diameter" + android:layout_height="@dimen/revamped_context_menu_header_circle_bg_diameter" + android:layout_margin="@dimen/revamped_context_menu_header_circle_bg_margin" + android:visibility="invisible" /> + + <org.chromium.ui.widget.RoundedCornerImageView + android:id="@+id/menu_header_image" + android:layout_width="@dimen/revamped_context_menu_header_image_max_size" + android:layout_height="@dimen/revamped_context_menu_header_image_max_size" + android:scaleType="centerInside" + android:importantForAccessibility="no" + app:cornerRadiusTopStart="@dimen/default_rounded_corner_radius" + app:cornerRadiusTopEnd="@dimen/default_rounded_corner_radius" + app:cornerRadiusBottomStart="@dimen/default_rounded_corner_radius" + app:cornerRadiusBottomEnd="@dimen/default_rounded_corner_radius" + app:roundedfillColor="@color/thumbnail_placeholder_on_primary_bg" /> + </FrameLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" - android:paddingStart="16dp" - android:paddingEnd="16dp" android:layout_gravity="center_vertical"> - <TextView + + <!-- TODO(sinansahin): Sync with UX to decide on what to do with cases like RTL text on LTR + device and LTR text on RTL device --> + <org.chromium.ui.widget.TextViewWithLeading android:id="@+id/menu_header_title" android:layout_width="match_parent" android:layout_height="wrap_content" + android:textAlignment="viewStart" android:ellipsize="end" android:maxLines="1" - android:textAppearance="@style/TextAppearance.BlackCaptionDefault"/> - <TextView + android:textAppearance="@style/TextAppearance.BlackCaptionDefault" + app:leading="@dimen/text_size_small_leading" /> + + <org.chromium.ui.widget.TextViewWithLeading android:id="@+id/menu_header_url" android:layout_width="match_parent" android:layout_height="wrap_content" + android:textAlignment="viewStart" android:ellipsize="end" android:maxLines="1" - android:textAppearance="@style/TextAppearance.BlackCaption"/> + android:textAppearance="@style/TextAppearance.BlackCaption" + app:leading="@dimen/text_size_small_leading" /> </LinearLayout> </LinearLayout> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/revamped_context_menu_row.xml b/chrome/android/java/res/layout/revamped_context_menu_row.xml index a5c38b3e..afe4792 100644 --- a/chrome/android/java/res/layout/revamped_context_menu_row.xml +++ b/chrome/android/java/res/layout/revamped_context_menu_row.xml
@@ -10,6 +10,6 @@ android:textAppearance="@style/TextAppearance.BlackTitle1" android:minHeight="48dp" android:gravity="center_vertical" - android:paddingStart="16dp" - android:paddingEnd="16dp" + android:paddingStart="@dimen/revamped_context_menu_list_lateral_padding" + android:paddingEnd="@dimen/revamped_context_menu_list_lateral_padding" android:background="?attr/selectableItemBackground"/> \ No newline at end of file
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index 1aedd80..15fd4b6 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -542,8 +542,16 @@ <dimen name="context_menu_selectable_items_min_size">120dp</dimen> <!-- Revamped Context Menu Dimensions --> - <dimen name="revamped_context_menu_header_image_max_size">64dp</dimen> - + <dimen name="revamped_context_menu_lateral_margin">40dp</dimen> + <dimen name="revamped_context_menu_vertical_margin">20dp</dimen> + <dimen name="revamped_context_menu_list_lateral_padding">16dp</dimen> + <dimen name="revamped_context_menu_header_vertical_padding">16dp</dimen> + <dimen name="revamped_context_menu_divider_padding">8dp</dimen> + <dimen name="revamped_context_menu_header_image_max_size">60dp</dimen> + <dimen name="revamped_context_menu_header_circle_bg_diameter">48dp</dimen> + <dimen name="revamped_context_menu_header_circle_bg_margin">6dp</dimen> + <dimen name="revamped_context_menu_header_monogram_text_size">16dp</dimen> + <dimen name="revamped_context_menu_header_monogram_size">26dp</dimen> <!-- Reader Mode dimensions --> <!-- Padding surrounding the message. --> <dimen name="reader_mode_infobar_text_padding">8dp</dimen>
diff --git a/chrome/android/java/res/values/drawables.xml b/chrome/android/java/res/values/drawables.xml index c4cc320..e6eeff455 100644 --- a/chrome/android/java/res/values/drawables.xml +++ b/chrome/android/java/res/values/drawables.xml
@@ -6,4 +6,5 @@ <resources> <drawable name="ntp_search_box">@drawable/modern_toolbar_text_box_background</drawable> <drawable name="badge_update">@drawable/badge_update_dark</drawable> + <drawable name="ic_error_24dp_filled">@drawable/ic_error_grey800_24dp_filled</drawable> </resources> \ No newline at end of file
diff --git a/chrome/android/java/res_night/values-night/drawables.xml b/chrome/android/java/res_night/values-night/drawables.xml index 602df802..d51dc6d 100644 --- a/chrome/android/java/res_night/values-night/drawables.xml +++ b/chrome/android/java/res_night/values-night/drawables.xml
@@ -4,4 +4,5 @@ found in the LICENSE file. --> <resources> <drawable name="badge_update">@drawable/badge_update_light</drawable> + <drawable name="ic_error_24dp_filled">@drawable/ic_error_white_24dp_filled</drawable> </resources> \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java index 75881ac..d9b28c33 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java
@@ -12,7 +12,7 @@ import android.support.annotation.StyleRes; import android.support.v7.app.AppCompatActivity; -import org.chromium.chrome.browser.night_mode.GlobalNightModeStateController; +import org.chromium.chrome.browser.night_mode.GlobalNightModeStateProviderHolder; import org.chromium.chrome.browser.night_mode.NightModeStateProvider; import org.chromium.chrome.browser.night_mode.NightModeUtils; @@ -90,7 +90,7 @@ * of this class. */ protected NightModeStateProvider createNightModeStateProvider() { - return GlobalNightModeStateController.getInstance(); + return GlobalNightModeStateProviderHolder.getInstance(); } /**
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 b4fdba6..ba53734 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -749,11 +749,11 @@ UsageStatsService.getInstance().createPageViewObserver(mTabModelSelectorImpl, this); } - if (FeatureUtilities.isGridTabSwitcherEnabled() - || FeatureUtilities.isTabGroupsAndroidEnabled()) { + if (TabManagementModuleProvider.getDelegate() != null + && (FeatureUtilities.isGridTabSwitcherEnabled() + || FeatureUtilities.isTabGroupsAndroidEnabled())) { GridTabSwitcher gridTabSwitcher = - TabManagementModuleProvider.getTabManagementModule().createGridTabSwitcher( - this); + TabManagementModuleProvider.getDelegate().createGridTabSwitcher(this); mOverviewModeController.overrideOverviewModeController( gridTabSwitcher.getOverviewModeController()); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java index 00198d3..81f8ab9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java
@@ -11,6 +11,7 @@ import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.support.annotation.IntDef; +import android.support.v4.graphics.drawable.DrawableCompat; import android.support.v7.content.res.AppCompatResources; import android.text.TextUtils; import android.view.LayoutInflater; @@ -207,7 +208,7 @@ holder.text.setText(itemState.title); holder.text.setContentDescription(resources.getString(itemState.title)); holder.text.setTextColor( - ApiCompatibilityUtils.getColor(resources, itemState.titleColor)); + ApiCompatibilityUtils.getColor(resources, itemState.titleColorId)); if (!TextUtils.isEmpty(itemState.summary)) { holder.summary.setText(itemState.summary); @@ -218,6 +219,10 @@ } holder.image.setImageResource(itemState.icon); + if (itemState.iconTintId != 0) { + DrawableCompat.setTint(holder.image.getDrawable(), + ApiCompatibilityUtils.getColor(resources, itemState.iconTintId)); + } convertView.setEnabled(itemState.enabled); } break;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/animation/CompositorAnimator.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/animation/CompositorAnimator.java index 05ece2d..03d8eeb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/animation/CompositorAnimator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/animation/CompositorAnimator.java
@@ -9,6 +9,7 @@ import android.support.annotation.IntDef; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.v4.view.animation.FastOutSlowInInterpolator; import android.view.animation.AccelerateInterpolator; import android.view.animation.DecelerateInterpolator; import android.view.animation.LinearInterpolator; @@ -96,6 +97,8 @@ new AccelerateInterpolator(); public static final DecelerateInterpolator DECELERATE_INTERPOLATOR = new DecelerateInterpolator(); + public static final FastOutSlowInInterpolator FAST_OUT_SLOW_IN_INTERPOLATOR = + new FastOutSlowInInterpolator(); public static final LinearInterpolator LINEAR_INTERPOLATOR = new LinearInterpolator(); /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchCaptionControl.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchCaptionControl.java index b63cec99..8768686 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchCaptionControl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchCaptionControl.java
@@ -5,10 +5,8 @@ package org.chromium.chrome.browser.compositor.bottombar.contextualsearch; import android.content.Context; -import android.support.v4.view.animation.FastOutSlowInInterpolator; import android.view.View; import android.view.ViewGroup; -import android.view.animation.Interpolator; import android.widget.TextView; import org.chromium.chrome.R; @@ -25,7 +23,6 @@ public class ContextualSearchCaptionControl extends OverlayPanelTextViewInflater { private static final float ANIMATION_PERCENTAGE_ZERO = 0.f; private static final float ANIMATION_PERCENTAGE_COMPLETE = 1.f; - private static final Interpolator ANIMATION_INTERPOLATOR = new FastOutSlowInInterpolator(); /** * The caption View. @@ -195,7 +192,8 @@ OverlayPanelAnimation.BASE_ANIMATION_DURATION_MS, null); mTransitionAnimator.addUpdateListener( animator -> mAnimationPercentage = animator.getAnimatedValue()); - mTransitionAnimator.setInterpolator(ANIMATION_INTERPOLATOR); + mTransitionAnimator.setInterpolator(CompositorAnimator.FAST_OUT_SLOW_IN_INTERPOLATOR); + mTransitionAnimator.start(); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/ToolbarSwipeLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/ToolbarSwipeLayout.java index 89505c1b..63c2ff3e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/ToolbarSwipeLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/ToolbarSwipeLayout.java
@@ -7,8 +7,6 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.RectF; -import android.view.animation.DecelerateInterpolator; -import android.view.animation.Interpolator; import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; @@ -67,8 +65,6 @@ private final BlackHoleEventFilter mBlackHoleEventFilter; private final TabListSceneLayer mSceneLayer; - private final Interpolator mEdgeInterpolator = new DecelerateInterpolator(); - /** The left and right scene layer responsible for drawing bottom toolbars for each tab. */ private ScrollingBottomViewSceneLayer mLeftBottomToolbarSceneLayer; private ScrollingBottomViewSceneLayer mRightBottomToolbarSceneLayer; @@ -284,7 +280,8 @@ if (doEdge) { float progress = mOffset / getWidth(); float direction = Math.signum(progress); - float smoothedProgress = mEdgeInterpolator.getInterpolation(Math.abs(progress)); + float smoothedProgress = + CompositorAnimator.DECELERATE_INTERPOLATOR.getInterpolation(Math.abs(progress)); float maxSlide = getWidth() / 5.f; rightX = direction * smoothedProgress * maxSlide;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/Stack.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/Stack.java index 737c82a..f0c5e001 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/Stack.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/Stack.java
@@ -12,8 +12,6 @@ import android.graphics.RectF; import android.support.annotation.IntDef; import android.util.Pair; -import android.view.animation.AccelerateDecelerateInterpolator; -import android.view.animation.Interpolator; import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; @@ -176,12 +174,6 @@ protected float mMaxUnderScroll; protected float mMaxOverScrollAngle; // This will be updated from values.xml private float mMaxOverScrollSlide; - private final Interpolator mOverScrollAngleInterpolator = - new AccelerateDecelerateInterpolator(); - private final Interpolator mUnderScrollAngleInterpolator = - CompositorAnimator.DECELERATE_INTERPOLATOR; - private final Interpolator mOverscrollSlideInterpolator = - new AccelerateDecelerateInterpolator(); // Drag Lock private @DragLock int mDragLock = DragLock.NONE;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackAnimation.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackAnimation.java index c2345729..efb54a1e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackAnimation.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackAnimation.java
@@ -52,38 +52,37 @@ int NONE = 10; } - private static final int ENTER_STACK_TOOLBAR_ALPHA_DURATION = 100; - private static final int ENTER_STACK_TOOLBAR_ALPHA_DELAY = 100; - private static final int ENTER_STACK_ANIMATION_DURATION = 300; - private static final int ENTER_STACK_RESIZE_DELAY = 10; - private static final int ENTER_STACK_BORDER_ALPHA_DURATION = 200; + private static final int ENTER_STACK_ANIMATION_DURATION_MS = 300; + private static final int ENTER_STACK_BORDER_ALPHA_DURATION_MS = 200; + private static final int ENTER_STACK_RESIZE_DELAY_MS = 10; + private static final int ENTER_STACK_TOOLBAR_ALPHA_DURATION_MS = 100; + private static final int ENTER_STACK_TOOLBAR_ALPHA_DELAY_MS = 100; private static final float ENTER_STACK_SIZE_RATIO = 0.35f; - private static final int TAB_FOCUSED_TOOLBAR_ALPHA_DURATION = 250; - private static final int TAB_FOCUSED_TOOLBAR_ALPHA_DELAY = 0; - private static final int TAB_FOCUSED_ANIMATION_DURATION = 400; - private static final int TAB_FOCUSED_Y_STACK_DURATION = 200; - private static final int TAB_FOCUSED_BORDER_ALPHA_DURATION = 200; - private static final int TAB_FOCUSED_BORDER_ALPHA_DELAY = 0; - private static final int TAB_FOCUSED_MAX_DELAY = 100; + private static final int TAB_FOCUSED_ANIMATION_DURATION_MS = 400; + private static final int TAB_FOCUSED_BORDER_ALPHA_DURATION_MS = 200; + private static final int TAB_FOCUSED_TOOLBAR_ALPHA_DURATION_MS = 250; + private static final int TAB_FOCUSED_Y_STACK_DURATION_MS = 200; + private static final int TAB_FOCUSED_MAX_DELAY_MS = 100; - private static final int VIEW_MORE_ANIMATION_DURATION = 400; - private static final float VIEW_MORE_SIZE_RATIO = 0.75f; + private static final int VIEW_MORE_ANIMATION_DURATION_MS = 400; private static final int VIEW_MORE_MIN_SIZE = 200; + private static final float VIEW_MORE_SIZE_RATIO = 0.75f; - private static final int REACH_TOP_ANIMATION_DURATION = 400; + private static final int REACH_TOP_ANIMATION_DURATION_MS = 400; - private static final int UNDISCARD_ANIMATION_DURATION = 150; + private static final int UNDISCARD_ANIMATION_DURATION_MS = 150; - private static final int TAB_OPENED_ANIMATION_DURATION = 300; + private static final int TAB_OPENED_ANIMATION_DURATION_MS = 300; - private static final int DISCARD_ANIMATION_DURATION = 150; - private static final int TAB_REORDER_DURATION = 500; + private static final int DISCARD_ANIMATION_DURATION_MS = 150; + + private static final int TAB_REORDER_DURATION_MS = 500; private static final int TAB_REORDER_START_SPAN = 400; - private static final int START_PINCH_ANIMATION_DURATION = 75; + private static final int START_PINCH_ANIMATION_DURATION_MS = 75; - private static final int FULL_ROLL_ANIMATION_DURATION = 1000; + private static final int FULL_ROLL_ANIMATION_DURATION_MS = 1000; private final float mWidth; private final float mHeight; @@ -172,7 +171,7 @@ layoutTab.getTiltY(), layoutTab.getScaledContentWidth() / 2.0f); // Create the angle animation addLandscapePortraitTiltScrollAnimation(animationList, propertyList, handler, - layoutTab, -360.0f, FULL_ROLL_ANIMATION_DURATION, 0); + layoutTab, -360.0f, FULL_ROLL_ANIMATION_DURATION_MS); } break; case OverviewAnimationType.NEW_TAB_OPENED: @@ -182,7 +181,7 @@ for (int i = 0; i < tabs.length; i++) { addToAnimation(animationList, propertyList, handler, tabs[i], StackTab.SCROLL_OFFSET, tabs[i].getScrollOffset(), 0.0f, - TAB_OPENED_ANIMATION_DURATION, 0); + TAB_OPENED_ANIMATION_DURATION_MS, 0); } break; case OverviewAnimationType.REACH_TOP: @@ -195,7 +194,8 @@ break; addToAnimation(animationList, propertyList, handler, tabs[i], StackTab.SCROLL_OFFSET, tabs[i].getScrollOffset(), - mStack.screenToScroll(screenTarget), REACH_TOP_ANIMATION_DURATION, 0); + mStack.screenToScroll(screenTarget), REACH_TOP_ANIMATION_DURATION_MS, + 0); screenTarget += mOrientation == Orientation.LANDSCAPE ? tabs[i].getLayoutTab().getScaledContentWidth() : tabs[i].getLayoutTab().getScaledContentHeight(); @@ -205,7 +205,7 @@ // Responsible for generating the animations that flattens tabs when a pinch begins. for (int i = 0; i < tabs.length; ++i) { addLandscapePortraitTiltScrollAnimation(animationList, propertyList, handler, - tabs[i].getLayoutTab(), 0, START_PINCH_ANIMATION_DURATION, 0); + tabs[i].getLayoutTab(), 0, START_PINCH_ANIMATION_DURATION_MS); } break; case OverviewAnimationType.TAB_FOCUSED: @@ -226,7 +226,7 @@ for (int i = sourceIndex + 1; i < tabs.length; ++i) { addToAnimation(animationList, propertyList, handler, tabs[i], StackTab.SCROLL_OFFSET, tabs[i].getScrollOffset(), - tabs[i].getScrollOffset() + offset, VIEW_MORE_ANIMATION_DURATION, 0); + tabs[i].getScrollOffset() + offset, VIEW_MORE_ANIMATION_DURATION_MS, 0); } break; default: @@ -245,13 +245,13 @@ private void addLandscapePortraitTiltScrollAnimation(ArrayList<Animator> animationList, ArrayList<FloatProperty> propertyList, CompositorAnimationHandler handler, - LayoutTab tab, float end, int duration, int startTime) { + LayoutTab tab, float end, int durationMs) { if (mOrientation == Orientation.LANDSCAPE) { addToAnimation(animationList, propertyList, handler, tab, LayoutTab.TILTY, - tab.getTiltY(), end, duration, startTime); + tab.getTiltY(), end, durationMs, 0); } else { addToAnimation(animationList, propertyList, handler, tab, LayoutTab.TILTX, - tab.getTiltX(), end, duration, startTime); + tab.getTiltX(), end, durationMs, 0); } } @@ -289,34 +289,36 @@ if (i < focusIndex) { tab.getLayoutTab().setMaxContentHeight(mStack.getMaxTabHeight()); addToAnimation(animationList, propertyList, handler, tab, StackTab.SCROLL_OFFSET, - initialScrollOffset, scrollOffset, ENTER_STACK_ANIMATION_DURATION, 0); + initialScrollOffset, scrollOffset, ENTER_STACK_ANIMATION_DURATION_MS, 0); } else if (i > focusIndex) { tab.getLayoutTab().setMaxContentHeight(mStack.getMaxTabHeight()); tab.setScrollOffset(scrollOffset + trailingScrollOffset); addToAnimation(animationList, propertyList, handler, tab, - StackTab.Y_IN_STACK_OFFSET, mHeight, 0, ENTER_STACK_ANIMATION_DURATION, 0); + StackTab.Y_IN_STACK_OFFSET, mHeight, 0, ENTER_STACK_ANIMATION_DURATION_MS, + 0); } else { // i == focusIndex tab.setScrollOffset(scrollOffset); addToAnimation(animationList, propertyList, handler, tab.getLayoutTab(), LayoutTab.MAX_CONTENT_HEIGHT, tab.getLayoutTab().getUnclampedOriginalContentHeight(), - mStack.getMaxTabHeight(), ENTER_STACK_ANIMATION_DURATION, - ENTER_STACK_RESIZE_DELAY); + mStack.getMaxTabHeight(), ENTER_STACK_ANIMATION_DURATION_MS, + ENTER_STACK_RESIZE_DELAY_MS); addToAnimation(animationList, propertyList, handler, tab, StackTab.Y_IN_STACK_INFLUENCE, 0.0f, 1.0f, - ENTER_STACK_BORDER_ALPHA_DURATION, 0); + ENTER_STACK_BORDER_ALPHA_DURATION_MS, 0); addToAnimation(animationList, propertyList, handler, tab, StackTab.SCALE, 1.0f, - mStack.getScaleAmount(), ENTER_STACK_BORDER_ALPHA_DURATION, 0); - addToAnimation(animationList, propertyList, handler, tab.getLayoutTab(), - LayoutTab.TOOLBAR_ALPHA, 1.f, 0.f, ENTER_STACK_BORDER_ALPHA_DURATION, - ENTER_STACK_TOOLBAR_ALPHA_DELAY); + mStack.getScaleAmount(), ENTER_STACK_BORDER_ALPHA_DURATION_MS, 0); addToAnimation(animationList, propertyList, handler, tab.getLayoutTab(), LayoutTab.TOOLBAR_Y_OFFSET, 0.f, getToolbarOffsetToLineUpWithBorder(), - ENTER_STACK_BORDER_ALPHA_DURATION, TAB_FOCUSED_TOOLBAR_ALPHA_DELAY); + ENTER_STACK_BORDER_ALPHA_DURATION_MS, 0); addToAnimation(animationList, propertyList, handler, tab.getLayoutTab(), - LayoutTab.SIDE_BORDER_SCALE, 0.f, 1.f, ENTER_STACK_BORDER_ALPHA_DURATION, - TAB_FOCUSED_TOOLBAR_ALPHA_DELAY); + LayoutTab.SIDE_BORDER_SCALE, 0.f, 1.f, ENTER_STACK_BORDER_ALPHA_DURATION_MS, + 0); + + addToAnimation(animationList, propertyList, handler, tab.getLayoutTab(), + LayoutTab.TOOLBAR_ALPHA, 1.f, 0.f, ENTER_STACK_BORDER_ALPHA_DURATION_MS, + ENTER_STACK_TOOLBAR_ALPHA_DELAY_MS); tab.setYOutOfStack(getStaticTabPosition()); } @@ -342,32 +344,34 @@ addToAnimation(animationList, propertyList, handler, tab.getLayoutTab(), LayoutTab.MAX_CONTENT_HEIGHT, tab.getLayoutTab().getUnclampedOriginalContentHeight(), - mStack.getMaxTabHeight(), ENTER_STACK_ANIMATION_DURATION, 0); + mStack.getMaxTabHeight(), ENTER_STACK_ANIMATION_DURATION_MS, 0); if (i < focusIndex) { addToAnimation(animationList, propertyList, handler, tab, StackTab.SCROLL_OFFSET, - initialScrollOffset, scrollOffset, ENTER_STACK_ANIMATION_DURATION, 0); + initialScrollOffset, scrollOffset, ENTER_STACK_ANIMATION_DURATION_MS, 0); } else if (i > focusIndex) { tab.setScrollOffset(scrollOffset); addToAnimation(animationList, propertyList, handler, tab, StackTab.X_IN_STACK_OFFSET, (mWidth > mHeight && LocalizationUtils.isLayoutRtl()) ? -mWidth : mWidth, - 0.0f, ENTER_STACK_ANIMATION_DURATION, 0); + 0.0f, ENTER_STACK_ANIMATION_DURATION_MS, 0); } else { // i == focusIndex tab.setScrollOffset(scrollOffset); + addToAnimation(animationList, propertyList, handler, tab, StackTab.X_IN_STACK_INFLUENCE, 0.0f, 1.0f, - ENTER_STACK_BORDER_ALPHA_DURATION, 0); + ENTER_STACK_BORDER_ALPHA_DURATION_MS, 0); addToAnimation(animationList, propertyList, handler, tab, StackTab.SCALE, 1.0f, - mStack.getScaleAmount(), ENTER_STACK_BORDER_ALPHA_DURATION, 0); - addToAnimation(animationList, propertyList, handler, tab.getLayoutTab(), - LayoutTab.TOOLBAR_ALPHA, 1.f, 0.f, ENTER_STACK_TOOLBAR_ALPHA_DURATION, - ENTER_STACK_TOOLBAR_ALPHA_DELAY); + mStack.getScaleAmount(), ENTER_STACK_BORDER_ALPHA_DURATION_MS, 0); addToAnimation(animationList, propertyList, handler, tab.getLayoutTab(), LayoutTab.TOOLBAR_Y_OFFSET, 0.f, getToolbarOffsetToLineUpWithBorder(), - ENTER_STACK_BORDER_ALPHA_DURATION, TAB_FOCUSED_TOOLBAR_ALPHA_DELAY); + ENTER_STACK_BORDER_ALPHA_DURATION_MS, 0); addToAnimation(animationList, propertyList, handler, tab.getLayoutTab(), - LayoutTab.SIDE_BORDER_SCALE, 0.f, 1.f, ENTER_STACK_BORDER_ALPHA_DURATION, - TAB_FOCUSED_TOOLBAR_ALPHA_DELAY); + LayoutTab.SIDE_BORDER_SCALE, 0.f, 1.f, ENTER_STACK_BORDER_ALPHA_DURATION_MS, + 0); + + addToAnimation(animationList, propertyList, handler, tab.getLayoutTab(), + LayoutTab.TOOLBAR_ALPHA, 1.f, 0.f, ENTER_STACK_TOOLBAR_ALPHA_DURATION_MS, + ENTER_STACK_TOOLBAR_ALPHA_DELAY_MS); } } } @@ -393,9 +397,9 @@ LayoutTab layoutTab = tab.getLayoutTab(); addLandscapePortraitTiltScrollAnimation(animationList, propertyList, handler, layoutTab, - 0.0f, TAB_FOCUSED_ANIMATION_DURATION, 0); + 0.0f, TAB_FOCUSED_ANIMATION_DURATION_MS); addToAnimation(animationList, propertyList, handler, tab, StackTab.DISCARD_AMOUNT, - tab.getDiscardAmount(), 0.0f, TAB_FOCUSED_ANIMATION_DURATION, 0); + tab.getDiscardAmount(), 0.0f, TAB_FOCUSED_ANIMATION_DURATION_MS, 0); if (i < focusIndex) { // Landscape: for tabs left of the focused tab move them left to 0. @@ -405,7 +409,7 @@ mOrientation == Orientation.LANDSCAPE ? Math.max(0.0f, tab.getScrollOffset() - mWidth - spacing) : tab.getScrollOffset() - mHeight - spacing, - TAB_FOCUSED_ANIMATION_DURATION, 0); + TAB_FOCUSED_ANIMATION_DURATION_MS, 0); continue; } else if (i > focusIndex) { if (mOrientation == Orientation.LANDSCAPE) { @@ -416,23 +420,23 @@ ? coveringTabPosition + layoutTab.getScaledContentWidth() : mWidth - coveringTabPosition; float clampedDistanceToBorder = MathUtils.clamp(distanceToBorder, 0, mWidth); - float delay = TAB_FOCUSED_MAX_DELAY * clampedDistanceToBorder / mWidth; + float delay = TAB_FOCUSED_MAX_DELAY_MS * clampedDistanceToBorder / mWidth; addToAnimation(animationList, propertyList, handler, tab, StackTab.X_IN_STACK_OFFSET, tab.getXInStackOffset(), tab.getXInStackOffset() + (LocalizationUtils.isLayoutRtl() ? -mWidth : mWidth), - (TAB_FOCUSED_ANIMATION_DURATION - (long) delay), (long) delay); + (TAB_FOCUSED_ANIMATION_DURATION_MS - (long) delay), (long) delay); } else { // mOrientation == Orientation.PORTRAIT // We also need to animate the Y Translation to move them down // off the screen. float coveringTabPosition = layoutTab.getY(); float distanceToBorder = MathUtils.clamp(mHeight - coveringTabPosition, 0, mHeight); - float delay = TAB_FOCUSED_MAX_DELAY * distanceToBorder / mHeight; + float delay = TAB_FOCUSED_MAX_DELAY_MS * distanceToBorder / mHeight; addToAnimation(animationList, propertyList, handler, tab, StackTab.Y_IN_STACK_OFFSET, tab.getYInStackOffset(), tab.getYInStackOffset() + mHeight, - (TAB_FOCUSED_ANIMATION_DURATION - (long) delay), (long) delay); + (TAB_FOCUSED_ANIMATION_DURATION_MS - (long) delay), (long) delay); } continue; } @@ -451,44 +455,43 @@ if (mOrientation == Orientation.LANDSCAPE) { addToAnimation(animationList, propertyList, handler, tab, StackTab.X_IN_STACK_INFLUENCE, tab.getXInStackInfluence(), 0.0f, - TAB_FOCUSED_ANIMATION_DURATION, 0); + TAB_FOCUSED_ANIMATION_DURATION_MS, 0); if (!isHorizontalTabSwitcherFlagEnabled()) { addToAnimation(animationList, propertyList, handler, tab, StackTab.SCROLL_OFFSET, tab.getScrollOffset(), mStack.screenToScroll(0), - TAB_FOCUSED_ANIMATION_DURATION, 0); + TAB_FOCUSED_ANIMATION_DURATION_MS, 0); } } else { // mOrientation == Orientation.PORTRAIT addToAnimation(animationList, propertyList, handler, tab, StackTab.SCROLL_OFFSET, tab.getScrollOffset(), Math.max(0.0f, tab.getScrollOffset() - mWidth - spacing), - TAB_FOCUSED_ANIMATION_DURATION, 0); + TAB_FOCUSED_ANIMATION_DURATION_MS, 0); } addToAnimation(animationList, propertyList, handler, tab, StackTab.SCALE, - tab.getScale(), 1.0f, TAB_FOCUSED_ANIMATION_DURATION, 0); + tab.getScale(), 1.0f, TAB_FOCUSED_ANIMATION_DURATION_MS, 0); addToAnimation(animationList, propertyList, handler, tab, StackTab.Y_IN_STACK_INFLUENCE, - tab.getYInStackInfluence(), 0.0f, TAB_FOCUSED_Y_STACK_DURATION, 0); - + tab.getYInStackInfluence(), 0.0f, TAB_FOCUSED_Y_STACK_DURATION_MS, 0); addToAnimation(animationList, propertyList, handler, tab.getLayoutTab(), LayoutTab.MAX_CONTENT_HEIGHT, tab.getLayoutTab().getMaxContentHeight(), tab.getLayoutTab().getUnclampedOriginalContentHeight(), - TAB_FOCUSED_ANIMATION_DURATION, 0); + TAB_FOCUSED_ANIMATION_DURATION_MS, 0); + tab.setYOutOfStack(getStaticTabPosition()); if (layoutTab.shouldStall()) { addToAnimation(animationList, propertyList, handler, layoutTab, - LayoutTab.SATURATION, 1.0f, 0.0f, TAB_FOCUSED_BORDER_ALPHA_DURATION, - TAB_FOCUSED_BORDER_ALPHA_DELAY); + LayoutTab.SATURATION, 1.0f, 0.0f, TAB_FOCUSED_BORDER_ALPHA_DURATION_MS, 0); } addToAnimation(animationList, propertyList, handler, tab.getLayoutTab(), LayoutTab.TOOLBAR_ALPHA, layoutTab.getToolbarAlpha(), 1.f, - TAB_FOCUSED_TOOLBAR_ALPHA_DURATION, TAB_FOCUSED_TOOLBAR_ALPHA_DELAY); + TAB_FOCUSED_TOOLBAR_ALPHA_DURATION_MS, 0); addToAnimation(animationList, propertyList, handler, tab.getLayoutTab(), LayoutTab.TOOLBAR_Y_OFFSET, getToolbarOffsetToLineUpWithBorder(), 0.f, - TAB_FOCUSED_TOOLBAR_ALPHA_DURATION, TAB_FOCUSED_TOOLBAR_ALPHA_DELAY); + TAB_FOCUSED_TOOLBAR_ALPHA_DURATION_MS, 0); addToAnimation(animationList, propertyList, handler, tab.getLayoutTab(), - LayoutTab.SIDE_BORDER_SCALE, 1.f, 0.f, TAB_FOCUSED_TOOLBAR_ALPHA_DURATION, - TAB_FOCUSED_TOOLBAR_ALPHA_DELAY); + LayoutTab.SIDE_BORDER_SCALE, 1.f, 0.f, TAB_FOCUSED_TOOLBAR_ALPHA_DURATION_MS, + 0); } } @@ -513,16 +516,15 @@ int firstDyingTabIndex = -1; float firstDyingTabOffset = 0; for (int i = 0; i < tabs.length; ++i) { - StackTab tab = tabs[i]; - addLandscapePortraitTiltScrollAnimation(animationList, propertyList, handler, - tab.getLayoutTab(), 0.0f, UNDISCARD_ANIMATION_DURATION, 0); + tabs[i].getLayoutTab(), 0.0f, UNDISCARD_ANIMATION_DURATION_MS); - if (tab.isDying()) { + if (tabs[i].isDying()) { dyingTabsCount++; if (dyingTabsCount == 1) { firstDyingTabIndex = i; - firstDyingTabOffset = getLandscapePortraitScreenPositionInScrollDirection(tab); + firstDyingTabOffset = + getLandscapePortraitScreenPositionInScrollDirection(tabs[i]); } } } @@ -553,7 +555,7 @@ float discard = tab.getDiscardAmount(); if (discard == 0.0f) discard = defaultDiscardDirectionPositive ? 0.0f : -0.0f; float s = Math.copySign(1.0f, discard); - long duration = (long) (DISCARD_ANIMATION_DURATION + long duration = (long) (DISCARD_ANIMATION_DURATION_MS * (1.0f - Math.abs(discard / discardRange))); animationList.add(CompositorAnimator.ofFloatProperty(handler, tab, @@ -564,14 +566,14 @@ if (tab.getDiscardAmount() != 0.f) { addToAnimation(animationList, propertyList, handler, tab, StackTab.DISCARD_AMOUNT, tab.getDiscardAmount(), 0.0f, - UNDISCARD_ANIMATION_DURATION, 0); + UNDISCARD_ANIMATION_DURATION_MS, 0); } addToAnimation(animationList, propertyList, handler, tab, StackTab.SCALE, - tab.getScale(), mStack.getScaleAmount(), DISCARD_ANIMATION_DURATION, 0); + tab.getScale(), mStack.getScaleAmount(), DISCARD_ANIMATION_DURATION_MS, 0); addToAnimation(animationList, propertyList, handler, tab.getLayoutTab(), LayoutTab.MAX_CONTENT_HEIGHT, tab.getLayoutTab().getMaxContentHeight(), - mStack.getMaxTabHeight(), DISCARD_ANIMATION_DURATION, 0); + mStack.getMaxTabHeight(), DISCARD_ANIMATION_DURATION_MS, 0); float newScrollOffset = mStack.screenToScroll(spacing * newIndex); @@ -586,7 +588,7 @@ if (start != newScrollOffset) { addToAnimation(animationList, propertyList, handler, tab, StackTab.SCROLL_OFFSET, start, newScrollOffset, - TAB_REORDER_DURATION, 0); + TAB_REORDER_DURATION_MS, 0); } } newIndex++; @@ -622,7 +624,7 @@ nonOverlappingStack.suppressScrollClampingForAnimation(); addToAnimation(animationList, propertyList, handler, nonOverlappingStack, Stack.SCROLL_OFFSET, stack.getScrollOffset(), - -(centeredTabIndex - 1) * stack.getSpacing(), TAB_REORDER_DURATION, 0); + -(centeredTabIndex - 1) * stack.getSpacing(), TAB_REORDER_DURATION_MS, 0); } } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackViewAnimation.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackViewAnimation.java index 01ce1a6..a564572 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackViewAnimation.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackViewAnimation.java
@@ -9,13 +9,13 @@ import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.content.res.Resources; -import android.support.v4.view.animation.FastOutSlowInInterpolator; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.widget.FrameLayout; import org.chromium.chrome.R; +import org.chromium.chrome.browser.compositor.animation.CompositorAnimator; import org.chromium.chrome.browser.compositor.layouts.phone.stack.StackAnimation.OverviewAnimationType; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabThemeColorHelper; @@ -87,19 +87,19 @@ PropertyValuesHolder viewAlpha = PropertyValuesHolder.ofFloat(View.ALPHA, 0.f, 1.f); ObjectAnimator viewAlphaAnimator = ObjectAnimator.ofPropertyValuesHolder(view, viewAlpha); viewAlphaAnimator.setDuration(TAB_OPENED_VIEW_ANIMATION_DURATION); - viewAlphaAnimator.setInterpolator(new FastOutSlowInInterpolator()); + viewAlphaAnimator.setInterpolator(CompositorAnimator.FAST_OUT_SLOW_IN_INTERPOLATOR); PropertyValuesHolder yTranslation = PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, mTranslationYStart, 0.f); ObjectAnimator viewYTranslationAnimator = ObjectAnimator.ofPropertyValuesHolder(view, yTranslation); viewYTranslationAnimator.setDuration(TAB_OPENED_VIEW_ANIMATION_DURATION); - viewYTranslationAnimator.setInterpolator(new FastOutSlowInInterpolator()); + viewYTranslationAnimator.setInterpolator(CompositorAnimator.FAST_OUT_SLOW_IN_INTERPOLATOR); PropertyValuesHolder bgAlpha = PropertyValuesHolder.ofFloat(View.ALPHA, 0.f, 1.f); ObjectAnimator bgAlphaAnimator = ObjectAnimator.ofPropertyValuesHolder(bgView, bgAlpha); bgAlphaAnimator.setDuration(TAB_OPENED_BG_ANIMATION_DURATION); - bgAlphaAnimator.setInterpolator(new FastOutSlowInInterpolator()); + bgAlphaAnimator.setInterpolator(CompositorAnimator.FAST_OUT_SLOW_IN_INTERPOLATOR); AnimatorSet set = new AnimatorSet(); set.playTogether(viewAlphaAnimator, viewYTranslationAnimator, bgAlphaAnimator);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java index 82525d26..d3493df 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
@@ -223,21 +223,35 @@ */ public static String createHeaderText(ContextMenuParams params) { if (!isEmptyUrl(params.getLinkUrl())) { - // The context menu can be created without native library - // being loaded. Only use native URL formatting methods - // if the native libraries have been loaded. - if (BrowserStartupController.get(LibraryProcessType.PROCESS_BROWSER) - .isStartupSuccessfullyCompleted()) { - return UrlFormatter.formatUrlForDisplayOmitHTTPScheme(params.getLinkUrl()); - } else { - return params.getLinkUrl(); - } + return getUrlText(params); } else if (!TextUtils.isEmpty(params.getTitleText())) { return params.getTitleText(); } return ""; } + /** + * Gets the link of the item or empty text if the Url is empty. + * @return A string with the link or an empty string. + */ + public static String createUrlText(ContextMenuParams params) { + if (!isEmptyUrl(params.getLinkUrl())) { + return getUrlText(params); + } + return ""; + } + + private static String getUrlText(ContextMenuParams params) { + // The context menu can be created without native library + // being loaded. Only use native URL formatting methods + // if the native libraries have been loaded. + if (BrowserStartupController.get(LibraryProcessType.PROCESS_BROWSER) + .isStartupSuccessfullyCompleted()) { + return UrlFormatter.formatUrlForDisplayOmitHTTPScheme(params.getLinkUrl()); + } + return params.getLinkUrl(); + } + @Override public List<Pair<Integer, List<ContextMenuItem>>> buildContextMenu( ContextMenu menu, Context context, ContextMenuParams params) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java index a49a925..862a82e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java
@@ -23,6 +23,8 @@ import org.chromium.base.task.PostTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeFeatureList; +import org.chromium.chrome.browser.favicon.LargeIconBridge; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.share.ShareHelper; import org.chromium.chrome.browser.share.ShareParams; import org.chromium.content_public.browser.UiThreadTaskTraits; @@ -138,12 +140,13 @@ mOnMenuShown, mOnMenuClosed); // TODO(sinansahin): This could be pushed in to the menuController. if (mCurrentContextMenuParams.isImage()) { - getThumbnail(menuController, new Callback<Bitmap>() { - @Override - public void onResult(Bitmap result) { - menuController.onImageThumbnailRetrieved(result); - } - }); + getThumbnail(menuController, menuController::onImageThumbnailRetrieved); + } else { + LargeIconBridge iconBridge = new LargeIconBridge(Profile.getLastUsedProfile()); + iconBridge.getLargeIconForUrl(mCurrentContextMenuParams.getUrl(), + getActivity().getResources().getDimensionPixelSize( + R.dimen.default_favicon_size), + menuController::onFaviconAvailable); } return; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuController.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuController.java index 5a6cba6..166c516a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuController.java
@@ -7,16 +7,33 @@ import android.app.Activity; import android.content.res.Resources; import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.Shader; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.support.annotation.ColorInt; import android.support.annotation.IntDef; +import android.support.annotation.Nullable; import android.support.v7.app.AlertDialog; +import android.text.SpannableString; +import android.text.TextUtils; import android.util.Pair; import android.view.LayoutInflater; import android.view.View; import android.widget.AdapterView; +import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.Callback; import org.chromium.chrome.R; +import org.chromium.chrome.browser.ChromeBaseAppCompatActivity; +import org.chromium.chrome.browser.favicon.IconType; +import org.chromium.chrome.browser.night_mode.GlobalNightModeStateController; +import org.chromium.chrome.browser.omnibox.OmniboxUrlEmphasizer; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.widget.ContextMenuDialog; +import org.chromium.components.security_state.ConnectionSecurityLevel; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -44,13 +61,14 @@ private RevampedContextMenuListAdapter mListAdapter; private Callback<Integer> mItemClickCallback; private float mTopContentOffsetPx; + private String mPlainUrl; /** * Constructor that also sets the content offset. * * @param topContentOffsetPx content offset from the top. */ - public RevampedContextMenuController(float topContentOffsetPx) { + RevampedContextMenuController(float topContentOffsetPx) { mTopContentOffsetPx = topContentOffsetPx; } @@ -59,15 +77,16 @@ List<Pair<Integer, List<ContextMenuItem>>> items, Callback<Integer> onItemClicked, final Runnable onMenuShown, final Runnable onMenuClosed) { mItemClickCallback = onItemClicked; - float density = Resources.getSystem().getDisplayMetrics().density; + final Resources resources = activity.getResources(); + final float density = resources.getDisplayMetrics().density; final float touchPointXPx = params.getTriggeringTouchXDp() * density; final float touchPointYPx = params.getTriggeringTouchYDp() * density; final View view = LayoutInflater.from(activity).inflate(R.layout.revamped_context_menu, null); mContextMenuDialog = createContextMenuDialog(activity, view, touchPointXPx, touchPointYPx); - mContextMenuDialog.setOnShowListener(dialogInterface -> { onMenuShown.run(); }); - mContextMenuDialog.setOnDismissListener(dialogInterface -> { onMenuClosed.run(); }); + mContextMenuDialog.setOnShowListener(dialogInterface -> onMenuShown.run()); + mContextMenuDialog.setOnDismissListener(dialogInterface -> onMenuClosed.run()); // Integer here indicates if the item is the header, a divider, or a row (selectable option) List<Pair<Integer, ContextMenuItem>> itemList = new ArrayList<>(); @@ -82,9 +101,31 @@ } } - mListAdapter = new RevampedContextMenuListAdapter(itemList); - mListAdapter.setHeaderTitle(params.getTitleText()); - mListAdapter.setHeaderUrl(params.getLinkUrl()); + String headerTitle = params.getTitleText(); + if (TextUtils.isEmpty(headerTitle)) { + headerTitle = params.getLinkText(); + } + + mPlainUrl = params.getUrl(); + CharSequence url = params.getUrl(); + if (!TextUtils.isEmpty(url)) { + boolean useDarkColors = !GlobalNightModeStateController.getInstance().isInNightMode(); + if (activity instanceof ChromeBaseAppCompatActivity) { + useDarkColors = !((ChromeBaseAppCompatActivity) activity) + .getNightModeStateProvider() + .isInNightMode(); + } + + SpannableString spannableUrl = + new SpannableString(ChromeContextMenuPopulator.createUrlText(params)); + OmniboxUrlEmphasizer.emphasizeUrl(spannableUrl, resources, Profile.getLastUsedProfile(), + ConnectionSecurityLevel.NONE, false, useDarkColors, false); + url = spannableUrl; + } + + mListAdapter = new RevampedContextMenuListAdapter(activity, itemList); + mListAdapter.setHeaderTitle(headerTitle); + mListAdapter.setHeaderUrl(url); RevampedContextMenuListView listView = view.findViewById(R.id.context_menu_list_view); listView.setAdapter(mListAdapter); listView.setOnItemClickListener(this); @@ -114,16 +155,55 @@ } /** + * This adds a checkerboard style background to the image. + * It is useful for the transparent PNGs. + * @return The given image with the checkerboard pattern in the background. + */ + static Bitmap getImageWithCheckerBackground(Resources res, Bitmap image) { + // 1. Create a bitmap for the checkerboard pattern. + Drawable drawable = ApiCompatibilityUtils.getDrawable( + res, org.chromium.chrome.R.drawable.checkerboard_background); + Bitmap tileBitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), + drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); + Canvas tileCanvas = new Canvas(tileBitmap); + drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); + drawable.draw(tileCanvas); + + // 2. Create a BitmapDrawable using the checkerboard pattern bitmap. + BitmapDrawable bitmapDrawable = new BitmapDrawable(res, tileBitmap); + bitmapDrawable.setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); + bitmapDrawable.setBounds(0, 0, image.getWidth(), image.getHeight()); + + // 3. Create a bitmap-backed canvas for the final image. + Bitmap bitmap = + Bitmap.createBitmap(image.getWidth(), image.getHeight(), Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + + // 4. Paint the checkerboard background into the final canvas + bitmapDrawable.draw(canvas); + + // 5. Draw the image on top. + Paint paint = new Paint(); + paint.setAntiAlias(true); + canvas.drawBitmap(image, new Matrix(), paint); + + return bitmap; + } + + /** * This is called when the thumbnail is fetched and ready to display. * @param thumbnail The bitmap received that will be displayed as the header image. */ - public void onImageThumbnailRetrieved(Bitmap thumbnail) { - if (thumbnail != null) { - mListAdapter.getHeaderImage().setImageBitmap(thumbnail); - } else { - // TODO(sinansahin): Handle the failed image loads differently. - mListAdapter.getHeaderImage().setImageResource(R.drawable.sad_tab); - } + void onImageThumbnailRetrieved(Bitmap thumbnail) { + mListAdapter.onImageThumbnailRetrieved(thumbnail); + } + + /** + * See {@link org.chromium.chrome.browser.favicon.LargeIconBridge#getLargeIconForUrl} + */ + void onFaviconAvailable(@Nullable Bitmap icon, @ColorInt int fallbackColor, + boolean isColorDefault, @IconType int iconType) { + mListAdapter.onFaviconAvailable(icon, fallbackColor, mPlainUrl); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuListAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuListAdapter.java index a7d826e..0f5a5a8ac 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuListAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuListAdapter.java
@@ -4,16 +4,22 @@ package org.chromium.chrome.browser.contextmenu; +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.support.annotation.ColorInt; +import android.support.annotation.Nullable; import android.text.TextUtils; import android.util.Pair; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; -import android.widget.ImageView; import android.widget.TextView; import org.chromium.chrome.R; +import org.chromium.chrome.browser.widget.RoundedIconGenerator; +import org.chromium.ui.widget.RoundedCornerImageView; import java.util.List; @@ -23,10 +29,17 @@ private final List<Pair<Integer, ContextMenuItem>> mMenuItems; private String mHeaderTitle; - private String mHeaderUrl; - private ImageView mHeaderImage; + private CharSequence mHeaderUrl; + private RoundedCornerImageView mHeaderImage; + private Bitmap mHeaderBitmap; - public RevampedContextMenuListAdapter(List<Pair<Integer, ContextMenuItem>> menuItems) { + private boolean mIsHeaderImageThumbnail; + + private Context mContext; + + public RevampedContextMenuListAdapter( + Context context, List<Pair<Integer, ContextMenuItem>> menuItems) { + mContext = context; mMenuItems = menuItems; } @@ -70,6 +83,12 @@ mHeaderImage = convertView.findViewById(R.id.menu_header_image); + // We should've cached the bitmap if the header wasn't ready when we received a + // thumbnail, favicon, or monogram. We can set the image to the cached bitmap here. + if (mHeaderBitmap != null) { + setHeaderImage(mHeaderBitmap); + } + TextView titleText = convertView.findViewById(R.id.menu_header_title); titleText.setText(mHeaderTitle); @@ -98,8 +117,7 @@ } } else if (getItem(position).first == RevampedContextMenuController.ListItemType.DIVIDER) { - // TODO(sinansahin): divider_preference can be renamed to horizontal_divider - layout = R.layout.divider_preference; + layout = R.layout.context_menu_divider; convertView = LayoutInflater.from(parent.getContext()).inflate(layout, null); } else { layout = R.layout.revamped_context_menu_row; @@ -117,12 +135,72 @@ mHeaderTitle = headerTitle; } - public void setHeaderUrl(String headerUrl) { + public void setHeaderUrl(CharSequence headerUrl) { mHeaderUrl = headerUrl; } - public ImageView getHeaderImage() { - return mHeaderImage; + /** + * This is called when the thumbnail is fetched and ready to display. + * @param thumbnail The bitmap received that will be displayed as the header image. + */ + void onImageThumbnailRetrieved(Bitmap thumbnail) { + mIsHeaderImageThumbnail = true; + if (thumbnail != null) { + setHeaderImage(RevampedContextMenuController.getImageWithCheckerBackground( + mContext.getResources(), thumbnail)); + } + // TODO(sinansahin): Handle the case where the retrieval of the thumbnail fails. + } + + void onFaviconAvailable(@Nullable Bitmap icon, @ColorInt int fallbackColor, String iconUrl) { + // If we didn't get a favicon, generate a monogram instead + if (icon == null) { + RoundedIconGenerator iconGenerator = createRoundedIconGenerator(fallbackColor); + icon = iconGenerator.generateIconForUrl(iconUrl); + } + + mIsHeaderImageThumbnail = false; + final int size = mContext.getResources().getDimensionPixelSize( + R.dimen.revamped_context_menu_header_monogram_size); + + if (icon.getWidth() > size) { + icon = Bitmap.createScaledBitmap(icon, size, size, true); + } + + setHeaderImage(icon); + } + + private void setHeaderImage(Bitmap bitmap) { + // If the HeaderImage hasn't been inflated by the time we receive the bitmap, + // cache the bitmap received to be set in #getView later. + if (mHeaderImage == null) { + mHeaderBitmap = bitmap; + return; + } + + // Clear the loading background color now that we have the real image. + mHeaderImage.setRoundedFillColor(android.R.color.transparent); + + if (mIsHeaderImageThumbnail) { + mHeaderImage.setImageBitmap(bitmap); + return; + } + + ((View) mHeaderImage.getParent()) + .findViewById(R.id.circle_background) + .setVisibility(View.VISIBLE); + mHeaderImage.setImageBitmap(bitmap); + } + + private RoundedIconGenerator createRoundedIconGenerator(@ColorInt int iconColor) { + final Resources resources = mContext.getResources(); + final int iconSize = + resources.getDimensionPixelSize(R.dimen.revamped_context_menu_header_monogram_size); + final int cornerRadius = iconSize / 2; + final int textSize = resources.getDimensionPixelSize( + R.dimen.revamped_context_menu_header_monogram_text_size); + + return new RoundedIconGenerator(iconSize, iconSize, cornerRadius, iconColor, textSize); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuListView.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuListView.java index 21ffc9c..1480788 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuListView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuListView.java
@@ -34,7 +34,8 @@ private int calculateWidth() { int windowWidthPx = getResources().getDisplayMetrics().widthPixels; int maxWidth = getResources().getDimensionPixelSize(R.dimen.context_menu_max_width); - int lateralMargin = getResources().getDimensionPixelSize(R.dimen.context_menu_min_padding); + int lateralMargin = + getResources().getDimensionPixelSize(R.dimen.revamped_context_menu_lateral_margin); return Math.min(maxWidth, windowWidthPx - 2 * lateralMargin); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/ConfirmInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/ConfirmInfoBar.java index f86b9951..d0fc6d1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/ConfirmInfoBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/ConfirmInfoBar.java
@@ -70,7 +70,10 @@ @Override public boolean supportsTouchlessMode() { // Only allow whitelisted implementations of the confirm infobar. - return getInfoBarIdentifier() == InfoBarIdentifier.POPUP_BLOCKED_INFOBAR_DELEGATE_MOBILE; + @InfoBarIdentifier + int infobarId = getInfoBarIdentifier(); + return infobarId == InfoBarIdentifier.POPUP_BLOCKED_INFOBAR_DELEGATE_MOBILE + || infobarId == InfoBarIdentifier.DANGEROUS_DOWNLOAD_INFOBAR_DELEGATE_ANDROID; } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBar.java index 2ddd5dfd..e110bae52 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBar.java
@@ -135,9 +135,9 @@ } ActionNames names = new ActionNames(); - names.cancel = mContext.getResources().getString(R.string.cancel); - names.select = mContext.getResources().getString(R.string.select); - names.alt = ""; + names.cancel = R.string.cancel; + names.select = R.string.select; + names.alt = 0; PropertyModel model = new PropertyModel.Builder(TouchlessDialogProperties.ALL_DIALOG_KEYS) .with(TouchlessDialogProperties.IS_FULLSCREEN, false)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateController.java b/chrome/android/java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateController.java index 20b0d27..07865db1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateController.java
@@ -22,20 +22,18 @@ import org.chromium.base.ApplicationStatus; import org.chromium.base.ContextUtils; import org.chromium.base.ObserverList; -import org.chromium.chrome.browser.ChromeBaseAppCompatActivity; import org.chromium.chrome.browser.preferences.ChromePreferenceManager; import org.chromium.chrome.browser.preferences.themes.ThemePreferences; -import org.chromium.chrome.browser.util.FeatureUtilities; /** * Maintains and provides the night mode state for the entire application. */ -public class GlobalNightModeStateController implements NightModeStateProvider, - SystemNightModeMonitor.Observer, - ApplicationStatus.ApplicationStateListener { - private static GlobalNightModeStateController sInstance; - +class GlobalNightModeStateController implements NightModeStateProvider, + SystemNightModeMonitor.Observer, + ApplicationStatus.ApplicationStateListener { private final ObserverList<Observer> mObservers = new ObserverList<>(); + private final SystemNightModeMonitor mSystemNightModeMonitor; + private final ChromePreferenceManager mChromePreferenceManager; /** * Whether night mode is enabled throughout the entire app. If null, night mode is not @@ -53,24 +51,17 @@ private boolean mIsStarted; /** - * @return The {@link GlobalNightModeStateController} that maintains the night mode state for - * the entire application. Note that UI widgets should always get the - * {@link NightModeStateProvider} from the {@link ChromeBaseAppCompatActivity} they are - * attached to, because the night mode state can be overridden at the activity level. + * Should not directly instantiate unless for testing purpose. Use + * {@link GlobalNightModeStateProviderHolder#getInstance()} instead. + * @param systemNightModeMonitor The {@link SystemNightModeMonitor} that maintains the system + * night mode state. + * @param chromePreferenceManager The {@link ChromePreferenceManager} that maintains shared + * preferences. */ - public static GlobalNightModeStateController getInstance() { - if (sInstance == null) { - sInstance = new GlobalNightModeStateController(); - } - return sInstance; - } - - private GlobalNightModeStateController() { - if (!NightModeUtils.isNightModeSupported() || !FeatureUtilities.isNightModeAvailable()) { - // Always stay in light mode if night mode is not available. - AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); - return; - } + GlobalNightModeStateController(@NonNull SystemNightModeMonitor systemNightModeMonitor, + @NonNull ChromePreferenceManager chromePreferenceManager) { + mSystemNightModeMonitor = systemNightModeMonitor; + mChromePreferenceManager = chromePreferenceManager; mPreferenceObserver = key -> { if (TextUtils.equals(key, UI_THEME_SETTING_KEY)) updateNightMode(); @@ -131,8 +122,8 @@ ContextUtils.getApplicationContext().registerReceiver(mPowerModeReceiver, new IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)); } - SystemNightModeMonitor.getInstance().addObserver(this); - ChromePreferenceManager.getInstance().addObserver(mPreferenceObserver); + mSystemNightModeMonitor.addObserver(this); + mChromePreferenceManager.addObserver(mPreferenceObserver); updateNightMode(); } @@ -144,16 +135,14 @@ if (mPowerModeReceiver != null) { ContextUtils.getApplicationContext().unregisterReceiver(mPowerModeReceiver); } - SystemNightModeMonitor.getInstance().removeObserver(this); - ChromePreferenceManager.getInstance().removeObserver(mPreferenceObserver); + mSystemNightModeMonitor.removeObserver(this); + mChromePreferenceManager.removeObserver(mPreferenceObserver); } private void updateNightMode() { - final int themeSetting = - ChromePreferenceManager.getInstance().readInt(UI_THEME_SETTING_KEY); + final int themeSetting = mChromePreferenceManager.readInt(UI_THEME_SETTING_KEY); final boolean newNightModeOn = themeSetting == ThemePreferences.ThemeSetting.SYSTEM_DEFAULT - && (mPowerSaveModeOn - || SystemNightModeMonitor.getInstance().isSystemNightModeOn()) + && (mPowerSaveModeOn || mSystemNightModeMonitor.isSystemNightModeOn()) || themeSetting == ThemePreferences.ThemeSetting.DARK; if (mNightModeOn != null && newNightModeOn == mNightModeOn) return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateProviderHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateProviderHolder.java new file mode 100644 index 0000000..c06fa20 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateProviderHolder.java
@@ -0,0 +1,66 @@ +// 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. + +package org.chromium.chrome.browser.night_mode; + +import android.support.annotation.NonNull; +import android.support.v7.app.AppCompatDelegate; + +import org.chromium.base.VisibleForTesting; +import org.chromium.chrome.browser.ChromeBaseAppCompatActivity; +import org.chromium.chrome.browser.preferences.ChromePreferenceManager; +import org.chromium.chrome.browser.util.FeatureUtilities; + +/** + * Holds an instance of {@link NightModeStateProvider} that provides night mode state for the entire + * application. + */ +public class GlobalNightModeStateProviderHolder { + private static NightModeStateProvider sInstance; + + /** + * Created when night mode is not available or not supported. + */ + private static class DummyNightModeStateProvider implements NightModeStateProvider { + private DummyNightModeStateProvider() { + // Always stay in light mode if night mode is not available. + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); + } + + @Override + public boolean isInNightMode() { + return false; + } + + @Override + public void addObserver(@NonNull Observer observer) {} + + @Override + public void removeObserver(@NonNull Observer observer) {} + } + + /** + * @return The {@link NightModeStateProvider} that maintains the night mode state for the entire + * application. Note that UI widgets should always get the + * {@link NightModeStateProvider} from the {@link ChromeBaseAppCompatActivity} they are + * attached to, because the night mode state can be overridden at the activity level. + */ + public static NightModeStateProvider getInstance() { + if (sInstance == null) { + if (!NightModeUtils.isNightModeSupported() + || !FeatureUtilities.isNightModeAvailable()) { + sInstance = new DummyNightModeStateProvider(); + } else { + sInstance = new GlobalNightModeStateController(SystemNightModeMonitor.getInstance(), + ChromePreferenceManager.getInstance()); + } + } + return sInstance; + } + + @VisibleForTesting + static void resetInstanceForTesting() { + sInstance = null; + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/night_mode/SystemNightModeMonitor.java b/chrome/android/java/src/org/chromium/chrome/browser/night_mode/SystemNightModeMonitor.java index f89ec4d..bd1dd98 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/night_mode/SystemNightModeMonitor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/night_mode/SystemNightModeMonitor.java
@@ -8,6 +8,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.ObserverList; +import org.chromium.base.VisibleForTesting; import org.chromium.chrome.browser.ChromeApplication; /** @@ -76,4 +77,9 @@ mSystemNightModeOn = (uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES; } + + @VisibleForTesting + void notifyObserversForTesting() { + for (Observer observer : mObservers) observer.onSystemNightModeChanged(); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateMenuItemHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateMenuItemHelper.java index ff09c839..20dc63b0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateMenuItemHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateMenuItemHelper.java
@@ -9,7 +9,7 @@ import android.content.Intent; import android.content.res.Resources; import android.net.Uri; -import android.support.annotation.ColorInt; +import android.support.annotation.ColorRes; import android.support.annotation.DrawableRes; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -61,7 +61,7 @@ public @StringRes int title; /** The color resource of the title. Always set if this object is not {@code null}. */ - public @ColorInt int titleColor; + public @ColorRes int titleColorId; /** The summary string for the menu. Maybe {@code null} if no summary should be shown. */ public @Nullable String summary; @@ -69,6 +69,9 @@ /** An icon resource for the menu item. May be {@code 0} if no icon is specified. */ public @DrawableRes int icon; + /** The color resource of the icon tint. May be {@code 0} if no tint is specified. */ + public @ColorRes int iconTintId; + /** Whether or not the menu item should be enabled (and clickable). */ public boolean enabled; } @@ -287,7 +290,7 @@ mMenuUiState.itemState = new MenuItemState(); mMenuUiState.itemState.title = R.string.menu_update; - mMenuUiState.itemState.titleColor = R.color.error_text_color; + mMenuUiState.itemState.titleColorId = R.color.error_text_color; mMenuUiState.itemState.icon = R.drawable.badge_update; mMenuUiState.itemState.enabled = true; mMenuUiState.itemState.summary = UpdateConfigs.getCustomSummary(); @@ -316,10 +319,10 @@ mMenuUiState.itemState = new MenuItemState(); mMenuUiState.itemState.title = R.string.menu_update_unsupported; - mMenuUiState.itemState.titleColor = R.color.default_text_color; + mMenuUiState.itemState.titleColorId = R.color.default_text_color; mMenuUiState.itemState.summary = resources.getString(R.string.menu_update_unsupported_summary_default); - mMenuUiState.itemState.icon = R.drawable.ic_error_grey800_24dp_filled; + mMenuUiState.itemState.icon = R.drawable.ic_error_24dp_filled; mMenuUiState.itemState.enabled = false; break; case UpdateState.INLINE_UPDATE_AVAILABLE: @@ -339,35 +342,38 @@ mMenuUiState.itemState = new MenuItemState(); mMenuUiState.itemState.title = R.string.menu_update; - mMenuUiState.itemState.titleColor = R.color.default_text_color_blue; + mMenuUiState.itemState.titleColorId = R.color.default_text_color_blue; mMenuUiState.itemState.summary = UpdateConfigs.getCustomSummary(); if (TextUtils.isEmpty(mMenuUiState.itemState.summary)) { mMenuUiState.itemState.summary = resources.getString(R.string.menu_update_summary_default); } mMenuUiState.itemState.icon = R.drawable.ic_history_googblue_24dp; + mMenuUiState.itemState.iconTintId = R.color.default_icon_color_blue; mMenuUiState.itemState.enabled = true; break; case UpdateState.INLINE_UPDATE_DOWNLOADING: mMenuUiState.itemState = new MenuItemState(); mMenuUiState.itemState.title = R.string.menu_inline_update_downloading; - mMenuUiState.itemState.titleColor = R.color.default_text_color_secondary; + mMenuUiState.itemState.titleColorId = R.color.default_text_color_secondary; break; case UpdateState.INLINE_UPDATE_READY: mMenuUiState.itemState = new MenuItemState(); mMenuUiState.itemState.title = R.string.menu_inline_update_ready; - mMenuUiState.itemState.titleColor = R.color.default_text_color_blue; + mMenuUiState.itemState.titleColorId = R.color.default_text_color_blue; mMenuUiState.itemState.summary = resources.getString(R.string.menu_inline_update_ready_summary); mMenuUiState.itemState.icon = R.drawable.infobar_chrome; + mMenuUiState.itemState.iconTintId = R.color.default_icon_color_blue; mMenuUiState.itemState.enabled = true; break; case UpdateState.INLINE_UPDATE_FAILED: mMenuUiState.itemState = new MenuItemState(); mMenuUiState.itemState.title = R.string.menu_inline_update_failed; - mMenuUiState.itemState.titleColor = R.color.default_text_color_blue; + mMenuUiState.itemState.titleColorId = R.color.default_text_color_blue; mMenuUiState.itemState.summary = resources.getString(R.string.try_again); mMenuUiState.itemState.icon = R.drawable.ic_history_googblue_24dp; + mMenuUiState.itemState.iconTintId = R.color.default_icon_color_blue; mMenuUiState.itemState.enabled = true; break; case UpdateState.NONE:
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsCoordinator.java index 5e78cd4..d04721f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsCoordinator.java
@@ -82,8 +82,9 @@ root.getResources().getDimensionPixelOffset( R.dimen.bottom_toolbar_height_with_shadow)); - if (FeatureUtilities.isTabGroupsAndroidEnabled()) { - mTabGroupUi = TabManagementModuleProvider.getTabManagementModule().createTabGroupUi( + if (TabManagementModuleProvider.getDelegate() != null + && FeatureUtilities.isTabGroupsAndroidEnabled()) { + mTabGroupUi = TabManagementModuleProvider.getDelegate().createTabGroupUi( root.findViewById(R.id.bottom_container_slot), themeColorProvider); } else { mBottomToolbarCoordinator = new BottomToolbarCoordinator(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java b/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java index 8bb16fe..48a08dd3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java
@@ -14,6 +14,7 @@ import android.os.Bundle; import android.os.UserManager; import android.speech.RecognizerIntent; +import android.support.annotation.Nullable; import org.chromium.base.CommandLine; import org.chromium.base.ContextUtils; @@ -536,6 +537,15 @@ } /** + * Toggles whether the night mode experiment is enabled for testing. Should be reset back to + * null after the test has finished. + */ + @VisibleForTesting + public static void setNightModeAvailableForTesting(@Nullable Boolean available) { + sIsNightModeAvailable = available; + } + + /** * Cache whether or not night mode is available for custom tabs (i.e. night mode experiment is * enabled), so the value is immediately available on next start-up. */ @@ -593,7 +603,7 @@ ChromeFeatureList.DOWNLOAD_TAB_MANAGEMENT_MODULE) || ChromeFeatureList.isEnabled( ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID)) - && TabManagementModuleProvider.getTabManagementModule() != null + && TabManagementModuleProvider.getDelegate() != null && ChromeFeatureList.isEnabled(ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID)); } @@ -620,7 +630,7 @@ ChromeFeatureList.DOWNLOAD_TAB_MANAGEMENT_MODULE) || ChromeFeatureList.isEnabled( ChromeFeatureList.TAB_GROUPS_ANDROID)) - && TabManagementModuleProvider.getTabManagementModule() != null + && TabManagementModuleProvider.getDelegate() != null && ChromeFeatureList.isEnabled(ChromeFeatureList.TAB_GROUPS_ANDROID)); } @@ -654,7 +664,7 @@ ChromeFeatureList.DOWNLOAD_TAB_MANAGEMENT_MODULE) || ChromeFeatureList.isEnabled( ChromeFeatureList.TAB_GROUPS_UI_IMPROVEMENTS_ANDROID)) - && TabManagementModuleProvider.getTabManagementModule() != null + && TabManagementModuleProvider.getDelegate() != null && ChromeFeatureList.isEnabled( ChromeFeatureList.TAB_GROUPS_UI_IMPROVEMENTS_ANDROID)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedAppLifecycleTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedAppLifecycleTest.java index dcd22f0..c9ad451a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedAppLifecycleTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedAppLifecycleTest.java
@@ -32,7 +32,6 @@ import org.chromium.base.task.PostTask; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.Feature; import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.ChromeSwitches; @@ -51,7 +50,6 @@ import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.test.util.TestThreadUtils; -import org.chromium.ui.test.util.UiDisableIf; import java.util.Map; import java.util.concurrent.TimeoutException; @@ -131,7 +129,6 @@ @Test @SmallTest @Feature({"InterestFeedContentSuggestions"}) - @DisableIf.Device(type = {UiDisableIf.TABLET}) // https://crbug.com/944061. public void testNtpOpeningTriggersInitializeOnlyOnce() throws InterruptedException { // We open to about:blank initially so we shouldn't have called initialize() yet. verify(mAppLifecycleListener, times(0)).initialize(); @@ -262,7 +259,6 @@ @Test @SmallTest @Feature({"InterestFeedContentSuggestions"}) - @DisableIf.Device(type = {UiDisableIf.TABLET}) // https://crbug.com/944061. public void testMultiWindowDoesNotCauseMultipleInitialize() throws InterruptedException { mActivityTestRule.loadUrl(UrlConstants.NTP_URL); verify(mAppLifecycleListener, times(1)).initialize();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java index 012b410..a5ccc39f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java
@@ -309,9 +309,6 @@ @Feature({"NewTabPage", "FeedNewTabPage"}) @ParameterAnnotations.UseMethodParameter(InterestFeedParams.class) public void testFocusFakebox(boolean interestFeedEnabled) { - // TODO(https://crbug.com/944061): Re-enable tablet test on interest feed enabled. - if (interestFeedEnabled && mActivityTestRule.getActivity().isTablet()) return; - int initialFakeboxTop = getFakeboxTop(mNtp); TouchCommon.singleClickView(mFakebox); @@ -336,9 +333,6 @@ @DisableIf.Build(sdk_is_greater_than = 22, message = "crbug.com/593007") @ParameterAnnotations.UseMethodParameter(InterestFeedParams.class) public void testSearchFromFakebox(boolean interestFeedEnabled) throws InterruptedException { - // TODO(https://crbug.com/944061): Re-enable tablet test on interest feed enabled. - if (interestFeedEnabled && mActivityTestRule.getActivity().isTablet()) return; - TouchCommon.singleClickView(mFakebox); waitForFakeboxFocusAnimationComplete(mNtp); final UrlBar urlBar = (UrlBar) mActivityTestRule.getActivity().findViewById(R.id.url_bar); @@ -400,9 +394,6 @@ @ParameterAnnotations.UseMethodParameter(InterestFeedParams.class) public void testOpenMostVisitedItemInIncognitoTab(boolean interestFeedEnabled) throws InterruptedException, ExecutionException { - // TODO(https://crbug.com/944061): Re-enable tablet test on interest feed enabled. - if (interestFeedEnabled && mActivityTestRule.getActivity().isTablet()) return; - ChromeTabUtils.invokeContextMenuAndOpenInANewTab(mActivityTestRule, mTileGridLayout.getChildAt(0), ContextMenuManager.ContextMenuItemId.OPEN_IN_INCOGNITO_TAB, true, @@ -417,9 +408,6 @@ @Feature({"NewTabPage", "FeedNewTabPage"}) @ParameterAnnotations.UseMethodParameter(InterestFeedParams.class) public void testRemoveMostVisitedItem(boolean interestFeedEnabled) throws ExecutionException { - // TODO(https://crbug.com/944061): Re-enable tablet test on interest feed enabled. - if (interestFeedEnabled && mActivityTestRule.getActivity().isTablet()) return; - SiteSuggestion testSite = mSiteSuggestions.get(0); View mostVisitedItem = mTileGridLayout.getChildAt(0); ArrayList<View> views = new ArrayList<>(); @@ -440,9 +428,6 @@ @ParameterAnnotations.UseMethodParameter(InterestFeedParams.class) public void testUrlFocusAnimationsDisabledOnLoad(boolean interestFeedEnabled) throws InterruptedException { - // TODO(https://crbug.com/944061): Re-enable tablet test on interest feed enabled. - if (interestFeedEnabled && mActivityTestRule.getActivity().isTablet()) return; - Assert.assertFalse(getUrlFocusAnimationsDisabled()); ChromeTabUtils.waitForTabPageLoaded(mTab, mTestServer.getURL(TEST_PAGE), new Runnable() { @Override @@ -465,9 +450,6 @@ @ParameterAnnotations.UseMethodParameter(InterestFeedParams.class) public void testUrlFocusAnimationsEnabledOnFailedLoad(boolean interestFeedEnabled) throws Exception { - // TODO(https://crbug.com/944061): Re-enable tablet test on interest feed enabled. - if (interestFeedEnabled && mActivityTestRule.getActivity().isTablet()) return; - // TODO(jbudorick): switch this to EmbeddedTestServer. TestWebServer webServer = TestWebServer.start(); try { @@ -531,9 +513,6 @@ @Feature({"NewTabPage", "FeedNewTabPage"}) @ParameterAnnotations.UseMethodParameter(InterestFeedParams.class) public void testSetSearchProviderInfo(boolean interestFeedEnabled) throws Throwable { - // TODO(https://crbug.com/944061): Re-enable tablet test on interest feed enabled. - if (interestFeedEnabled && mActivityTestRule.getActivity().isTablet()) return; - mActivityTestRule.runOnUiThread(new Runnable() { @Override public void run() { @@ -679,9 +658,6 @@ @Feature({"NewTabPage", "FeedNewTabPage"}) @ParameterAnnotations.UseMethodParameter(InterestFeedParams.class) public void testMemoryPressure(boolean interestFeedEnabled) throws Exception { - // TODO(https://crbug.com/944061): Re-enable tablet test on interest feed enabled. - if (interestFeedEnabled && mActivityTestRule.getActivity().isTablet()) return; - // TODO(twellington): This test currently just checks that sending a memory pressure // signal doesn't crash. Enhance the test to also check whether certain behaviors are // performed.
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateControllerTest.java new file mode 100644 index 0000000..87954d1 --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateControllerTest.java
@@ -0,0 +1,201 @@ +// 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. + +package org.chromium.chrome.browser.night_mode; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.robolectric.Shadows.shadowOf; + +import static org.chromium.base.ApplicationState.HAS_RUNNING_ACTIVITIES; +import static org.chromium.base.ApplicationState.HAS_STOPPED_ACTIVITIES; +import static org.chromium.chrome.browser.preferences.ChromePreferenceManager.UI_THEME_SETTING_KEY; + +import android.content.Context; +import android.content.Intent; +import android.os.PowerManager; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowPowerManager; + +import org.chromium.base.ContextUtils; +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.chrome.browser.preferences.ChromePreferenceManager; +import org.chromium.chrome.browser.preferences.themes.ThemePreferences; + +/** + * Unit tests for {@link GlobalNightModeStateController}. + */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class GlobalNightModeStateControllerTest { + @Mock + private NightModeStateProvider.Observer mObserver; + + private GlobalNightModeStateController mGlobalNightModeStateController; + + private SystemNightModeMonitor mSystemNightModeMonitor; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + mSystemNightModeMonitor = spy(SystemNightModeMonitor.getInstance()); + mGlobalNightModeStateController = new GlobalNightModeStateController( + mSystemNightModeMonitor, ChromePreferenceManager.getInstance()); + + mGlobalNightModeStateController.onApplicationStateChange(HAS_RUNNING_ACTIVITIES); + + // Night mode is disabled by default. + assertFalse(GlobalNightModeStateProviderHolder.getInstance().isInNightMode()); + } + + @After + public void tearDown() throws Exception { + ChromePreferenceManager.getInstance().removeKey(UI_THEME_SETTING_KEY); + } + + @Test + public void testUpdateNightMode_PowerSaveMode() { + // Enable power save mode and verify night mode is enabled. + setIsPowerSaveMode(true); + assertTrue(mGlobalNightModeStateController.isInNightMode()); + + // Disable power save mode and verify night mode is disabled. + setIsPowerSaveMode(false); + assertFalse(mGlobalNightModeStateController.isInNightMode()); + } + + @Test + public void testUpdateNightMode_SystemNightMode() { + // Enable system night mode and verify night mode is enabled. + setSystemNightMode(true); + assertTrue(mGlobalNightModeStateController.isInNightMode()); + + // Disable system night mode and verify night mode is disabled. + setSystemNightMode(false); + assertFalse(mGlobalNightModeStateController.isInNightMode()); + } + + @Test + public void testUpdateNightMode_Preference() { + // Set preference to dark theme and verify night mode is enabled. + ChromePreferenceManager.getInstance().writeInt( + UI_THEME_SETTING_KEY, ThemePreferences.ThemeSetting.DARK); + assertTrue(mGlobalNightModeStateController.isInNightMode()); + + // Set preference to light theme and verify night mode is disabled. + ChromePreferenceManager.getInstance().writeInt( + UI_THEME_SETTING_KEY, ThemePreferences.ThemeSetting.LIGHT); + assertFalse(mGlobalNightModeStateController.isInNightMode()); + + // Regardless of power save mode and system night mode, night mode is disabled with light + // theme preference. + setIsPowerSaveMode(true); + assertFalse(mGlobalNightModeStateController.isInNightMode()); + + setSystemNightMode(true); + assertFalse(mGlobalNightModeStateController.isInNightMode()); + } + + @Test + public void testStopAndRestart() { + // Simulate to stop listening to night mode state changes. Verify that night mode state is + // not changed. + mGlobalNightModeStateController.onApplicationStateChange(HAS_STOPPED_ACTIVITIES); + setIsPowerSaveMode(true); + assertFalse(mGlobalNightModeStateController.isInNightMode()); + + setSystemNightMode(true); + assertFalse(mGlobalNightModeStateController.isInNightMode()); + + ChromePreferenceManager.getInstance().writeInt( + UI_THEME_SETTING_KEY, ThemePreferences.ThemeSetting.DARK); + assertFalse(mGlobalNightModeStateController.isInNightMode()); + + // Simulate to start listening to night mode state changes. Verify that + // 1. Night mode state is updated after #start(). + // 2. Night mode state is updated on power save mode, system night mode, or preference + // changes. + mGlobalNightModeStateController.onApplicationStateChange(HAS_RUNNING_ACTIVITIES); + assertTrue(mGlobalNightModeStateController.isInNightMode()); + + ChromePreferenceManager.getInstance().writeInt( + UI_THEME_SETTING_KEY, ThemePreferences.ThemeSetting.SYSTEM_DEFAULT); + assertTrue(mGlobalNightModeStateController.isInNightMode()); + + setIsPowerSaveMode(false); + assertTrue(mGlobalNightModeStateController.isInNightMode()); + + setSystemNightMode(false); + assertFalse(mGlobalNightModeStateController.isInNightMode()); + } + + @Test + public void testObserver() { + mGlobalNightModeStateController.addObserver(mObserver); + + // Verify that observer is called on night mode state changed from false to true. + ChromePreferenceManager.getInstance().writeInt( + UI_THEME_SETTING_KEY, ThemePreferences.ThemeSetting.DARK); + assertTrue(mGlobalNightModeStateController.isInNightMode()); + verify(mObserver, times(1)).onNightModeStateChanged(); + + // Verify that observer is not called when night mode state is not changed. + setIsPowerSaveMode(true); + assertTrue(mGlobalNightModeStateController.isInNightMode()); + verify(mObserver, times(1)).onNightModeStateChanged(); + + // Verify that observer is not called when night mode state is not changed. + setIsPowerSaveMode(false); + assertTrue(mGlobalNightModeStateController.isInNightMode()); + verify(mObserver, times(1)).onNightModeStateChanged(); + + // Verify that observer is called when set to light theme. + ChromePreferenceManager.getInstance().writeInt( + UI_THEME_SETTING_KEY, ThemePreferences.ThemeSetting.LIGHT); + assertFalse(mGlobalNightModeStateController.isInNightMode()); + verify(mObserver, times(2)).onNightModeStateChanged(); + + // Verify that observer is not called after it is removed. + mGlobalNightModeStateController.removeObserver(mObserver); + ChromePreferenceManager.getInstance().writeInt( + UI_THEME_SETTING_KEY, ThemePreferences.ThemeSetting.DARK); + assertTrue(mGlobalNightModeStateController.isInNightMode()); + verify(mObserver, times(2)).onNightModeStateChanged(); + } + + /** + * Simulates setting power save mode, and notifies the change. + * @param isPowerSaveMode Whether power save mode is enabled or not. + */ + private void setIsPowerSaveMode(boolean isPowerSaveMode) { + PowerManager powerManager = (PowerManager) RuntimeEnvironment.application.getSystemService( + Context.POWER_SERVICE); + ShadowPowerManager shadowPowerManager = shadowOf(powerManager); + shadowPowerManager.setIsPowerSaveMode(isPowerSaveMode); + ContextUtils.getApplicationContext().sendBroadcast( + new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)); + } + + /** + * Simulates setting system night mode, and notifies the change. + * @param isSystemNightModeOn Whether system night mode is enabled or not. + */ + private void setSystemNightMode(boolean isSystemNightModeOn) { + when(mSystemNightModeMonitor.isSystemNightModeOn()).thenReturn(isSystemNightModeOn); + mSystemNightModeMonitor.notifyObserversForTesting(); + } +}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateProviderHolderTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateProviderHolderTest.java new file mode 100644 index 0000000..d4ac5ce --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateProviderHolderTest.java
@@ -0,0 +1,56 @@ +// 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. + +package org.chromium.chrome.browser.night_mode; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import static org.chromium.chrome.browser.preferences.ChromePreferenceManager.UI_THEME_SETTING_KEY; + +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.chrome.browser.preferences.ChromePreferenceManager; +import org.chromium.chrome.browser.preferences.themes.ThemePreferences; +import org.chromium.chrome.browser.util.FeatureUtilities; + +/** + * Unit tests for {@link GlobalNightModeStateProviderHolder}. + */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class GlobalNightModeStateProviderHolderTest { + @After + public void tearDown() throws Exception { + FeatureUtilities.setNightModeAvailableForTesting(null); + GlobalNightModeStateProviderHolder.resetInstanceForTesting(); + ChromePreferenceManager.getInstance().removeKey(UI_THEME_SETTING_KEY); + } + + @Test + public void testNightModeNotAvailable() { + FeatureUtilities.setNightModeAvailableForTesting(false); + + // Verify that night mode is disabled. + assertFalse(GlobalNightModeStateProviderHolder.getInstance().isInNightMode()); + + // Verify that night mode cannot be enabled. + ChromePreferenceManager.getInstance().writeInt( + UI_THEME_SETTING_KEY, ThemePreferences.ThemeSetting.DARK); + assertFalse(GlobalNightModeStateProviderHolder.getInstance().isInNightMode()); + } + + @Test + public void testNightModeAvailable() { + // Verify that the instance is a GlobalNightModeStateController. Other tests are covered + // in GlobalNightModeStateControllerTest.java. + FeatureUtilities.setNightModeAvailableForTesting(true); + assertTrue(GlobalNightModeStateProviderHolder.getInstance() + instanceof GlobalNightModeStateController); + } +}
diff --git a/chrome/android/touchless/java/res/layout/touchless_dialog_view.xml b/chrome/android/touchless/java/res/layout/touchless_dialog_view.xml index 997646c..2d999ad 100644 --- a/chrome/android/touchless/java/res/layout/touchless_dialog_view.xml +++ b/chrome/android/touchless/java/res/layout/touchless_dialog_view.xml
@@ -23,7 +23,6 @@ android:layout_gravity="center" android:ellipsize="end" android:padding="8dp" - android:singleLine="true" android:textAppearance="@style/TextAppearance.BlackTitle1" android:visibility="gone" />
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessContextMenuManager.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessContextMenuManager.java index 75f6ddd9..2b346e7 100644 --- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessContextMenuManager.java +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessContextMenuManager.java
@@ -158,9 +158,9 @@ PropertyModel.Builder builder = new PropertyModel.Builder(TouchlessDialogProperties.ALL_DIALOG_KEYS); ActionNames names = new ActionNames(); - names.cancel = context.getResources().getString(org.chromium.chrome.R.string.cancel); - names.select = context.getResources().getString(org.chromium.chrome.R.string.select); - names.alt = ""; + names.cancel = org.chromium.chrome.R.string.cancel; + names.select = org.chromium.chrome.R.string.select; + names.alt = 0; builder.with(TouchlessDialogProperties.IS_FULLSCREEN, true) .with(ModalDialogProperties.CONTROLLER, new ModalDialogProperties.Controller() {
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/dialog/TouchlessDialogProperties.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/dialog/TouchlessDialogProperties.java index 3514bae..1c458df1 100644 --- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/dialog/TouchlessDialogProperties.java +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/dialog/TouchlessDialogProperties.java
@@ -6,6 +6,7 @@ import android.graphics.drawable.Drawable; import android.support.annotation.IntDef; +import android.support.annotation.StringRes; import android.view.View.OnClickListener; import org.chromium.ui.modaldialog.ModalDialogProperties; @@ -67,9 +68,9 @@ * Struct-like class for holding the Names for the dialog actions. */ public static class ActionNames { - public String cancel; - public String select; - public String alt; + public @StringRes int cancel; + public @StringRes int select; + public @StringRes int alt; } /**
diff --git a/chrome/android/webapk/libs/runtime_library/BUILD.gn b/chrome/android/webapk/libs/runtime_library/BUILD.gn index eef3a89..d3c20a12 100644 --- a/chrome/android/webapk/libs/runtime_library/BUILD.gn +++ b/chrome/android/webapk/libs/runtime_library/BUILD.gn
@@ -30,7 +30,7 @@ # runtime_library_from_assets_java cannot be used as a dependency of another # library because the dx tool expects files ending in .dex.jar android_library("runtime_library_for_assets_java") { - emma_never_instrument = true + jacoco_never_instrument = true java_files = [ "src/org/chromium/webapk/lib/runtime_library/WebApkServiceImpl.java" ] srcjar_deps = [ ":webapk_service_aidl" ]
diff --git a/chrome/app/BUILD.gn b/chrome/app/BUILD.gn index e21d3b6..057e6a4 100644 --- a/chrome/app/BUILD.gn +++ b/chrome/app/BUILD.gn
@@ -458,6 +458,7 @@ deps += [ "//chrome/browser/chromeos/kiosk_next_home/mojom", "//chrome/browser/chromeos/supervision/mojom", + "//chrome/browser/ui/webui/chromeos/add_supervision:mojo_bindings", "//chrome/browser/ui/webui/chromeos/machine_learning:mojo_bindings", "//chromeos/assistant:buildflags", "//chromeos/services/cellular_setup/public/mojom",
diff --git a/chrome/app/chrome_content_browser_overlay_manifest.cc b/chrome/app/chrome_content_browser_overlay_manifest.cc index 63c57fb..23d5778 100644 --- a/chrome/app/chrome_content_browser_overlay_manifest.cc +++ b/chrome/app/chrome_content_browser_overlay_manifest.cc
@@ -50,6 +50,7 @@ #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/kiosk_next_home/mojom/kiosk_next_home_interface_broker.mojom.h" // nogncheck #include "chrome/browser/chromeos/supervision/mojom/onboarding_controller.mojom.h" +#include "chrome/browser/ui/webui/chromeos/add_supervision/add_supervision.mojom.h" #include "chrome/browser/ui/webui/chromeos/machine_learning/machine_learning_internals_page_handler.mojom.h" #include "chromeos/assistant/buildflags.h" // nogncheck #include "chromeos/services/cellular_setup/public/mojom/cellular_setup.mojom.h" @@ -260,6 +261,9 @@ mojom::DiscardsDetailsProvider, performance_manager::mojom::WebUIGraphDump, #endif +#if defined(OS_CHROMEOS) + add_supervision::mojom::AddSupervisionHandler, +#endif mojom::BluetoothInternalsHandler, mojom::InterventionsInternalsPageHandler, mojom::OmniboxPageHandler, mojom::ResetPasswordHandler,
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 4e20308..08551bf5 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -3909,4 +3909,9 @@ <message name="IDS_TPM_AUTO_UPDATE_REBOOT_NOTIFICATION_MESSAGE" desc="Text for the notification informing the user that a TPM update will be performed after reboot which will result in local data being deleted."> The next time you restart your device, your administrator will perform a one-time update that will delete your local data. </message> + + <!-- Strings for Add Supervision screen --> + <message name="IDS_ADD_SUPERVISION_PAGE_TITLE" desc="Title for the Chrome OS Add Supervision screen."> + Add Supervision + </message> </grit-part>
diff --git a/chrome/app_shim/BUILD.gn b/chrome/app_shim/BUILD.gn index f651d88..93bf394 100644 --- a/chrome/app_shim/BUILD.gn +++ b/chrome/app_shim/BUILD.gn
@@ -34,7 +34,7 @@ ] } -tweak_info_plist("app_mode_loader_plist") { +tweak_info_plist("tweak_app_mode_loader_plist") { info_plist = "app_mode-Info.plist" args = [ "--breakpad=0", @@ -43,13 +43,30 @@ ] } -mac_app_bundle("app_mode_loader") { - extra_configs = [ "//build/config/compiler:wexit_time_destructors" ] +mac_info_plist("app_mode_loader_plist") { + info_plist_target = ":tweak_app_mode_loader_plist" - info_plist_target = ":app_mode_loader_plist" + executable_name = "app_mode_loader" + extra_substitutions = [ "APP_MODE_APP_BUNDLE_ID=$chrome_mac_bundle_id.app.@APP_MODE_SHORTCUT_ID@", ] +} + +bundle_data("app_mode_loader_plist_bundle_data") { + sources = get_target_outputs(":app_mode_loader_plist") + + outputs = [ + "{{bundle_resources_dir}}/app_mode-Info.plist", + ] + + public_deps = [ + ":app_mode_loader_plist", + ] +} + +executable("app_mode_loader") { + configs += [ "//build/config/compiler:wexit_time_destructors" ] sources = [ "app_mode_loader_mac.mm",
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 6452b5b..f7676d3 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1109,6 +1109,10 @@ "performance_manager/performance_manager_tab_helper.cc", "performance_manager/performance_manager_tab_helper.h", "performance_manager/persistence/site_data/disk_site_data_store.h", + "performance_manager/persistence/site_data/exponential_moving_average.cc", + "performance_manager/persistence/site_data/exponential_moving_average.h", + "performance_manager/persistence/site_data/feature_usage.h", + "performance_manager/persistence/site_data/tab_visibility.h", "performance_manager/public/graph/frame_node.h", "performance_manager/public/graph/graph.h", "performance_manager/public/graph/node_attached_data.h", @@ -1445,8 +1449,6 @@ "renderer_preferences_util.h", "resource_coordinator/discard_before_unload_helper.cc", "resource_coordinator/discard_before_unload_helper.h", - "resource_coordinator/exponential_moving_average.cc", - "resource_coordinator/exponential_moving_average.h", "resource_coordinator/resource_coordinator_parts.cc", "resource_coordinator/resource_coordinator_parts.h", "resource_coordinator/session_restore_policy.cc", @@ -3122,7 +3124,6 @@ "resource_coordinator/local_site_characteristics_data_writer.cc", "resource_coordinator/local_site_characteristics_data_writer.h", "resource_coordinator/local_site_characteristics_database.h", - "resource_coordinator/local_site_characteristics_feature_usage.h", "resource_coordinator/local_site_characteristics_non_recording_data_store.cc", "resource_coordinator/local_site_characteristics_non_recording_data_store.h", "resource_coordinator/local_site_characteristics_noop_data_writer.cc", @@ -3132,7 +3133,6 @@ "resource_coordinator/site_characteristics_data_reader.h", "resource_coordinator/site_characteristics_data_store.h", "resource_coordinator/site_characteristics_data_writer.h", - "resource_coordinator/site_characteristics_tab_visibility.h", "resource_coordinator/tab_activity_watcher.cc", "resource_coordinator/tab_activity_watcher.h", "resource_coordinator/tab_lifecycle_observer.h", @@ -5136,6 +5136,7 @@ if (is_chromeos) { deps += [ + "//chrome/browser/ui/webui/chromeos/add_supervision:mojo_bindings_js", "//chrome/browser/ui/webui/chromeos/machine_learning:mojo_bindings_js", ] }
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 9f969bb..a17745693 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -2327,13 +2327,6 @@ FEATURE_VALUE_TYPE(features::kDisablePostScriptPrinting)}, #endif // defined(OS_WIN) -#if defined(OS_CHROMEOS) - {"force-enable-stylus-tools", - flag_descriptions::kForceEnableStylusToolsName, - flag_descriptions::kForceEnableStylusToolsDescription, kOsCrOS, - SINGLE_VALUE_TYPE(ash::switches::kAshForceEnableStylusTools)}, -#endif // defined(OS_CHROMEOS) - #if defined(OS_WIN) {"new-usb-backend", flag_descriptions::kNewUsbBackendName, flag_descriptions::kNewUsbBackendDescription, kOsWin,
diff --git a/chrome/browser/badging/badge_manager_delegate_win.cc b/chrome/browser/badging/badge_manager_delegate_win.cc index c588672..e3affbe 100644 --- a/chrome/browser/badging/badge_manager_delegate_win.cc +++ b/chrome/browser/badging/badge_manager_delegate_win.cc
@@ -73,8 +73,8 @@ bool BadgeManagerDelegateWin::IsAppBrowser(Browser* browser, const std::string& app_id) { - return browser->web_app_controller() && - browser->web_app_controller()->GetAppId() == app_id && + return browser->app_controller() && + browser->app_controller()->GetAppId() == app_id && browser->profile() == profile_; }
diff --git a/chrome/browser/badging/badge_service_impl.cc b/chrome/browser/badging/badge_service_impl.cc index 77118ea4..fc0ccf6c 100644 --- a/chrome/browser/badging/badge_service_impl.cc +++ b/chrome/browser/badging/badge_service_impl.cc
@@ -80,10 +80,10 @@ } bool BadgeServiceImpl::IsInApp() { - web_app::AppBrowserController* web_app_controller = - chrome::FindBrowserWithWebContents(web_contents_)->web_app_controller(); - return web_app_controller && - extensions::IsSameScope(web_app_controller->GetAppLaunchURL(), + web_app::AppBrowserController* app_controller = + chrome::FindBrowserWithWebContents(web_contents_)->app_controller(); + return app_controller && + extensions::IsSameScope(app_controller->GetAppLaunchURL(), web_contents_->GetLastCommittedURL(), web_contents_->GetBrowserContext()); }
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index 48ec1c49..ac78bd9 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -698,6 +698,11 @@ <include name="IDR_SYS_INTERNALS_IMAGE_CPU_SVG" file="resources\chromeos\sys_internals\img\cpu.svg" type="BINDATA" /> <include name="IDR_SYS_INTERNALS_IMAGE_MEMORY_SVG" file="resources\chromeos\sys_internals\img\memory.svg" type="BINDATA" /> <include name="IDR_SYS_INTERNALS_IMAGE_ZRAM_SVG" file="resources\chromeos\sys_internals\img\zram.svg" type="BINDATA" /> + <include name="IDR_ADD_SUPERVISION_HTML" file="resources\chromeos\add_supervision\add_supervision.html" compress="gzip" type="BINDATA" /> + <include name="IDR_ADD_SUPERVISION_JS" file="resources\chromeos\add_supervision\add_supervision.js" compress="gzip" type="BINDATA" /> + <include name="IDR_ADD_SUPERVISION_API_SERVER_JS" file="resources\chromeos\add_supervision\add_supervision_api_server.js" compress="gzip" type="BINDATA" /> + <include name="IDR_ADD_SUPERVISION_POST_MESSAGE_API_JS" file="resources\chromeos\add_supervision\post_message_api.js" compress="gzip" type="BINDATA" /> + <include name="IDR_ADD_SUPERVISION_MOJOM_LITE_JS" file="${root_gen_dir}\chrome\browser\ui\webui\chromeos\add_supervision\add_supervision.mojom-lite.js" compress="gzip" use_base_dir="false" type="BINDATA" /> </if> <if expr="chromeos"> <include name="IDR_ASSISTANT_LOGO_PNG" file="resources\chromeos\assistant_optin\assistant_logo.png" type="BINDATA" />
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 9f0839be..6545fd3 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -3278,10 +3278,10 @@ // WebContents. Browser* browser = chrome::FindBrowserWithWebContents(contents); if (base::FeatureList::IsEnabled(features::kDesktopPWAWindowing) && - browser && browser->web_app_controller() && - browser->web_app_controller()->CreatedForInstalledPwa()) { + browser && browser->app_controller() && + browser->app_controller()->CreatedForInstalledPwa()) { // PWAs should be hosted apps. - DCHECK(browser->web_app_controller()->IsHostedApp()); + DCHECK(browser->app_controller()->IsHostedApp()); // HostedApps that are PWAs are always created through WebAppProvider // or BookmarkAppHelper for profiles that support them, so we should // always be able to retrieve a WebAppProvider from the Profile. @@ -3291,15 +3291,15 @@ web_prefs->web_app_scope = web_app::WebAppProvider::Get(profile) ->registrar() - .GetScopeUrlForApp(*browser->web_app_controller()->GetAppId()); + .GetScopeUrlForApp(*browser->app_controller()->GetAppId()); } } #endif #if BUILDFLAG(ENABLE_EXTENSIONS) Browser* browser = chrome::FindBrowserWithWebContents(contents); - if (browser && browser->web_app_controller() && - browser->web_app_controller()->CreatedForInstalledPwa()) { + if (browser && browser->app_controller() && + browser->app_controller()->CreatedForInstalledPwa()) { web_prefs->strict_mixed_content_checking = true; } #endif
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index cbde5729..ab0f16a 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -1679,6 +1679,8 @@ "policy/single_app_install_event_log.h", "policy/status_collector/activity_storage.cc", "policy/status_collector/activity_storage.h", + "policy/status_collector/child_status_collector.cc", + "policy/status_collector/child_status_collector.h", "policy/status_collector/device_status_collector.cc", "policy/status_collector/device_status_collector.h", "policy/status_collector/status_collector.cc",
diff --git a/chrome/browser/chromeos/arc/pip/arc_picture_in_picture_window_controller_impl.cc b/chrome/browser/chromeos/arc/pip/arc_picture_in_picture_window_controller_impl.cc index 73284f1..6ade5a5 100644 --- a/chrome/browser/chromeos/arc/pip/arc_picture_in_picture_window_controller_impl.cc +++ b/chrome/browser/chromeos/arc/pip/arc_picture_in_picture_window_controller_impl.cc
@@ -14,7 +14,7 @@ ArcPictureInPictureWindowControllerImpl:: ~ArcPictureInPictureWindowControllerImpl() { - Close(false, false); + Close(false); } gfx::Size ArcPictureInPictureWindowControllerImpl::Show() { @@ -22,9 +22,7 @@ return gfx::Size(); } -void ArcPictureInPictureWindowControllerImpl::Close( - bool should_pause_video, - bool should_reset_pip_player) { +void ArcPictureInPictureWindowControllerImpl::Close(bool should_pause_video) { // TODO(edcourtney): Currently, |should_pause_video| will always be false // here, but if that changes, we should pause the video on the Android side. arc_pip_bridge_->ClosePip();
diff --git a/chrome/browser/chromeos/arc/pip/arc_picture_in_picture_window_controller_impl.h b/chrome/browser/chromeos/arc/pip/arc_picture_in_picture_window_controller_impl.h index ee4f7ea..1c5ff704 100644 --- a/chrome/browser/chromeos/arc/pip/arc_picture_in_picture_window_controller_impl.h +++ b/chrome/browser/chromeos/arc/pip/arc_picture_in_picture_window_controller_impl.h
@@ -31,7 +31,7 @@ // PictureInPictureWindowController: gfx::Size Show() override; - void Close(bool should_pause_video, bool should_reset_pip_player) override; + void Close(bool should_pause_video) override; void CloseAndFocusInitiator() override; void OnWindowDestroyed() override; void EmbedSurface(const viz::SurfaceId& surface_id,
diff --git a/chrome/browser/chromeos/child_accounts/consumer_status_reporting_service.cc b/chrome/browser/chromeos/child_accounts/consumer_status_reporting_service.cc index 42b1640..ec69b96e 100644 --- a/chrome/browser/chromeos/child_accounts/consumer_status_reporting_service.cc +++ b/chrome/browser/chromeos/child_accounts/consumer_status_reporting_service.cc
@@ -9,7 +9,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/chromeos/child_accounts/event_based_status_reporting_service_factory.h" #include "chrome/browser/chromeos/child_accounts/usage_time_limit_processor.h" -#include "chrome/browser/chromeos/policy/status_collector/device_status_collector.h" +#include "chrome/browser/chromeos/policy/status_collector/child_status_collector.h" #include "chrome/browser/chromeos/policy/status_uploader.h" #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h" #include "chrome/browser/chromeos/policy/user_policy_manager_factory_chromeos.h" @@ -85,19 +85,13 @@ VLOG(1) << "Creating status uploader for consumer status reporting."; day_reset_time_ = new_day_reset_time; - status_uploader_ = std::make_unique<policy::StatusUploader>( client, - std::make_unique<policy::DeviceStatusCollector>( + std::make_unique<policy::ChildStatusCollector>( pref_change_registrar_->prefs(), system::StatisticsProvider::GetInstance(), - policy::DeviceStatusCollector::VolumeInfoFetcher(), - policy::DeviceStatusCollector::CPUStatisticsFetcher(), - policy::DeviceStatusCollector::CPUTempFetcher(), - policy::DeviceStatusCollector::AndroidStatusFetcher(), - policy::DeviceStatusCollector::TpmStatusFetcher(), - policy::DeviceStatusCollector::EMMCLifetimeFetcher(), day_reset_time_, - false /* is_enterprise_reporting */), + policy::ChildStatusCollector::AndroidStatusFetcher(), + day_reset_time_), base::ThreadTaskRunnerHandle::Get(), kStatusUploadFrequency); } @@ -107,8 +101,8 @@ base::TimeDelta ConsumerStatusReportingService::GetChildScreenTime() const { // Notice that this cast works because we know that |status_uploader_| has a - // DeviceStatusCollector (see above). - return static_cast<policy::DeviceStatusCollector*>( + // ChildStatusCollector (see above). + return static_cast<policy::ChildStatusCollector*>( status_uploader_->status_collector()) ->GetActiveChildScreenTime(); }
diff --git a/chrome/browser/chromeos/login/error_screen_browsertest.cc b/chrome/browser/chromeos/login/error_screen_browsertest.cc index 956beed..39d6ea1 100644 --- a/chrome/browser/chromeos/login/error_screen_browsertest.cc +++ b/chrome/browser/chromeos/login/error_screen_browsertest.cc
@@ -6,21 +6,27 @@ #include "base/strings/strcat.h" #include "base/test/bind_test_util.h" #include "chrome/browser/chromeos/login/login_wizard.h" +#include "chrome/browser/chromeos/login/mixin_based_in_process_browser_test.h" #include "chrome/browser/chromeos/login/screens/error_screen.h" #include "chrome/browser/chromeos/login/test/js_checker.h" +#include "chrome/browser/chromeos/login/test/login_manager_mixin.h" #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h" #include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/ui/webui/chromeos/login/error_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/welcome_screen_handler.h" #include "chrome/test/base/in_process_browser_test.h" +#include "chromeos/dbus/session_manager/fake_session_manager_client.h" +#include "chromeos/dbus/session_manager/session_manager_client.h" #include "chromeos/dbus/shill/shill_profile_client.h" #include "chromeos/network/network_state_test_helper.h" +#include "components/user_manager/user_manager.h" #include "third_party/cros_system_api/dbus/shill/dbus-constants.h" namespace chromeos { namespace { +constexpr char kTestUser[] = "test-user1@gmail.com"; constexpr char kWifiServiceName[] = "stub_wifi"; constexpr char kWifiNetworkName[] = "wifi-test-network"; @@ -167,4 +173,48 @@ EXPECT_TRUE(callback_called); } +class GuestErrorScreenTest : public MixinBasedInProcessBrowserTest { + public: + GuestErrorScreenTest() { login_manager_.set_session_restore_enabled(); } + ~GuestErrorScreenTest() override = default; + + void SetUpInProcessBrowserTestFixture() override { + MixinBasedInProcessBrowserTest::SetUpInProcessBrowserTestFixture(); + SessionManagerClient::InitializeFakeInMemory(); + FakeSessionManagerClient::Get()->set_supports_browser_restart(true); + } + + protected: + const LoginManagerMixin::TestUserInfo test_user_{ + AccountId::FromUserEmailGaiaId(kTestUser, kTestUser)}; + LoginManagerMixin login_manager_{&mixin_host_, {test_user_}}; + + private: + DISALLOW_COPY_AND_ASSIGN(GuestErrorScreenTest); +}; + +// Test that guest signin option is shown when enabled and that clicking on it +// starts a guest session. +IN_PROC_BROWSER_TEST_F(GuestErrorScreenTest, PRE_GuestLogin) { + ShowLoginWizard(OobeScreen::SCREEN_TEST_NO_WINDOW); + GetScreen()->AllowGuestSignin(true); + GetScreen()->SetUIState(NetworkError::UI_STATE_UPDATE); + GetScreen()->Show(); + + OobeScreenWaiter(ErrorScreenView::kScreenId).Wait(); + test::OobeJS().ExpectVisiblePath({"error-guest-signin-link"}); + test::OobeJS().ClickOnPath({"error-guest-signin-link"}); + + base::RunLoop restart_job_waiter; + FakeSessionManagerClient::Get()->set_restart_job_callback( + restart_job_waiter.QuitClosure()); + restart_job_waiter.Run(); +} + +IN_PROC_BROWSER_TEST_F(GuestErrorScreenTest, GuestLogin) { + login_manager_.WaitForActiveSession(); + user_manager::UserManager* user_manager = user_manager::UserManager::Get(); + EXPECT_TRUE(user_manager->IsLoggedInAsGuest()); +} + } // namespace chromeos
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager.cc b/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager.cc index f049d9bb..bfb71b4 100644 --- a/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager.cc +++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager.cc
@@ -323,16 +323,9 @@ bool PluginVmImageManager::VerifyDownload( const std::string& downloaded_archive_hash) { - // Hash should be there in the common case. However, there are situations, - // when hash could not be available, for example, when download is parallel - // or the completion of download is reported after restart. Therefore, hash - // not being specified should not resolve in download being considered - // unsuccessful, but should be logged. - // TODO(okalitova): Consider download as unsuccessful once hash should always - // be in place. if (downloaded_archive_hash.empty()) { - LOG(WARNING) << "No hash for downloaded PluginVm image archive"; - return true; + LOG(ERROR) << "No hash found for downloaded PluginVm image archive"; + return false; } const base::Value* plugin_vm_image_hash_ptr = profile_->GetPrefs()
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager_unittest.cc b/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager_unittest.cc index a563413..b0b82a5 100644 --- a/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager_unittest.cc +++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager_unittest.cc
@@ -87,6 +87,7 @@ manager_ = PluginVmImageManagerFactory::GetForProfile(profile_.get()); download_service_->SetIsReady(true); + download_service_->SetHash256(kHash); download_service_->set_client( new PluginVmImageDownloadClient(profile_.get())); manager_->SetDownloadServiceForTesting(download_service_); @@ -394,6 +395,7 @@ EXPECT_FALSE(manager_->VerifyDownload(kHash2)); EXPECT_TRUE(manager_->VerifyDownload(kHashUppercase)); EXPECT_TRUE(manager_->VerifyDownload(kHash)); + EXPECT_FALSE(manager_->VerifyDownload(std::string())); } } // namespace plugin_vm
diff --git a/chrome/browser/chromeos/policy/status_collector/child_status_collector.cc b/chrome/browser/chromeos/policy/status_collector/child_status_collector.cc new file mode 100644 index 0000000..d80d81fd --- /dev/null +++ b/chrome/browser/chromeos/policy/status_collector/child_status_collector.cc
@@ -0,0 +1,579 @@ +// 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/chromeos/policy/status_collector/child_status_collector.h" + +#include <stddef.h> +#include <stdint.h> + +#include <algorithm> +#include <cstdio> +#include <limits> +#include <set> +#include <sstream> +#include <utility> + +#include "base/base64.h" +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/feature_list.h" +#include "base/format_macros.h" +#include "base/logging.h" +#include "base/optional.h" +#include "base/stl_util.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" +#include "base/task/post_task.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "base/values.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/chromeos/login/users/chrome_user_manager.h" +#include "chrome/browser/chromeos/policy/status_collector/activity_storage.h" +#include "chrome/browser/chromeos/policy/status_collector/device_status_collector.h" +#include "chrome/browser/chromeos/policy/status_collector/status_collector_state.h" +#include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "chrome/browser/chromeos/settings/cros_settings.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/common/chrome_features.h" +#include "chrome/common/pref_names.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/power_manager/idle.pb.h" +#include "chromeos/dbus/util/version_loader.h" +#include "chromeos/login/login_state/login_state.h" +#include "chromeos/settings/cros_settings_names.h" +#include "chromeos/settings/timezone_settings.h" +#include "chromeos/system/statistics_provider.h" +#include "components/arc/arc_service_manager.h" +#include "components/arc/common/enterprise_reporting.mojom.h" +#include "components/arc/session/arc_bridge_service.h" +#include "components/policy/core/common/cloud/cloud_policy_constants.h" +#include "components/policy/core/common/cloud/cloud_policy_util.h" +#include "components/policy/proto/device_management_backend.pb.h" +#include "components/prefs/pref_service.h" +#include "components/prefs/scoped_user_pref_update.h" +#include "components/session_manager/core/session_manager.h" +#include "components/session_manager/session_manager_types.h" +#include "components/user_manager/user.h" +#include "components/user_manager/user_manager.h" +#include "components/user_manager/user_type.h" +#include "content/public/browser/browser_thread.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace { + +namespace em = enterprise_management; + +using base::Time; +using base::TimeDelta; + +// How much time in the past to store active periods for. +constexpr TimeDelta kMaxStoredPastActivityInterval = TimeDelta::FromDays(30); + +// How much time in the future to store active periods for. +constexpr TimeDelta kMaxStoredFutureActivityInterval = TimeDelta::FromDays(2); + +// How often the child's usage time is stored. +static constexpr base::TimeDelta kUpdateChildActiveTimeInterval = + base::TimeDelta::FromSeconds(30); + +bool ReadAndroidStatus( + const policy::ChildStatusCollector::AndroidStatusReceiver& receiver) { + auto* const arc_service_manager = arc::ArcServiceManager::Get(); + if (!arc_service_manager) + return false; + auto* const instance_holder = + arc_service_manager->arc_bridge_service()->enterprise_reporting(); + if (!instance_holder) + return false; + auto* const instance = + ARC_GET_INSTANCE_FOR_METHOD(instance_holder, GetStatus); + if (!instance) + return false; + instance->GetStatus(receiver); + return true; +} + +} // namespace + +namespace policy { + +class ChildStatusCollectorState : public StatusCollectorState { + public: + explicit ChildStatusCollectorState( + const scoped_refptr<base::SequencedTaskRunner> task_runner, + const StatusCollectorCallback& response) + : StatusCollectorState(task_runner, response) {} + + bool FetchAndroidStatus(const DeviceStatusCollector::AndroidStatusFetcher& + android_status_fetcher) { + return android_status_fetcher.Run(base::BindRepeating( + &ChildStatusCollectorState::OnAndroidInfoReceived, this)); + } + + private: + ~ChildStatusCollectorState() override = default; + + void OnAndroidInfoReceived(const std::string& status, + const std::string& droid_guard_info) { + // TODO(crbug.com/827386): remove after migration. + em::AndroidStatus* const session_android_status = + response_params_.session_status->mutable_android_status(); + session_android_status->set_status_payload(status); + session_android_status->set_droid_guard_info(droid_guard_info); + // END. + + em::AndroidStatus* const child_android_status = + response_params_.child_status->mutable_android_status(); + child_android_status->set_status_payload(status); + child_android_status->set_droid_guard_info(droid_guard_info); + } +}; + +ChildStatusCollector::ChildStatusCollector( + PrefService* pref_service, + chromeos::system::StatisticsProvider* provider, + const AndroidStatusFetcher& android_status_fetcher, + TimeDelta activity_day_start) + : StatusCollector(provider, + chromeos::CrosSettings::Get(), + chromeos::PowerManagerClient::Get(), + session_manager::SessionManager::Get(), + activity_day_start), + pref_service_(pref_service), + android_status_fetcher_(android_status_fetcher) { + // protected fields of `StatusCollector`. + max_stored_past_activity_interval_ = kMaxStoredPastActivityInterval; + max_stored_future_activity_interval_ = kMaxStoredFutureActivityInterval; + + // Get the task runner of the current thread, so we can queue status responses + // on this thread. + CHECK(base::SequencedTaskRunnerHandle::IsSet()); + task_runner_ = base::SequencedTaskRunnerHandle::Get(); + + if (android_status_fetcher_.is_null()) + android_status_fetcher_ = base::BindRepeating(&ReadAndroidStatus); + + update_child_usage_timer_.Start(FROM_HERE, kUpdateChildActiveTimeInterval, + this, + &ChildStatusCollector::UpdateChildUsageTime); + // Watch for changes to the individual policies that control what the status + // reports contain. + base::Closure callback = base::BindRepeating( + &ChildStatusCollector::UpdateReportingSettings, base::Unretained(this)); + version_info_subscription_ = cros_settings_->AddSettingsObserver( + chromeos::kReportDeviceVersionInfo, callback); + boot_mode_subscription_ = cros_settings_->AddSettingsObserver( + chromeos::kReportDeviceBootMode, callback); + + // Watch for changes on the device state to calculate the child's active time. + if (base::FeatureList::IsEnabled(features::kUsageTimeStateNotifier)) { + chromeos::UsageTimeStateNotifier::GetInstance()->AddObserver(this); + } else { + power_manager_->AddObserver(this); + session_manager_->AddObserver(this); + } + + // Fetch the current values of the policies. + UpdateReportingSettings(); + + // Get the OS version. + base::PostTaskWithTraitsAndReplyWithResult( + FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, + base::BindRepeating(&chromeos::version_loader::GetVersion, + chromeos::version_loader::VERSION_FULL), + base::BindRepeating(&ChildStatusCollector::OnOSVersion, + weak_factory_.GetWeakPtr())); + + DCHECK(pref_service_->GetInitializationStatus() != + PrefService::INITIALIZATION_STATUS_WAITING); + activity_storage_ = std::make_unique<ActivityStorage>( + pref_service_, prefs::kUserActivityTimes, activity_day_start, false); +} + +ChildStatusCollector::~ChildStatusCollector() { + if (base::FeatureList::IsEnabled(features::kUsageTimeStateNotifier)) { + chromeos::UsageTimeStateNotifier::GetInstance()->RemoveObserver(this); + } else { + power_manager_->RemoveObserver(this); + session_manager_->RemoveObserver(this); + } +} + +TimeDelta ChildStatusCollector::GetActiveChildScreenTime() { + UpdateChildUsageTime(); + return TimeDelta::FromMilliseconds( + pref_service_->GetInteger(prefs::kChildScreenTimeMilliseconds)); +} + +void ChildStatusCollector::UpdateReportingSettings() { + // Attempt to fetch the current value of the reporting settings. + // If trusted values are not available, register this function to be called + // back when they are available. + if (chromeos::CrosSettingsProvider::TRUSTED != + cros_settings_->PrepareTrustedValues( + base::BindRepeating(&ChildStatusCollector::UpdateReportingSettings, + weak_factory_.GetWeakPtr()))) { + return; + } + + // Activity times. + report_activity_times_ = + base::FeatureList::IsEnabled(features::kUsageTimeLimitPolicy); + + // Settings related. + report_version_info_ = true; + cros_settings_->GetBoolean(chromeos::kReportDeviceVersionInfo, + &report_version_info_); + + report_boot_mode_ = true; + cros_settings_->GetBoolean(chromeos::kReportDeviceBootMode, + &report_boot_mode_); +} + +void ChildStatusCollector::OnSessionStateChanged() { + UpdateChildUsageTime(); + last_state_active_ = + session_manager::SessionManager::Get()->session_state() == + session_manager::SessionState::ACTIVE; +} + +void ChildStatusCollector::OnUsageTimeStateChange( + chromeos::UsageTimeStateNotifier::UsageTimeState state) { + DCHECK(base::FeatureList::IsEnabled(features::kUsageTimeStateNotifier)); + + UpdateChildUsageTime(); + last_state_active_ = + state == chromeos::UsageTimeStateNotifier::UsageTimeState::ACTIVE; +} + +void ChildStatusCollector::ScreenIdleStateChanged( + const power_manager::ScreenIdleState& state) { + DCHECK(!base::FeatureList::IsEnabled(features::kUsageTimeStateNotifier)); + + UpdateChildUsageTime(); + // It is active if screen is on and if the session is also active. + last_state_active_ = + !state.off() && session_manager_->session_state() == + session_manager::SessionState::ACTIVE; +} + +void ChildStatusCollector::SuspendImminent( + power_manager::SuspendImminent::Reason reason) { + DCHECK(!base::FeatureList::IsEnabled(features::kUsageTimeStateNotifier)); + + UpdateChildUsageTime(); + // Device is going to be suspended, so it won't be active. + last_state_active_ = false; +} + +void ChildStatusCollector::SuspendDone(const base::TimeDelta& sleep_duration) { + DCHECK(!base::FeatureList::IsEnabled(features::kUsageTimeStateNotifier)); + + UpdateChildUsageTime(); + // Device is returning from suspension, so it is considered active if the + // session is also active. + last_state_active_ = session_manager_->session_state() == + session_manager::SessionState::ACTIVE; +} + +void ChildStatusCollector::UpdateChildUsageTime() { + if (!report_activity_times_) { + return; + } + + Time now = GetCurrentTime(); + Time reset_time = now.LocalMidnight() + activity_day_start_; + if (reset_time > now) + reset_time -= TimeDelta::FromDays(1); + // Reset screen time if it has not been reset today. + if (reset_time > pref_service_->GetTime(prefs::kLastChildScreenTimeReset)) { + pref_service_->SetTime(prefs::kLastChildScreenTimeReset, now); + pref_service_->SetInteger(prefs::kChildScreenTimeMilliseconds, 0); + pref_service_->CommitPendingWrite(); + } + + if (!last_active_check_.is_null() && last_state_active_) { + // If it's been too long since the last report, or if the activity is + // negative (which can happen when the clock changes), assume a single + // interval of activity. This is the same strategy used to enterprise users. + base::TimeDelta active_seconds = now - last_active_check_; + if (active_seconds < base::TimeDelta::FromSeconds(0) || + active_seconds >= (2 * kUpdateChildActiveTimeInterval)) { + activity_storage_->AddActivityPeriod(now - kUpdateChildActiveTimeInterval, + now, now, + /*active_user_email=*/std::string()); + } else { + activity_storage_->AddActivityPeriod(last_active_check_, now, now, + /*active_user_email=*/std::string()); + } + + activity_storage_->PruneActivityPeriods( + now, max_stored_past_activity_interval_, + max_stored_future_activity_interval_); + } + last_active_check_ = now; +} + +bool ChildStatusCollector::GetActivityTimes( + em::DeviceStatusReportRequest* status) { + UpdateChildUsageTime(); + + // Signed-in user is reported in child reporting. + std::vector<ActivityStorage::ActivityPeriod> activity_times = + activity_storage_->GetFilteredActivityPeriods(/*omit_emails=*/false); + + bool anything_reported = false; + for (const auto& activity_period : activity_times) { + // This is correct even when there are leap seconds, because when a leap + // second occurs, two consecutive seconds have the same timestamp. + int64_t end_timestamp = + activity_period.start_timestamp + Time::kMillisecondsPerDay; + + em::ActiveTimePeriod* active_period = status->add_active_periods(); + em::TimePeriod* period = active_period->mutable_time_period(); + period->set_start_timestamp(activity_period.start_timestamp); + period->set_end_timestamp(end_timestamp); + active_period->set_active_duration(activity_period.activity_milliseconds); + // Report user email only if users reporting is turned on. + if (!activity_period.user_email.empty()) + active_period->set_user_email(activity_period.user_email); + if (activity_period.start_timestamp >= last_reported_day_) { + last_reported_day_ = activity_period.start_timestamp; + duration_for_last_reported_day_ = activity_period.activity_milliseconds; + } + anything_reported = true; + } + return anything_reported; +} + +bool ChildStatusCollector::GetActivityTimes( + em::ChildStatusReportRequest* status) { + UpdateChildUsageTime(); + + // Signed-in user is reported in child reporting. + std::vector<ActivityStorage::ActivityPeriod> activity_times = + activity_storage_->GetFilteredActivityPeriods(/*omit_emails=*/false); + + bool anything_reported = false; + for (const auto& activity_period : activity_times) { + // This is correct even when there are leap seconds, because when a leap + // second occurs, two consecutive seconds have the same timestamp. + int64_t end_timestamp = + activity_period.start_timestamp + Time::kMillisecondsPerDay; + + em::ScreenTimeSpan* screen_time_span = status->add_screen_time_span(); + em::TimePeriod* period = screen_time_span->mutable_time_period(); + period->set_start_timestamp(activity_period.start_timestamp); + period->set_end_timestamp(end_timestamp); + screen_time_span->set_active_duration_ms( + activity_period.activity_milliseconds); + if (activity_period.start_timestamp >= last_reported_day_) { + last_reported_day_ = activity_period.start_timestamp; + duration_for_last_reported_day_ = activity_period.activity_milliseconds; + } + anything_reported = true; + } + return anything_reported; +} + +bool ChildStatusCollector::GetVersionInfo( + em::DeviceStatusReportRequest* status) { + status->set_os_version(os_version_); + return true; +} + +bool ChildStatusCollector::GetVersionInfo( + em::ChildStatusReportRequest* status) { + status->set_os_version(os_version_); + return true; +} + +void ChildStatusCollector::GetStatusAsync( + const StatusCollectorCallback& response) { + // Must be on creation thread since some stats are written to in that thread + // and accessing them from another thread would lead to race conditions. + DCHECK(thread_checker_.CalledOnValidThread()); + + // Some of the data we're collecting is gathered in background threads. + // This object keeps track of the state of each async request. + scoped_refptr<ChildStatusCollectorState> state( + new ChildStatusCollectorState(task_runner_, response)); + + // Gather status data. The following calls might queue some async queries. + GetDeviceStatus(state); + GetSessionStatus(state); + FillChildStatusReportRequest(state); + + // If there are no outstanding async queries, the destructor of |state| calls + // |response|. If there are async queries, the queries hold references to + // |state|, so that |state| is only destroyed when the last async query has + // finished. +} + +void ChildStatusCollector::GetDeviceStatus( + scoped_refptr<ChildStatusCollectorState> state) { + em::DeviceStatusReportRequest* status = + state->response_params().device_status.get(); + bool anything_reported = false; + + if (report_version_info_) + anything_reported |= GetVersionInfo(status); + + if (report_activity_times_) + anything_reported |= GetActivityTimes(status); + + if (report_boot_mode_) { + base::Optional<std::string> boot_mode = + StatusCollector::GetBootMode(statistics_provider_); + if (boot_mode) { + status->set_boot_mode(*boot_mode); + anything_reported = true; + } + } + + // Wipe pointer if we didn't actually add any data. + if (!anything_reported) + state->response_params().device_status.reset(); +} + +bool ChildStatusCollector::GetSessionStatusForUser( + scoped_refptr<ChildStatusCollectorState> state, + em::SessionStatusReportRequest* status, + const user_manager::User* user) { + // Child accounts are not local accounts. + DCHECK(!user->IsDeviceLocalAccount()); + + Profile* const profile = + chromeos::ProfileHelper::Get()->GetProfileByUser(user); + if (!profile) + return false; + + // Time zone. + const std::string current_timezone = + base::UTF16ToUTF8(chromeos::system::TimezoneSettings::GetInstance() + ->GetCurrentTimezoneID()); + status->set_time_zone(current_timezone); + + // Android status. + const bool report_android_status = + profile->GetPrefs()->GetBoolean(prefs::kReportArcStatusEnabled); + if (report_android_status) + GetAndroidStatus(state); + + status->set_user_dm_token(GetDMTokenForProfile(profile)); + + // At least time zone is always reported. + return true; +} + +bool ChildStatusCollector::FillUserSpecificFields( + scoped_refptr<ChildStatusCollectorState> state, + em::ChildStatusReportRequest* status, + const user_manager::User* user) { + Profile* const profile = + chromeos::ProfileHelper::Get()->GetProfileByUser(user); + if (!profile) + return false; + + // Time zone. + const std::string current_timezone = + base::UTF16ToUTF8(chromeos::system::TimezoneSettings::GetInstance() + ->GetCurrentTimezoneID()); + status->set_time_zone(current_timezone); + + // Android status. + const bool report_android_status = + profile->GetPrefs()->GetBoolean(prefs::kReportArcStatusEnabled); + if (report_android_status) + GetAndroidStatus(state); + + if (!user->IsDeviceLocalAccount()) + status->set_user_dm_token(GetDMTokenForProfile(profile)); + + // At least time zone is always reported. + return true; +} + +void ChildStatusCollector::GetSessionStatus( + scoped_refptr<ChildStatusCollectorState> state) { + em::SessionStatusReportRequest* status = + state->response_params().session_status.get(); + bool anything_reported = false; + + user_manager::UserManager* user_manager = user_manager::UserManager::Get(); + const user_manager::User* const primary_user = user_manager->GetPrimaryUser(); + DCHECK(primary_user != nullptr); + + anything_reported |= GetSessionStatusForUser(state, status, primary_user); + + // Wipe pointer if we didn't actually add any data. + if (!anything_reported) + state->response_params().session_status.reset(); +} + +bool ChildStatusCollector::GetAndroidStatus( + const scoped_refptr<ChildStatusCollectorState>& state) { + return state->FetchAndroidStatus(android_status_fetcher_); +} + +void ChildStatusCollector::FillChildStatusReportRequest( + scoped_refptr<ChildStatusCollectorState> state) { + em::ChildStatusReportRequest* status = + state->response_params().child_status.get(); + bool anything_reported = false; + + user_manager::UserManager* user_manager = user_manager::UserManager::Get(); + const user_manager::User* const primary_user = user_manager->GetPrimaryUser(); + DCHECK(primary_user != nullptr); + + anything_reported |= FillUserSpecificFields(state, status, primary_user); + + if (report_version_info_) + anything_reported |= GetVersionInfo(status); + + if (report_activity_times_) + anything_reported |= GetActivityTimes(status); + + if (report_boot_mode_) { + base::Optional<std::string> boot_mode = + StatusCollector::GetBootMode(statistics_provider_); + if (boot_mode) { + status->set_boot_mode(*boot_mode); + anything_reported = true; + } + } + + // Wipe value if we didn't actually add any data. + if (!anything_reported) + state->response_params().child_status.reset(); +} + +void ChildStatusCollector::OnSubmittedSuccessfully() { + activity_storage_->TrimActivityPeriods(last_reported_day_, + duration_for_last_reported_day_, + std::numeric_limits<int64_t>::max()); +} + +bool ChildStatusCollector::ShouldReportActivityTimes() const { + return report_activity_times_; +} + +bool ChildStatusCollector::ShouldReportNetworkInterfaces() const { + return false; +} + +bool ChildStatusCollector::ShouldReportUsers() const { + return false; +} + +bool ChildStatusCollector::ShouldReportHardwareStatus() const { + return false; +} + +void ChildStatusCollector::OnOSVersion(const std::string& version) { + os_version_ = version; +} + +} // namespace policy
diff --git a/chrome/browser/chromeos/policy/status_collector/child_status_collector.h b/chrome/browser/chromeos/policy/status_collector/child_status_collector.h new file mode 100644 index 0000000..981735f --- /dev/null +++ b/chrome/browser/chromeos/policy/status_collector/child_status_collector.h
@@ -0,0 +1,191 @@ +// 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_CHROMEOS_POLICY_STATUS_COLLECTOR_CHILD_STATUS_COLLECTOR_H_ +#define CHROME_BROWSER_CHROMEOS_POLICY_STATUS_COLLECTOR_CHILD_STATUS_COLLECTOR_H_ + +#include <stdint.h> + +#include <map> +#include <memory> +#include <string> + +#include "base/callback_forward.h" +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "base/sequenced_task_runner.h" +#include "base/time/time.h" +#include "base/timer/timer.h" +#include "chrome/browser/chromeos/child_accounts/usage_time_state_notifier.h" +#include "chrome/browser/chromeos/policy/status_collector/status_collector.h" +#include "chromeos/dbus/power/power_manager_client.h" +#include "components/policy/proto/device_management_backend.pb.h" +#include "components/session_manager/core/session_manager_observer.h" +#include "ui/base/idle/idle.h" + +namespace chromeos { +namespace system { +class StatisticsProvider; +} +} // namespace chromeos + +namespace user_manager { +class User; +} + +namespace session_manager { +class SessionManager; +} + +class PrefService; + +namespace policy { + +class ActivityStorage; +class ChildStatusCollectorState; + +// Collects and summarizes the status of a child user in a Chrome OS device, +// also collecting some general (and limited) information about the device +// itself (e.g. OS version). Doesn't include anything related to other users on +// the device. +class ChildStatusCollector : public StatusCollector, + public session_manager::SessionManagerObserver, + public chromeos::UsageTimeStateNotifier::Observer, + public chromeos::PowerManagerClient::Observer { + public: + // Passed into asynchronous mojo interface for communicating with Android. + using AndroidStatusReceiver = + base::Callback<void(const std::string&, const std::string&)>; + + // Calls the reporting mojo interface, passing over the AndroidStatusReceiver. + // Returns false if the mojo interface isn't available, in which case no + // asynchronous query is emitted and the android status query fails + // synchronously. The |AndroidStatusReceiver| is not called in this case. + using AndroidStatusFetcher = + base::Callback<bool(const AndroidStatusReceiver&)>; + + // Constructor. Callers can inject their own *Fetcher callbacks, e.g. for unit + // testing. A null callback can be passed for any *Fetcher parameter, to use + // the default implementation. These callbacks are always executed on Blocking + // Pool. Caller is responsible for passing already initialized |pref_service|. + // |activity_day_start| indicates what time does the new day start for + // activity reporting daily data aggregation. It is represented by the + // distance from midnight. + ChildStatusCollector(PrefService* pref_service, + chromeos::system::StatisticsProvider* provider, + const AndroidStatusFetcher& android_status_fetcher, + base::TimeDelta activity_day_start); + ~ChildStatusCollector() override; + + // StatusCollector: + void GetStatusAsync(const StatusCollectorCallback& response) override; + void OnSubmittedSuccessfully() override; + bool ShouldReportActivityTimes() const override; + bool ShouldReportNetworkInterfaces() const override; + bool ShouldReportUsers() const override; + bool ShouldReportHardwareStatus() const override; + + // How often, in seconds, to poll to see if the user is idle. + static const unsigned int kIdlePollIntervalSeconds = 30; + + // Returns the amount of time the child has used so far today. If there is no + // user logged in, it returns 0. + base::TimeDelta GetActiveChildScreenTime(); + + protected: + // session_manager::SessionManagerObserver: + void OnSessionStateChanged() override; + + // chromeos::UsageTimeStateNotifier::Observer: + void OnUsageTimeStateChange( + chromeos::UsageTimeStateNotifier::UsageTimeState state) override; + + // power_manager::PowerManagerClient::Observer: + void ScreenIdleStateChanged( + const power_manager::ScreenIdleState& state) override; + + // power_manager::PowerManagerClient::Observer: + void SuspendImminent(power_manager::SuspendImminent::Reason reason) override; + + // power_manager::PowerManagerClient::Observer: + void SuspendDone(const base::TimeDelta& sleep_duration) override; + + // Updates the child's active time. + void UpdateChildUsageTime(); + + private: + // Callbacks from chromeos::VersionLoader. + void OnOSVersion(const std::string& version); + + // Fetches all child data that is necessary to fill ChildStatusReportRequest. + void FillChildStatusReportRequest( + scoped_refptr<ChildStatusCollectorState> state); + + // Fetches user data related to the particular child user that is in the + // session (i.e. it is not device data). + bool FillUserSpecificFields( + scoped_refptr<ChildStatusCollectorState> state, + enterprise_management::ChildStatusReportRequest* status, + const user_manager::User* user); + + // Helpers for the various portions of child status report. Return true if + // they actually report any status. Functions that queue async queries take a + // |ChildStatusCollectorState| instance. + bool GetActivityTimes( + enterprise_management::ChildStatusReportRequest* status); + bool GetVersionInfo(enterprise_management::ChildStatusReportRequest* status); + // Queues async queries! + bool GetAndroidStatus(const scoped_refptr<ChildStatusCollectorState>& state); + + // TODO(crbug.com/827386): remove after migration. + void GetDeviceStatus(scoped_refptr<ChildStatusCollectorState> state); + void GetSessionStatus(scoped_refptr<ChildStatusCollectorState> state); + bool GetSessionStatusForUser( + scoped_refptr<ChildStatusCollectorState> state, + enterprise_management::SessionStatusReportRequest* status, + const user_manager::User* user); + bool GetActivityTimes( + enterprise_management::DeviceStatusReportRequest* status); + bool GetVersionInfo(enterprise_management::DeviceStatusReportRequest* status); + // END. + + // Update the cached values of the reporting settings. + void UpdateReportingSettings(); + + // Mainly used to store activity periods for reporting. Not owned. + PrefService* const pref_service_; + + // The last time an idle state check was performed. + base::Time last_idle_check_; + + // The last time an active state check was performed. + base::Time last_active_check_; + + // Whether the last state of the device was active. This is used for child + // accounts only. Active is defined as having the screen turned on. + bool last_state_active_ = true; + + // The maximum key that went into the last report generated by + // GetStatusAsync(), and the duration for it. This is used to trim + // the stored data in OnSubmittedSuccessfully(). Trimming is delayed so + // unsuccessful uploads don't result in dropped data. + int64_t last_reported_day_ = 0; + int duration_for_last_reported_day_ = 0; + + base::RepeatingTimer update_child_usage_timer_; + + std::string os_version_; + + AndroidStatusFetcher android_status_fetcher_; + + base::WeakPtrFactory<ChildStatusCollector> weak_factory_{this}; + + DISALLOW_COPY_AND_ASSIGN(ChildStatusCollector); +}; + +} // namespace policy + +#endif // CHROME_BROWSER_CHROMEOS_POLICY_STATUS_COLLECTOR_CHILD_STATUS_COLLECTOR_H_
diff --git a/chrome/browser/chromeos/policy/status_collector/child_status_collector_browsertest.cc b/chrome/browser/chromeos/policy/status_collector/child_status_collector_browsertest.cc new file mode 100644 index 0000000..2e81c3a --- /dev/null +++ b/chrome/browser/chromeos/policy/status_collector/child_status_collector_browsertest.cc
@@ -0,0 +1,894 @@ +// 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 <stddef.h> +#include <stdint.h> + +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#include "base/bind.h" +#include "base/environment.h" +#include "base/memory/ptr_util.h" +#include "base/run_loop.h" +#include "base/strings/stringprintf.h" +#include "base/strings/utf_string_conversions.h" +#include "base/system/sys_info.h" +#include "base/test/scoped_feature_list.h" +#include "base/test/scoped_path_override.h" +#include "base/threading/thread_task_runner_handle.h" +#include "chrome/browser/chrome_content_browser_client.h" +#include "chrome/browser/chromeos/login/users/mock_user_manager.h" +#include "chrome/browser/chromeos/ownership/fake_owner_settings_service.h" +#include "chrome/browser/chromeos/policy/status_collector/child_status_collector.h" +#include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "chrome/browser/chromeos/settings/scoped_testing_cros_settings.h" +#include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h" +#include "chrome/common/chrome_content_client.h" +#include "chrome/common/chrome_features.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/common/pref_names.h" +#include "chrome/test/base/chrome_unit_test_suite.h" +#include "chrome/test/base/testing_browser_process.h" +#include "chrome/test/base/testing_profile_manager.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/fake_update_engine_client.h" +#include "chromeos/dbus/power/fake_power_manager_client.h" +#include "chromeos/dbus/power_manager/idle.pb.h" +#include "chromeos/login/login_state/login_state.h" +#include "chromeos/settings/cros_settings_names.h" +#include "chromeos/settings/timezone_settings.h" +#include "chromeos/system/fake_statistics_provider.h" +#include "components/account_id/account_id.h" +#include "components/policy/proto/device_management_backend.pb.h" +#include "components/prefs/pref_service.h" +#include "components/prefs/testing_pref_service.h" +#include "components/session_manager/core/session_manager.h" +#include "components/user_manager/scoped_user_manager.h" +#include "components/user_manager/user_type.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "content/public/test/test_utils.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { +namespace em = enterprise_management; + +using ::base::Time; +using ::base::TimeDelta; +using ::testing::Return; +using ::testing::ReturnRef; + +// Time delta representing midnight 00:00. +constexpr TimeDelta kMidnight; + +// Time delta representing 06:00AM. +constexpr TimeDelta kSixAm = TimeDelta::FromHours(6); + +// Time delta representing 1 hour time interval. +constexpr TimeDelta kHour = TimeDelta::FromHours(1); + +constexpr int64_t kMillisecondsPerDay = Time::kMicrosecondsPerDay / 1000; +const char kArcStatus[] = R"( +{ + "applications":[ + { + "packageName":"com.android.providers.telephony", + "versionName":"6.0.1", + "permissions":[ "android.permission.INTERNET" ] + } + ], + "userEmail":"xxx@google.com" +})"; +const char kDroidGuardInfo[] = "{\"droid_guard_info\":42}"; + +const char kFakeDmToken[] = "kFakeDmToken"; + +class TestingChildStatusCollector : public policy::ChildStatusCollector { + public: + TestingChildStatusCollector( + PrefService* pref_service, + chromeos::system::StatisticsProvider* provider, + const policy::ChildStatusCollector::AndroidStatusFetcher& + android_status_fetcher, + TimeDelta activity_day_start) + : policy::ChildStatusCollector(pref_service, + provider, + android_status_fetcher, + activity_day_start) { + // Set the baseline time to a fixed value (1 hour after day start) to + // prevent test flakiness due to a single activity period spanning two days. + // TODO(crbug.com/827386): migrate to use SimpleTestClock. + SetBaselineTime(Time::Now().LocalMidnight() + activity_day_start + kHour); + } + + void UpdateUsageTime() { UpdateChildUsageTime(); } + + // Reset the baseline time. + void SetBaselineTime(Time time) { + baseline_time_ = time; + baseline_offset_periods_ = 0; + } + + std::string GetDMTokenForProfile(Profile* profile) const override { + return kFakeDmToken; + } + + protected: + // Each time this is called, returns a time that is a fixed increment + // later than the previous time. + Time GetCurrentTime() override { + int poll_interval = policy::ChildStatusCollector::kIdlePollIntervalSeconds; + return baseline_time_ + + TimeDelta::FromSeconds(poll_interval * baseline_offset_periods_++); + } + + private: + // Baseline time for the fake times returned from GetCurrentTime(). + Time baseline_time_; + + // The number of simulated periods since the baseline time. + int baseline_offset_periods_; +}; + +// Return the total number of active milliseconds contained in a device +// status report. +int64_t GetActiveMilliseconds(const em::DeviceStatusReportRequest& status) { + int64_t active_milliseconds = 0; + for (int i = 0; i < status.active_periods_size(); i++) { + active_milliseconds += status.active_periods(i).active_duration(); + } + return active_milliseconds; +} + +// Overloads |GetActiveMilliseconds| for child status report. +int64_t GetActiveMilliseconds(const em::ChildStatusReportRequest& status) { + int64_t active_milliseconds = 0; + for (int i = 0; i < status.screen_time_span_size(); i++) { + active_milliseconds += status.screen_time_span(i).active_duration_ms(); + } + return active_milliseconds; +} + +void CallAndroidStatusReceiver( + const policy::ChildStatusCollector::AndroidStatusReceiver& receiver, + const std::string& status, + const std::string& droid_guard_info) { + receiver.Run(status, droid_guard_info); +} + +bool GetEmptyAndroidStatus( + const policy::ChildStatusCollector::AndroidStatusReceiver& receiver) { + // Post it to the thread because this call is expected to be asynchronous. + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(&CallAndroidStatusReceiver, receiver, "", "")); + return true; +} + +bool GetFakeAndroidStatus( + const std::string& status, + const std::string& droid_guard_info, + const policy::ChildStatusCollector::AndroidStatusReceiver& receiver) { + // Post it to the thread because this call is expected to be asynchronous. + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(&CallAndroidStatusReceiver, receiver, status, + droid_guard_info)); + return true; +} + +} // namespace + +namespace policy { + +// Though it is a unit test, this test is linked with browser_tests so that it +// runs in a separate process. The intention is to avoid overriding the timezone +// environment variable for other tests. +class BaseChildStatusCollectorTest : public testing::Test { + public: + BaseChildStatusCollectorTest() + : user_manager_(new chromeos::MockUserManager()), + user_manager_enabler_(base::WrapUnique(user_manager_)), + user_data_dir_override_(chrome::DIR_USER_DATA), + update_engine_client_(new chromeos::FakeUpdateEngineClient) { + scoped_stub_install_attributes_.Get()->SetCloudManaged("managed.com", + "device_id"); + EXPECT_CALL(*user_manager_, Shutdown()).Times(1); + + // Although this is really a unit test which runs in the browser_tests + // binary, it doesn't get the unit setup which normally happens in the unit + // test binary. + ChromeUnitTestSuite::InitializeProviders(); + ChromeUnitTestSuite::InitializeResourceBundle(); + + content::SetContentClient(&content_client_); + content::SetBrowserClientForTesting(&browser_content_client_); + + // Run this test with a well-known timezone so that Time::LocalMidnight() + // returns the same values on all machines. + std::unique_ptr<base::Environment> env(base::Environment::Create()); + env->SetVar("TZ", "UTC"); + + TestingChildStatusCollector::RegisterProfilePrefs( + profile_pref_service_.registry()); + + owner_settings_service_.set_ignore_profile_creation_notification(true); + + TestingBrowserProcess::GetGlobal()->SetLocalState(&local_state_); + + // Use FakeUpdateEngineClient. + std::unique_ptr<chromeos::DBusThreadManagerSetter> dbus_setter = + chromeos::DBusThreadManager::GetSetterForTesting(); + dbus_setter->SetUpdateEngineClient( + base::WrapUnique<chromeos::UpdateEngineClient>(update_engine_client_)); + + chromeos::PowerManagerClient::InitializeFake(); + chromeos::LoginState::Initialize(); + } + + ~BaseChildStatusCollectorTest() override { + chromeos::LoginState::Shutdown(); + chromeos::PowerManagerClient::Shutdown(); + TestingBrowserProcess::GetGlobal()->SetLocalState(nullptr); + + // Finish pending tasks. + content::RunAllTasksUntilIdle(); + } + + void SetUp() override { + RestartStatusCollector(base::BindRepeating(&GetEmptyAndroidStatus)); + + // Disable network interface reporting since it requires additional setup. + scoped_testing_cros_settings_.device_settings()->SetBoolean( + chromeos::kReportDeviceNetworkInterfaces, false); + } + + void TearDown() override { status_collector_.reset(); } + + protected: + // States tracked to calculate a child's active time. + enum class DeviceStateTransitions { + kEnterIdleState, + kLeaveIdleState, + kEnterSleep, + kLeaveSleep, + kEnterSessionActive, + kLeaveSessionActive, + kPeriodicCheckTriggered + }; + + void SimulateStateChanges(DeviceStateTransitions* states, int len) { + for (int i = 0; i < len; i++) { + switch (states[i]) { + case DeviceStateTransitions::kEnterIdleState: { + power_manager::ScreenIdleState state; + state.set_off(true); + chromeos::FakePowerManagerClient::Get()->SendScreenIdleStateChanged( + state); + } break; + case DeviceStateTransitions::kLeaveIdleState: { + power_manager::ScreenIdleState state; + state.set_off(false); + chromeos::FakePowerManagerClient::Get()->SendScreenIdleStateChanged( + state); + } break; + case DeviceStateTransitions::kEnterSleep: + chromeos::FakePowerManagerClient::Get()->SendSuspendImminent( + power_manager::SuspendImminent_Reason_LID_CLOSED); + break; + case DeviceStateTransitions::kLeaveSleep: + chromeos::FakePowerManagerClient::Get()->SendSuspendDone( + base::TimeDelta::FromSeconds( + policy::ChildStatusCollector::kIdlePollIntervalSeconds)); + break; + case DeviceStateTransitions::kEnterSessionActive: + session_manager::SessionManager::Get()->SetSessionState( + session_manager::SessionState::ACTIVE); + break; + case DeviceStateTransitions::kLeaveSessionActive: + session_manager::SessionManager::Get()->SetSessionState( + session_manager::SessionState::LOCKED); + break; + case DeviceStateTransitions::kPeriodicCheckTriggered: + status_collector_->UpdateUsageTime(); + break; + } + } + } + + virtual void RestartStatusCollector( + const policy::ChildStatusCollector::AndroidStatusFetcher& + android_status_fetcher, + const TimeDelta activity_day_start = kMidnight) { + status_collector_ = std::make_unique<TestingChildStatusCollector>( + &local_state_, &fake_statistics_provider_, android_status_fetcher, + activity_day_start); + } + + void GetStatus() { + device_status_.Clear(); + session_status_.Clear(); + run_loop_.reset(new base::RunLoop()); + status_collector_->GetStatusAsync( + base::BindRepeating(&BaseChildStatusCollectorTest::OnStatusReceived, + base::Unretained(this))); + run_loop_->Run(); + run_loop_.reset(); + } + + void OnStatusReceived(StatusCollectorParams callback_params) { + if (callback_params.device_status) + device_status_ = *callback_params.device_status; + if (callback_params.session_status) + session_status_ = *callback_params.session_status; + if (callback_params.child_status) + child_status_ = *callback_params.child_status; + EXPECT_TRUE(run_loop_); + run_loop_->Quit(); + } + + void MockUserWithTypeAndAffiliation(const AccountId& account_id, + user_manager::UserType user_type, + bool is_affiliated) { + user_manager_->AddUserWithAffiliationAndType(account_id, is_affiliated, + user_type); + // The user just added will be the active user because there's only one + // user. + user_manager::User* user = user_manager_->GetActiveUser(); + + // Build a profile with profile name=account e-mail because our testing + // version of GetDMTokenForProfile returns the profile name. + TestingProfile::Builder profile_builder; + profile_builder.SetProfileName(account_id.GetUserEmail()); + testing_profile_ = profile_builder.Build(); + chromeos::ProfileHelper::Get()->SetUserToProfileMappingForTesting( + user, testing_profile_.get()); + + EXPECT_CALL(*user_manager_, IsLoggedInAsKioskApp()) + .WillRepeatedly(Return(false)); + } + + void MockRegularUserWithAffiliation(const AccountId& account_id, + bool is_affiliated) { + MockUserWithTypeAndAffiliation(account_id, user_manager::USER_TYPE_REGULAR, + is_affiliated); + } + + void MockChildUser(const AccountId& account_id) { + MockUserWithTypeAndAffiliation(account_id, user_manager::USER_TYPE_CHILD, + false); + EXPECT_CALL(*user_manager_, IsLoggedInAsChildUser()) + .WillRepeatedly(Return(true)); + } + + void MockPlatformVersion(const std::string& platform_version) { + const std::string lsb_release = base::StringPrintf( + "CHROMEOS_RELEASE_VERSION=%s", platform_version.c_str()); + base::SysInfo::SetChromeOSVersionInfoForTest(lsb_release, + base::Time::Now()); + } + + // Convenience method. + int64_t ActivePeriodMilliseconds() { + return policy::ChildStatusCollector::kIdlePollIntervalSeconds * 1000; + } + + // Since this is a unit test running in browser_tests we must do additional + // unit test setup and make a TestingBrowserProcess. Must be first member. + TestingBrowserProcessInitializer initializer_; + content::TestBrowserThreadBundle test_browser_thread_bundle_; + + ChromeContentClient content_client_; + ChromeContentBrowserClient browser_content_client_; + chromeos::system::ScopedFakeStatisticsProvider fake_statistics_provider_; + chromeos::ScopedStubInstallAttributes scoped_stub_install_attributes_; + chromeos::ScopedTestingCrosSettings scoped_testing_cros_settings_; + chromeos::FakeOwnerSettingsService owner_settings_service_{ + scoped_testing_cros_settings_.device_settings(), nullptr}; + std::unique_ptr<TestingProfile> testing_profile_; + chromeos::MockUserManager* const user_manager_; + user_manager::ScopedUserManager user_manager_enabler_; + em::DeviceStatusReportRequest device_status_; + em::SessionStatusReportRequest session_status_; + em::ChildStatusReportRequest child_status_; + TestingPrefServiceSimple local_state_; + TestingPrefServiceSimple profile_pref_service_; + std::unique_ptr<TestingChildStatusCollector> status_collector_; + base::ScopedPathOverride user_data_dir_override_; + chromeos::FakeUpdateEngineClient* const update_engine_client_; + std::unique_ptr<base::RunLoop> run_loop_; + + // This property is required to instantiate the session manager, a singleton + // which is used by the device status collector. + session_manager::SessionManager session_manager_; + + private: + DISALLOW_COPY_AND_ASSIGN(BaseChildStatusCollectorTest); +}; + +// Tests collecting device status for registered consumer device. +class ChildStatusCollectorTimeLimitDisabledTest + : public BaseChildStatusCollectorTest { + public: + ChildStatusCollectorTimeLimitDisabledTest() { + user_account_id_ = AccountId::FromUserEmail("user0@gmail.com"); + MockChildUser(user_account_id_); + scoped_feature_list_.InitAndDisableFeature(features::kUsageTimeLimitPolicy); + } + + ~ChildStatusCollectorTimeLimitDisabledTest() override = default; + + protected: + void RestartStatusCollector( + const policy::ChildStatusCollector::AndroidStatusFetcher& + android_status_fetcher, + const TimeDelta activity_day_start = kMidnight) override { + status_collector_ = std::make_unique<TestingChildStatusCollector>( + &profile_pref_service_, &fake_statistics_provider_, + android_status_fetcher, activity_day_start); + } + + void ExpectChildScreenTimeMilliseconds(int64_t duration) { + profile_pref_service_.CommitPendingWrite( + base::OnceClosure(), + base::BindOnce( + [](int64_t duration, + TestingPrefServiceSimple* profile_pref_service_) { + EXPECT_EQ(duration, profile_pref_service_->GetInteger( + prefs::kChildScreenTimeMilliseconds)); + }, + duration, &profile_pref_service_)); + } + + void ExpectLastChildScreenTimeReset(Time time) { + profile_pref_service_.CommitPendingWrite( + base::OnceClosure(), + base::BindOnce( + [](Time time, TestingPrefServiceSimple* profile_pref_service_) { + EXPECT_EQ(time, profile_pref_service_->GetTime( + prefs::kLastChildScreenTimeReset)); + }, + time, &profile_pref_service_)); + } + + AccountId user_account_id_; + base::test::ScopedFeatureList scoped_feature_list_; +}; + +TEST_F(ChildStatusCollectorTimeLimitDisabledTest, ReportingBootMode) { + fake_statistics_provider_.SetMachineStatistic( + chromeos::system::kDevSwitchBootKey, + chromeos::system::kDevSwitchBootValueVerified); + + GetStatus(); + + // TODO(crbug.com/827386): remove after migration. + EXPECT_TRUE(device_status_.has_boot_mode()); + EXPECT_EQ("Verified", device_status_.boot_mode()); + // END. + + EXPECT_TRUE(child_status_.has_boot_mode()); + EXPECT_EQ("Verified", child_status_.boot_mode()); +} + +// TODO(crbug.com/827386): remove after migration. +TEST_F(ChildStatusCollectorTimeLimitDisabledTest, + NotReportingWriteProtectSwitch) { + fake_statistics_provider_.SetMachineStatistic( + chromeos::system::kFirmwareWriteProtectBootKey, + chromeos::system::kFirmwareWriteProtectBootValueOn); + + GetStatus(); + + EXPECT_FALSE(device_status_.has_write_protect_switch()); +} +// END. + +TEST_F(ChildStatusCollectorTimeLimitDisabledTest, ReportingArcStatus) { + RestartStatusCollector( + base::BindRepeating(&GetFakeAndroidStatus, kArcStatus, kDroidGuardInfo)); + testing_profile_->GetPrefs()->SetBoolean(prefs::kReportArcStatusEnabled, + true); + + GetStatus(); + + // TODO(crbug.com/827386): remove after migration. + EXPECT_EQ(kArcStatus, session_status_.android_status().status_payload()); + EXPECT_EQ(kDroidGuardInfo, + session_status_.android_status().droid_guard_info()); + EXPECT_EQ(kFakeDmToken, session_status_.user_dm_token()); + // END. + + EXPECT_EQ(kArcStatus, child_status_.android_status().status_payload()); + EXPECT_EQ(kDroidGuardInfo, child_status_.android_status().droid_guard_info()); + EXPECT_EQ(kFakeDmToken, child_status_.user_dm_token()); +} + +TEST_F(ChildStatusCollectorTimeLimitDisabledTest, ReportingPartialVersionInfo) { + GetStatus(); + + // TODO(crbug.com/827386): remove after migration. + // Should only report OS version. + EXPECT_TRUE(device_status_.has_os_version()); + EXPECT_FALSE(device_status_.has_browser_version()); + EXPECT_FALSE(device_status_.has_channel()); + EXPECT_FALSE(device_status_.has_firmware_version()); + EXPECT_FALSE(device_status_.has_tpm_version_info()); + // END. + + EXPECT_TRUE(child_status_.has_os_version()); +} + +// TODO(crbug.com/827386): remove after migration. +TEST_F(ChildStatusCollectorTimeLimitDisabledTest, NotReportingVolumeInfo) { + RestartStatusCollector(base::BindRepeating(&GetEmptyAndroidStatus)); + content::RunAllTasksUntilIdle(); + + GetStatus(); + + EXPECT_EQ(0, device_status_.volume_infos_size()); +} + +TEST_F(ChildStatusCollectorTimeLimitDisabledTest, NotReportingUsers) { + const AccountId account_id0(AccountId::FromUserEmail("user0@gmail.com")); + const AccountId account_id1(AccountId::FromUserEmail("user1@gmail.com")); + user_manager_->AddUserWithAffiliationAndType(account_id0, true, + user_manager::USER_TYPE_REGULAR); + user_manager_->AddUserWithAffiliationAndType(account_id1, true, + user_manager::USER_TYPE_CHILD); + + GetStatus(); + + EXPECT_EQ(0, device_status_.users_size()); +} + +TEST_F(ChildStatusCollectorTimeLimitDisabledTest, NotReportingOSUpdateStatus) { + MockPlatformVersion("1234.0.0"); + + GetStatus(); + + EXPECT_FALSE(device_status_.has_os_update_status()); +} + +TEST_F(ChildStatusCollectorTimeLimitDisabledTest, + NotReportingDeviceHardwareStatus) { + EXPECT_FALSE(device_status_.has_sound_volume()); + EXPECT_EQ(0, device_status_.cpu_utilization_pct_samples().size()); + EXPECT_EQ(0, device_status_.cpu_temp_infos_size()); + EXPECT_EQ(0, device_status_.system_ram_free_samples().size()); + EXPECT_FALSE(device_status_.has_system_ram_total()); + EXPECT_FALSE(device_status_.has_tpm_status_info()); +} +// END. + +TEST_F(ChildStatusCollectorTimeLimitDisabledTest, TimeZoneReporting) { + const std::string timezone = + base::UTF16ToUTF8(chromeos::system::TimezoneSettings::GetInstance() + ->GetCurrentTimezoneID()); + + GetStatus(); + + // TODO(crbug.com/827386): remove after migration. + EXPECT_TRUE(session_status_.has_time_zone()); + EXPECT_EQ(timezone, session_status_.time_zone()); + // END. + + EXPECT_TRUE(child_status_.has_time_zone()); + EXPECT_EQ(timezone, child_status_.time_zone()); +} + +TEST_F(ChildStatusCollectorTimeLimitDisabledTest, ActivityTimesFeatureDisable) { + scoped_testing_cros_settings_.device_settings()->SetBoolean( + chromeos::kReportDeviceActivityTimes, true); + scoped_testing_cros_settings_.device_settings()->SetBoolean( + chromeos::kReportDeviceUsers, true); + DeviceStateTransitions test_states[] = { + DeviceStateTransitions::kEnterSessionActive, + DeviceStateTransitions::kPeriodicCheckTriggered, + DeviceStateTransitions::kPeriodicCheckTriggered, + DeviceStateTransitions::kLeaveSessionActive, + DeviceStateTransitions::kPeriodicCheckTriggered, // Check while inactive + DeviceStateTransitions::kEnterSessionActive, + DeviceStateTransitions::kPeriodicCheckTriggered, + DeviceStateTransitions::kLeaveSessionActive}; + SimulateStateChanges(test_states, + sizeof(test_states) / sizeof(DeviceStateTransitions)); + + GetStatus(); + + // TODO(crbug.com/827386): remove after migration. + EXPECT_EQ(0, device_status_.active_periods_size()); + // END. + + EXPECT_EQ(0, child_status_.screen_time_span_size()); +} + +// Tests collecting device status for registered consumer device when time +// limit feature is enabled. +class ChildStatusCollectorTimeLimitEnabledTest + : public ChildStatusCollectorTimeLimitDisabledTest { + public: + ChildStatusCollectorTimeLimitEnabledTest() { + scoped_feature_list_.InitAndEnableFeature(features::kUsageTimeLimitPolicy); + } + ~ChildStatusCollectorTimeLimitEnabledTest() override = default; + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +TEST_F(ChildStatusCollectorTimeLimitEnabledTest, + ReportingActivityTimesSessionTransistions) { + DeviceStateTransitions test_states[] = { + DeviceStateTransitions::kEnterSessionActive, + DeviceStateTransitions::kPeriodicCheckTriggered, + DeviceStateTransitions::kPeriodicCheckTriggered, + DeviceStateTransitions::kLeaveSessionActive, + DeviceStateTransitions::kPeriodicCheckTriggered, // Check while inactive + DeviceStateTransitions::kEnterSessionActive, + DeviceStateTransitions::kPeriodicCheckTriggered, + DeviceStateTransitions::kLeaveSessionActive}; + SimulateStateChanges(test_states, + sizeof(test_states) / sizeof(DeviceStateTransitions)); + + GetStatus(); + + // TODO(crbug.com/827386): remove after migration. + ASSERT_EQ(1, device_status_.active_periods_size()); + EXPECT_EQ(5 * ActivePeriodMilliseconds(), + GetActiveMilliseconds(device_status_)); + EXPECT_EQ("", // No email should be saved for child account. + device_status_.active_periods(0).user_email()); + // END. + + ASSERT_EQ(1, child_status_.screen_time_span_size()); + EXPECT_EQ(5 * ActivePeriodMilliseconds(), + GetActiveMilliseconds(child_status_)); + ExpectChildScreenTimeMilliseconds(5 * ActivePeriodMilliseconds()); +} + +TEST_F(ChildStatusCollectorTimeLimitEnabledTest, + ReportingActivityTimesSleepTransistions) { + DeviceStateTransitions test_states[] = { + DeviceStateTransitions::kEnterSessionActive, + DeviceStateTransitions::kPeriodicCheckTriggered, + DeviceStateTransitions::kEnterSleep, + DeviceStateTransitions::kPeriodicCheckTriggered, // Check while inactive + DeviceStateTransitions::kLeaveSleep, + DeviceStateTransitions::kPeriodicCheckTriggered, + DeviceStateTransitions::kLeaveSessionActive, + DeviceStateTransitions::kEnterSleep, + DeviceStateTransitions::kLeaveSleep, + DeviceStateTransitions::kPeriodicCheckTriggered}; + SimulateStateChanges(test_states, + sizeof(test_states) / sizeof(DeviceStateTransitions)); + + GetStatus(); + + // TODO(crbug.com/827386): remove after migration. + ASSERT_EQ(1, device_status_.active_periods_size()); + EXPECT_EQ(4 * ActivePeriodMilliseconds(), + GetActiveMilliseconds(device_status_)); + EXPECT_EQ("", // No email should be saved for child account. + device_status_.active_periods(0).user_email()); + // END. + + ASSERT_EQ(1, child_status_.screen_time_span_size()); + EXPECT_EQ(4 * ActivePeriodMilliseconds(), + GetActiveMilliseconds(child_status_)); + ExpectChildScreenTimeMilliseconds(4 * ActivePeriodMilliseconds()); +} + +TEST_F(ChildStatusCollectorTimeLimitEnabledTest, + ReportingActivityTimesIdleTransitions) { + DeviceStateTransitions test_states[] = { + DeviceStateTransitions::kEnterSessionActive, + DeviceStateTransitions::kPeriodicCheckTriggered, + DeviceStateTransitions::kPeriodicCheckTriggered, + DeviceStateTransitions::kEnterIdleState, + DeviceStateTransitions::kPeriodicCheckTriggered, // Check while inactive + DeviceStateTransitions::kPeriodicCheckTriggered, // Check while inactive + DeviceStateTransitions::kLeaveIdleState, + DeviceStateTransitions::kPeriodicCheckTriggered, + DeviceStateTransitions::kLeaveSessionActive}; + SimulateStateChanges(test_states, + sizeof(test_states) / sizeof(DeviceStateTransitions)); + + GetStatus(); + + // TODO(crbug.com/827386): remove after migration. + ASSERT_EQ(1, device_status_.active_periods_size()); + EXPECT_EQ(5 * ActivePeriodMilliseconds(), + GetActiveMilliseconds(device_status_)); + EXPECT_EQ("", // No email should be saved for child account. + device_status_.active_periods(0).user_email()); + // END. + + ASSERT_EQ(1, child_status_.screen_time_span_size()); + EXPECT_EQ(5 * ActivePeriodMilliseconds(), + GetActiveMilliseconds(child_status_)); + ExpectChildScreenTimeMilliseconds(5 * ActivePeriodMilliseconds()); +} + +TEST_F(ChildStatusCollectorTimeLimitEnabledTest, ActivityKeptInPref) { + EXPECT_TRUE( + profile_pref_service_.GetDictionary(prefs::kUserActivityTimes)->empty()); + base::Time initial_time = base::Time::Now() + kHour; + status_collector_->SetBaselineTime(initial_time); + + DeviceStateTransitions test_states[] = { + DeviceStateTransitions::kEnterSessionActive, + DeviceStateTransitions::kPeriodicCheckTriggered, + DeviceStateTransitions::kLeaveSessionActive, + DeviceStateTransitions::kEnterSessionActive, + DeviceStateTransitions::kPeriodicCheckTriggered, + DeviceStateTransitions::kPeriodicCheckTriggered, + DeviceStateTransitions::kLeaveSessionActive, + DeviceStateTransitions::kPeriodicCheckTriggered, // Check while inactive + DeviceStateTransitions::kEnterSessionActive, + DeviceStateTransitions::kLeaveSessionActive}; + SimulateStateChanges(test_states, + sizeof(test_states) / sizeof(DeviceStateTransitions)); + EXPECT_FALSE( + profile_pref_service_.GetDictionary(prefs::kUserActivityTimes)->empty()); + + // Process the list a second time after restarting the collector. It should be + // able to count the active periods found by the original collector, because + // the results are stored in a pref. + RestartStatusCollector(base::BindRepeating(&GetEmptyAndroidStatus)); + status_collector_->SetBaselineTime(initial_time); + SimulateStateChanges(test_states, + sizeof(test_states) / sizeof(DeviceStateTransitions)); + + GetStatus(); + + // TODO(crbug.com/827386): remove after migration. + EXPECT_EQ(12 * ActivePeriodMilliseconds(), + GetActiveMilliseconds(device_status_)); + // END. + + ExpectChildScreenTimeMilliseconds(12 * ActivePeriodMilliseconds()); + EXPECT_EQ(12 * ActivePeriodMilliseconds(), + GetActiveMilliseconds(child_status_)); +} + +TEST_F(ChildStatusCollectorTimeLimitEnabledTest, + ActivityNotWrittenToLocalState) { + DeviceStateTransitions test_states[] = { + DeviceStateTransitions::kEnterSessionActive, + DeviceStateTransitions::kPeriodicCheckTriggered, + DeviceStateTransitions::kLeaveSessionActive, + DeviceStateTransitions::kPeriodicCheckTriggered, // Check while inactive + DeviceStateTransitions::kPeriodicCheckTriggered, // Check while inactive + DeviceStateTransitions::kEnterSessionActive, + DeviceStateTransitions::kLeaveSessionActive, + DeviceStateTransitions::kPeriodicCheckTriggered, // Check while inactive + DeviceStateTransitions::kEnterSessionActive, + DeviceStateTransitions::kPeriodicCheckTriggered, + DeviceStateTransitions::kLeaveSessionActive}; + SimulateStateChanges(test_states, + sizeof(test_states) / sizeof(DeviceStateTransitions)); + GetStatus(); + + // TODO(crbug.com/827386): remove after migration. + EXPECT_EQ(1, device_status_.active_periods_size()); + EXPECT_EQ(5 * ActivePeriodMilliseconds(), + GetActiveMilliseconds(device_status_)); + // END. + + EXPECT_EQ(1, child_status_.screen_time_span_size()); + EXPECT_EQ(5 * ActivePeriodMilliseconds(), + GetActiveMilliseconds(child_status_)); + ExpectChildScreenTimeMilliseconds(5 * ActivePeriodMilliseconds()); + // Nothing should be written to local state, because it is only used for + // enterprise reporting. +} + +TEST_F(ChildStatusCollectorTimeLimitEnabledTest, BeforeDayStart) { + RestartStatusCollector(base::BindRepeating(&GetEmptyAndroidStatus), kSixAm); + // 04:00 AM + Time initial_time = Time::Now().LocalMidnight() + TimeDelta::FromHours(4); + status_collector_->SetBaselineTime(initial_time); + EXPECT_TRUE( + profile_pref_service_.GetDictionary(prefs::kUserActivityTimes)->empty()); + + DeviceStateTransitions test_states[] = { + DeviceStateTransitions::kEnterSessionActive, + DeviceStateTransitions::kLeaveSessionActive, + DeviceStateTransitions::kEnterSessionActive, + DeviceStateTransitions::kPeriodicCheckTriggered, + DeviceStateTransitions::kPeriodicCheckTriggered, + DeviceStateTransitions::kLeaveSessionActive}; + SimulateStateChanges(test_states, + sizeof(test_states) / sizeof(DeviceStateTransitions)); + GetStatus(); + // 4 is the number of states yielding an active period with duration of + // ActivePeriodMilliseconds + // TODO(crbug.com/827386): remove after migration. + EXPECT_EQ(4 * ActivePeriodMilliseconds(), + GetActiveMilliseconds(device_status_)); + // END. + EXPECT_EQ(4 * ActivePeriodMilliseconds(), + GetActiveMilliseconds(child_status_)); + ExpectChildScreenTimeMilliseconds(4 * ActivePeriodMilliseconds()); + ExpectLastChildScreenTimeReset(initial_time); +} + +TEST_F(ChildStatusCollectorTimeLimitEnabledTest, ActivityCrossingMidnight) { + DeviceStateTransitions test_states[] = { + DeviceStateTransitions::kEnterSessionActive, + DeviceStateTransitions::kLeaveSessionActive}; + + // Set the baseline time to 15 seconds before midnight, so the activity is + // split between two days. + status_collector_->SetBaselineTime(Time::Now().LocalMidnight() - + TimeDelta::FromSeconds(15)); + SimulateStateChanges(test_states, + sizeof(test_states) / sizeof(DeviceStateTransitions)); + GetStatus(); + + // TODO(crbug.com/827386): remove after migration. + ASSERT_EQ(2, device_status_.active_periods_size()); + + em::ActiveTimePeriod period0 = device_status_.active_periods(0); + em::ActiveTimePeriod period1 = device_status_.active_periods(1); + EXPECT_EQ(ActivePeriodMilliseconds() - 15000, period0.active_duration()); + EXPECT_EQ(15000, period1.active_duration()); + + em::TimePeriod time_period0 = period0.time_period(); + em::TimePeriod time_period1 = period1.time_period(); + + EXPECT_EQ(time_period0.end_timestamp(), time_period1.start_timestamp()); + + // Ensure that the start and end times for the period are a day apart. + EXPECT_EQ(time_period0.end_timestamp() - time_period0.start_timestamp(), + kMillisecondsPerDay); + EXPECT_EQ(time_period1.end_timestamp() - time_period1.start_timestamp(), + kMillisecondsPerDay); + // END. + + ASSERT_EQ(2, child_status_.screen_time_span_size()); + + em::ScreenTimeSpan timespan0 = child_status_.screen_time_span(0); + em::ScreenTimeSpan timespan1 = child_status_.screen_time_span(1); + EXPECT_EQ(ActivePeriodMilliseconds() - 15000, timespan0.active_duration_ms()); + EXPECT_EQ(15000, timespan1.active_duration_ms()); + + em::TimePeriod timespan0period = timespan0.time_period(); + em::TimePeriod timespan1period = timespan1.time_period(); + + EXPECT_EQ(timespan0period.end_timestamp(), timespan1period.start_timestamp()); + + // Ensure that the start and end times for the period are a day apart. + EXPECT_EQ(timespan0period.end_timestamp() - timespan0period.start_timestamp(), + kMillisecondsPerDay); + EXPECT_EQ(timespan1period.end_timestamp() - timespan1period.start_timestamp(), + kMillisecondsPerDay); + ExpectChildScreenTimeMilliseconds(0.5 * ActivePeriodMilliseconds()); +} + +TEST_F(ChildStatusCollectorTimeLimitEnabledTest, ClockChanged) { + DeviceStateTransitions test_states[1] = { + DeviceStateTransitions::kEnterSessionActive}; + base::Time initial_time = + Time::Now().LocalMidnight() + base::TimeDelta::FromHours(1); + status_collector_->SetBaselineTime(initial_time); + SimulateStateChanges(test_states, 1); + + // Simulate clock change. + status_collector_->SetBaselineTime(initial_time - TimeDelta::FromMinutes(30)); + test_states[0] = DeviceStateTransitions::kLeaveSessionActive; + SimulateStateChanges(test_states, 1); + + GetStatus(); + + // TODO(crbug.com/827386): remove after migration. + ASSERT_EQ(1, device_status_.active_periods_size()); + // END. + ASSERT_EQ(1, child_status_.screen_time_span_size()); + ExpectChildScreenTimeMilliseconds(ActivePeriodMilliseconds()); +} + +} // namespace policy
diff --git a/chrome/browser/chromeos/policy/status_collector/device_status_collector.cc b/chrome/browser/chromeos/policy/status_collector/device_status_collector.cc index 9f45514d..d8d1881 100644 --- a/chrome/browser/chromeos/policy/status_collector/device_status_collector.cc +++ b/chrome/browser/chromeos/policy/status_collector/device_status_collector.cc
@@ -46,8 +46,6 @@ #include "chrome/browser/chromeos/policy/device_local_account.h" #include "chrome/browser/chromeos/policy/status_collector/activity_storage.h" #include "chrome/browser/chromeos/policy/status_collector/status_collector_state.h" -#include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h" -#include "chrome/browser/chromeos/policy/user_policy_manager_factory_chromeos.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/policy/profile_policy_connector.h" @@ -645,28 +643,26 @@ const EMMCLifetimeFetcher& emmc_lifetime_fetcher, TimeDelta activity_day_start, bool is_enterprise_reporting) - : max_stored_past_activity_interval_(kMaxStoredPastActivityInterval), - max_stored_future_activity_interval_(kMaxStoredFutureActivityInterval), + : StatusCollector(provider, + chromeos::CrosSettings::Get(), + chromeos::PowerManagerClient::Get(), + session_manager::SessionManager::Get(), + activity_day_start), pref_service_(pref_service), - last_idle_check_(Time()), - last_active_check_(base::Time()), - last_state_active_(true), volume_info_fetcher_(volume_info_fetcher), cpu_statistics_fetcher_(cpu_statistics_fetcher), cpu_temp_fetcher_(cpu_temp_fetcher), android_status_fetcher_(android_status_fetcher), tpm_status_fetcher_(tpm_status_fetcher), emmc_lifetime_fetcher_(emmc_lifetime_fetcher), - statistics_provider_(provider), - cros_settings_(chromeos::CrosSettings::Get()), - power_manager_(chromeos::PowerManagerClient::Get()), - session_manager_(session_manager::SessionManager::Get()), runtime_probe_( chromeos::DBusThreadManager::Get()->GetRuntimeProbeClient()), is_enterprise_reporting_(is_enterprise_reporting), - activity_day_start_(activity_day_start), - task_runner_(nullptr), weak_factory_(this) { + // protected fields of `StatusCollector`. + max_stored_past_activity_interval_ = kMaxStoredPastActivityInterval; + max_stored_future_activity_interval_ = kMaxStoredFutureActivityInterval; + // Get the task runner of the current thread, so we can queue status responses // on this thread. CHECK(base::SequencedTaskRunnerHandle::IsSet()); @@ -793,15 +789,6 @@ registry->RegisterDictionaryPref(prefs::kDeviceActivityTimes); } -// static -void DeviceStatusCollector::RegisterProfilePrefs(PrefRegistrySimple* registry) { - registry->RegisterBooleanPref(prefs::kReportArcStatusEnabled, false); - registry->RegisterDictionaryPref(prefs::kUserActivityTimes); - registry->RegisterTimePref(prefs::kLastChildScreenTimeReset, Time()); - registry->RegisterTimePref(prefs::kLastChildScreenTimeSaved, Time()); - registry->RegisterIntegerPref(prefs::kChildScreenTimeMilliseconds, 0); -} - TimeDelta DeviceStatusCollector::GetActiveChildScreenTime() { if (!user_manager::UserManager::Get()->IsLoggedInAsChildUser()) return TimeDelta::FromSeconds(0); @@ -894,10 +881,6 @@ } } -Time DeviceStatusCollector::GetCurrentTime() { - return Time::Now(); -} - void DeviceStatusCollector::ClearCachedResourceUsage() { resource_usage_.clear(); last_cpu_active_ = 0; @@ -1349,20 +1332,6 @@ return true; } -bool DeviceStatusCollector::GetBootMode(em::DeviceStatusReportRequest* status) { - std::string dev_switch_mode; - bool anything_reported = false; - if (statistics_provider_->GetMachineStatistic( - chromeos::system::kDevSwitchBootKey, &dev_switch_mode)) { - if (dev_switch_mode == chromeos::system::kDevSwitchBootValueDev) - status->set_boot_mode("Dev"); - else if (dev_switch_mode == chromeos::system::kDevSwitchBootValueVerified) - status->set_boot_mode("Verified"); - anything_reported = true; - } - return anything_reported; -} - bool DeviceStatusCollector::GetWriteProtectSwitch( em::DeviceStatusReportRequest* status) { std::string firmware_write_protect; @@ -1697,8 +1666,14 @@ if (report_version_info_) anything_reported |= GetVersionInfo(status); - if (report_boot_mode_) - anything_reported |= GetBootMode(status); + if (report_boot_mode_) { + base::Optional<std::string> boot_mode = + StatusCollector::GetBootMode(statistics_provider_); + if (boot_mode) { + status->set_boot_mode(*boot_mode); + anything_reported = true; + } + } if (report_network_interfaces_) anything_reported |= GetNetworkInterfaces(status); @@ -1722,21 +1697,6 @@ state->response_params().device_status.reset(); } -std::string DeviceStatusCollector::GetDMTokenForProfile(Profile* profile) { - CloudPolicyManager* user_cloud_policy_manager = - UserPolicyManagerFactoryChromeOS::GetCloudPolicyManagerForProfile( - profile); - if (!user_cloud_policy_manager) { - NOTREACHED(); - return std::string(); - } - - auto* cloud_policy_client = user_cloud_policy_manager->core()->client(); - std::string dm_token = cloud_policy_client->dm_token(); - - return dm_token; -} - bool DeviceStatusCollector::GetSessionStatusForUser( scoped_refptr<DeviceStatusCollectorState> state, em::SessionStatusReportRequest* status,
diff --git a/chrome/browser/chromeos/policy/status_collector/device_status_collector.h b/chrome/browser/chromeos/policy/status_collector/device_status_collector.h index 40c44070..f593463 100644 --- a/chrome/browser/chromeos/policy/status_collector/device_status_collector.h +++ b/chrome/browser/chromeos/policy/status_collector/device_status_collector.h
@@ -21,7 +21,6 @@ #include "base/memory/weak_ptr.h" #include "base/sequenced_task_runner.h" #include "base/task/cancelable_task_tracker.h" -#include "base/threading/thread_checker.h" #include "base/time/time.h" #include "base/timer/timer.h" #include "chrome/browser/chromeos/child_accounts/usage_time_state_notifier.h" @@ -63,7 +62,6 @@ namespace policy { -class ActivityStorage; struct DeviceLocalAccount; class DeviceStatusCollectorState; @@ -193,7 +191,6 @@ bool ShouldReportHardwareStatus() const override; static void RegisterPrefs(PrefRegistrySimple* registry); - static void RegisterProfilePrefs(PrefRegistrySimple* registry); // How often, in seconds, to poll to see if the user is idle. static const unsigned int kIdlePollIntervalSeconds = 30; @@ -212,19 +209,12 @@ // Check whether the user has been idle for a certain period of time. virtual void CheckIdleState(); - // Used instead of base::Time::Now(), to make testing possible. - virtual base::Time GetCurrentTime(); - // Handles the results of the idle state check. void ProcessIdleState(ui::IdleState state); // Gets the version of the passed app. Virtual to allow mocking. virtual std::string GetAppVersion(const std::string& app_id); - // Gets the DMToken associated with a profile. Returns an empty string if no - // DMToken could be retrieved. Virtual to allow mocking. - virtual std::string GetDMTokenForProfile(Profile* profile); - // Samples the current hardware resource usage to be sent up with the // next device status update. void SampleResourceUsage(); @@ -249,15 +239,6 @@ // power_manager::PowerManagerClient::Observer: void PowerChanged(const power_manager::PowerSupplyProperties& prop) override; - // The timeout in the past to store device activity. - // This is kept in case device status uploads fail for a number of days. - base::TimeDelta max_stored_past_activity_interval_; - - // The timeout in the future to store device activity. - // When changing the system time and/or timezones, it's possible to record - // activity time that is slightly in the future. - base::TimeDelta max_stored_future_activity_interval_; - // Updates the child's active time. void UpdateChildUsageTime(); @@ -290,7 +271,6 @@ bool GetActivityTimes( enterprise_management::DeviceStatusReportRequest* status); bool GetVersionInfo(enterprise_management::DeviceStatusReportRequest* status); - bool GetBootMode(enterprise_management::DeviceStatusReportRequest* status); bool GetWriteProtectSwitch( enterprise_management::DeviceStatusReportRequest* status); bool GetNetworkInterfaces( @@ -376,12 +356,12 @@ // Whether the last state of the device was active. This is used for child // accounts only. Active is defined as having the screen turned on. - bool last_state_active_; + bool last_state_active_ = true; // The maximum key that went into the last report generated by - // GetDeviceStatusAsync(), and the duration for it. This is used to trim - // the stored data in OnSubmittedSuccessfully(). Trimming is delayed so - // unsuccessful uploads don't result in dropped data. + // GetStatusAsync(), and the duration for it. This is used to trim the stored + // data in OnSubmittedSuccessfully(). Trimming is delayed so unsuccessful + // uploads don't result in dropped data. int64_t last_reported_day_ = 0; int duration_for_last_reported_day_ = 0; @@ -429,30 +409,15 @@ PowerStatusCallback power_status_callback_; - chromeos::system::StatisticsProvider* const statistics_provider_; - - chromeos::CrosSettings* const cros_settings_; - - // Power manager client. Used to listen to suspend and idle events. - chromeos::PowerManagerClient* const power_manager_; - - // Session manager. Used to listen to session state changes. - session_manager::SessionManager* const session_manager_; - // Runtime probe client. Used to fetch hardware data. chromeos::RuntimeProbeClient* const runtime_probe_; - // Stores and filters activity periods used for reporting. - std::unique_ptr<ActivityStorage> activity_storage_; - // The most recent CPU readings. uint64_t last_cpu_active_ = 0; uint64_t last_cpu_idle_ = 0; - // Cached values of the reporting settings from the device policy. - bool report_version_info_ = false; - bool report_activity_times_ = false; - bool report_boot_mode_ = false; + // Cached values of the reporting settings. These are enterprise only. There + // are common ones in StatusCollector interface. bool report_network_interfaces_ = false; bool report_users_ = false; bool report_hardware_status_ = false; @@ -466,17 +431,9 @@ // Whether reporting is for enterprise or consumer. bool is_enterprise_reporting_ = false; - // New day start time used to separate the children usage time into different - // days. - const base::TimeDelta activity_day_start_; - - std::unique_ptr<chromeos::CrosSettings::ObserverSubscription> - version_info_subscription_; std::unique_ptr<chromeos::CrosSettings::ObserverSubscription> activity_times_subscription_; std::unique_ptr<chromeos::CrosSettings::ObserverSubscription> - boot_mode_subscription_; - std::unique_ptr<chromeos::CrosSettings::ObserverSubscription> network_interfaces_subscription_; std::unique_ptr<chromeos::CrosSettings::ObserverSubscription> users_subscription_; @@ -497,10 +454,6 @@ std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_; - // Task runner in the creation thread where responses are sent to. - scoped_refptr<base::SequencedTaskRunner> task_runner_; - base::ThreadChecker thread_checker_; - base::WeakPtrFactory<DeviceStatusCollector> weak_factory_; DISALLOW_COPY_AND_ASSIGN(DeviceStatusCollector);
diff --git a/chrome/browser/chromeos/policy/status_collector/device_status_collector_browsertest.cc b/chrome/browser/chromeos/policy/status_collector/device_status_collector_browsertest.cc index bcd42040..10d57500 100644 --- a/chrome/browser/chromeos/policy/status_collector/device_status_collector_browsertest.cc +++ b/chrome/browser/chromeos/policy/status_collector/device_status_collector_browsertest.cc
@@ -194,7 +194,7 @@ return app_id; } - std::string GetDMTokenForProfile(Profile* profile) override { + std::string GetDMTokenForProfile(Profile* profile) const override { // Return the profile user name (passed to CreateTestingProfile) to make it // easy to confirm that the correct profile's DMToken was requested. return profile->GetProfileUserName();
diff --git a/chrome/browser/chromeos/policy/status_collector/status_collector.cc b/chrome/browser/chromeos/policy/status_collector/status_collector.cc index a0aa92a0..0e6632d9 100644 --- a/chrome/browser/chromeos/policy/status_collector/status_collector.cc +++ b/chrome/browser/chromeos/policy/status_collector/status_collector.cc
@@ -4,9 +4,17 @@ #include "chrome/browser/chromeos/policy/status_collector/status_collector.h" +#include "base/time/time.h" #include "chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_manager.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" #include "chrome/browser/chromeos/policy/device_local_account.h" +#include "chrome/browser/chromeos/policy/status_collector/activity_storage.h" +#include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h" +#include "chrome/browser/chromeos/policy/user_policy_manager_factory_chromeos.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/common/pref_names.h" +#include "chromeos/system/statistics_provider.h" +#include "components/prefs/pref_registry_simple.h" #include "components/user_manager/user_manager.h" namespace policy { @@ -41,6 +49,10 @@ } // namespace +// ----------------------------------------------------------------------------- +// StatusCollectorParams. +// ----------------------------------------------------------------------------- + StatusCollectorParams::StatusCollectorParams() { device_status = std::make_unique<ent_mgmt::DeviceStatusReportRequest>(); session_status = std::make_unique<ent_mgmt::SessionStatusReportRequest>(); @@ -53,6 +65,54 @@ StatusCollectorParams& StatusCollectorParams::operator=( StatusCollectorParams&&) = default; +// ----------------------------------------------------------------------------- +// StatusCollector. +// ----------------------------------------------------------------------------- +// static +void StatusCollector::RegisterProfilePrefs(PrefRegistrySimple* registry) { + registry->RegisterBooleanPref(prefs::kReportArcStatusEnabled, false); + + // TODO(crbug.com/827386): move to ChildStatusCollector after migration. + registry->RegisterDictionaryPref(prefs::kUserActivityTimes); + registry->RegisterTimePref(prefs::kLastChildScreenTimeReset, base::Time()); + registry->RegisterTimePref(prefs::kLastChildScreenTimeSaved, base::Time()); + registry->RegisterIntegerPref(prefs::kChildScreenTimeMilliseconds, 0); +} + +// static +base::Optional<std::string> StatusCollector::GetBootMode( + chromeos::system::StatisticsProvider* statistics_provider) { + std::string dev_switch_mode; + if (!statistics_provider->GetMachineStatistic( + chromeos::system::kDevSwitchBootKey, &dev_switch_mode)) { + return base::nullopt; + } + + if (dev_switch_mode == chromeos::system::kDevSwitchBootValueDev) { + return std::string("Dev"); + } + + if (dev_switch_mode == chromeos::system::kDevSwitchBootValueVerified) { + return std::string("Verified"); + } + + return base::nullopt; +} + +StatusCollector::StatusCollector( + chromeos::system::StatisticsProvider* provider, + chromeos::CrosSettings* cros_settings, + chromeos::PowerManagerClient* power_manager, + session_manager::SessionManager* session_manager, + base::TimeDelta activity_day_start) + : statistics_provider_(provider), + cros_settings_(cros_settings), + power_manager_(power_manager), + session_manager_(session_manager), + activity_day_start_(activity_day_start) {} + +StatusCollector::~StatusCollector() = default; + std::unique_ptr<DeviceLocalAccount> StatusCollector::GetAutoLaunchedKioskSessionInfo() { std::unique_ptr<DeviceLocalAccount> account = @@ -77,4 +137,16 @@ : nullptr; } +std::string StatusCollector::GetDMTokenForProfile(Profile* profile) const { + CloudPolicyManager* user_cloud_policy_manager = + UserPolicyManagerFactoryChromeOS::GetCloudPolicyManagerForProfile( + profile); + DCHECK(user_cloud_policy_manager != nullptr); + return user_cloud_policy_manager->core()->client()->dm_token(); +} + +base::Time StatusCollector::GetCurrentTime() { + return base::Time::Now(); +} + } // namespace policy
diff --git a/chrome/browser/chromeos/policy/status_collector/status_collector.h b/chrome/browser/chromeos/policy/status_collector/status_collector.h index 8110556f..d34c2a2 100644 --- a/chrome/browser/chromeos/policy/status_collector/status_collector.h +++ b/chrome/browser/chromeos/policy/status_collector/status_collector.h
@@ -8,10 +8,28 @@ #include <memory> #include "base/callback.h" +#include "base/optional.h" +#include "base/threading/thread_checker.h" +#include "base/time/time.h" +#include "chrome/browser/chromeos/settings/cros_settings.h" +#include "chromeos/dbus/power/power_manager_client.h" #include "components/policy/proto/device_management_backend.pb.h" +#include "components/session_manager/core/session_manager.h" +#include "components/session_manager/core/session_manager_observer.h" + +class PrefRegistrySimple; +class Profile; + +namespace chromeos { +class CrosSettings; +namespace system { +class StatisticsProvider; +} +} // namespace chromeos namespace policy { +class ActivityStorage; struct DeviceLocalAccount; // Groups parameters that are necessary either directly in the @@ -49,8 +67,19 @@ // Defines the API for a status collector. class StatusCollector { public: - StatusCollector() = default; - virtual ~StatusCollector() = default; + static void RegisterProfilePrefs(PrefRegistrySimple* registry); + + // Simplifies filling the boot mode for any of the relevant status report + // requests. + static base::Optional<std::string> GetBootMode( + chromeos::system::StatisticsProvider* statistics_provider); + + StatusCollector(chromeos::system::StatisticsProvider* provider, + chromeos::CrosSettings* cros_settings, + chromeos::PowerManagerClient* power_manager, + session_manager::SessionManager* session_manager, + base::TimeDelta activity_day_start); + virtual ~StatusCollector(); // Gathers status information and calls the passed response callback. virtual void GetStatusAsync(const StatusCollectorCallback& callback) = 0; @@ -72,6 +101,58 @@ // functionality such as network reporting). If it isn't a kiosk session, // nullptr is returned. virtual std::unique_ptr<DeviceLocalAccount> GetAutoLaunchedKioskSessionInfo(); + + protected: + // Gets the DMToken associated with a profile. Returns an empty string if no + // DMToken could be retrieved. Virtual to allow mocking. + virtual std::string GetDMTokenForProfile(Profile* profile) const; + + // Used instead of base::Time::Now(), to make testing possible. + // TODO(crbug.com/827386): pass a Clock object and use SimpleTestClock to test + // it. + virtual base::Time GetCurrentTime(); + + // The timeout in the past to store activity. + // This is kept in case status uploads fail for a number of days. + base::TimeDelta max_stored_past_activity_interval_; + + // The timeout in the future to store activity. + // When changing the system time and/or timezones, it's possible to record + // activity time that is slightly in the future. + base::TimeDelta max_stored_future_activity_interval_; + + chromeos::system::StatisticsProvider* const statistics_provider_; + + chromeos::CrosSettings* const cros_settings_; + + // Power manager client. Used to listen to suspend and idle events. + chromeos::PowerManagerClient* const power_manager_; + + // Session manager. Used to listen to session state changes. + session_manager::SessionManager* const session_manager_; + + // Stores and filters activity periods used for reporting. + std::unique_ptr<ActivityStorage> activity_storage_; + + // Cached values of the reporting settings. + bool report_version_info_ = false; + bool report_activity_times_ = false; + bool report_boot_mode_ = false; + + // New day start time used to separate the children usage time into different + // days. + const base::TimeDelta activity_day_start_; + + std::unique_ptr<chromeos::CrosSettings::ObserverSubscription> + version_info_subscription_; + std::unique_ptr<chromeos::CrosSettings::ObserverSubscription> + boot_mode_subscription_; + + // Task runner in the creation thread where responses are sent to. + scoped_refptr<base::SequencedTaskRunner> task_runner_ = nullptr; + // TODO(crbug.com/827386): check if it is possible to use the SequenceChecker + // instead. + base::ThreadChecker thread_checker_; }; } // namespace policy
diff --git a/chrome/browser/conflicts/module_database_win.cc b/chrome/browser/conflicts/module_database_win.cc index 5213cdf4..95bc78f7 100644 --- a/chrome/browser/conflicts/module_database_win.cc +++ b/chrome/browser/conflicts/module_database_win.cc
@@ -80,7 +80,8 @@ // only be invoked if it is still alive. pref_change_registrar->Add( prefs::kThirdPartyBlockingEnabled, - base::Bind(&OnThirdPartyBlockingPolicyChanged, pref_change_registrar)); + base::BindRepeating(&OnThirdPartyBlockingPolicyChanged, + pref_change_registrar)); } #endif // defined(GOOGLE_CHROME_BUILD) @@ -92,10 +93,10 @@ ModuleDatabase::ModuleDatabase( std::unique_ptr<service_manager::Connector> connector, bool third_party_blocking_policy_enabled) - : idle_timer_( - FROM_HERE, - kIdleTimeout, - base::Bind(&ModuleDatabase::OnDelayExpired, base::Unretained(this))), + : idle_timer_(FROM_HERE, + kIdleTimeout, + base::BindRepeating(&ModuleDatabase::OnDelayExpired, + base::Unretained(this))), has_started_processing_(false), shell_extensions_enumerated_(false), ime_enumerated_(false), @@ -104,8 +105,8 @@ #endif // ModuleDatabase owns |module_inspector_|, so it is safe to use // base::Unretained(). - module_inspector_(base::Bind(&ModuleDatabase::OnModuleInspected, - base::Unretained(this)), + module_inspector_(base::BindRepeating(&ModuleDatabase::OnModuleInspected, + base::Unretained(this)), std::move(connector)) { AddObserver(&module_inspector_); AddObserver(&third_party_metrics_);
diff --git a/chrome/browser/conflicts/module_event_sink_impl_win.h b/chrome/browser/conflicts/module_event_sink_impl_win.h index 8058e13e..785e3a78 100644 --- a/chrome/browser/conflicts/module_event_sink_impl_win.h +++ b/chrome/browser/conflicts/module_event_sink_impl_win.h
@@ -26,7 +26,7 @@ public: // Callback for retrieving the handle associated with a process. This is used // by "Create" to get a handle to the remote process. - using GetProcessCallback = base::Callback<base::Process()>; + using GetProcessCallback = base::RepeatingCallback<base::Process()>; using OnModuleLoadCallback = base::RepeatingCallback<void(content::ProcessType process_type,
diff --git a/chrome/browser/conflicts/module_inspector_win.h b/chrome/browser/conflicts/module_inspector_win.h index 181a347..1080ad9 100644 --- a/chrome/browser/conflicts/module_inspector_win.h +++ b/chrome/browser/conflicts/module_inspector_win.h
@@ -59,8 +59,8 @@ base::TimeDelta::FromMinutes(5); using OnModuleInspectedCallback = - base::Callback<void(const ModuleInfoKey& module_key, - ModuleInspectionResult inspection_result)>; + base::RepeatingCallback<void(const ModuleInfoKey& module_key, + ModuleInspectionResult inspection_result)>; ModuleInspector(const OnModuleInspectedCallback& on_module_inspected_callback, std::unique_ptr<service_manager::Connector> connector);
diff --git a/chrome/browser/conflicts/module_inspector_win_unittest.cc b/chrome/browser/conflicts/module_inspector_win_unittest.cc index ed1afc5..0dec2938 100644 --- a/chrome/browser/conflicts/module_inspector_win_unittest.cc +++ b/chrome/browser/conflicts/module_inspector_win_unittest.cc
@@ -91,8 +91,8 @@ TEST_F(ModuleInspectorTest, OneModule) { ModuleInspector module_inspector( - base::Bind(&ModuleInspectorTest::OnModuleInspected, - base::Unretained(this)), + base::BindRepeating(&ModuleInspectorTest::OnModuleInspected, + base::Unretained(this)), nullptr); module_inspector.AddModule({GetKernel32DllFilePath(), 0, 0}); @@ -110,8 +110,8 @@ }; ModuleInspector module_inspector( - base::Bind(&ModuleInspectorTest::OnModuleInspected, - base::Unretained(this)), + base::BindRepeating(&ModuleInspectorTest::OnModuleInspected, + base::Unretained(this)), nullptr); for (const auto& module : kTestCases) @@ -133,8 +133,8 @@ }; ModuleInspector module_inspector( - base::Bind(&ModuleInspectorTest::OnModuleInspected, - base::Unretained(this)), + base::BindRepeating(&ModuleInspectorTest::OnModuleInspected, + base::Unretained(this)), nullptr); for (const auto& module : kTestCases) @@ -168,8 +168,8 @@ }; ModuleInspector module_inspector( - base::Bind(&ModuleInspectorTest::OnModuleInspected, - base::Unretained(this)), + base::BindRepeating(&ModuleInspectorTest::OnModuleInspected, + base::Unretained(this)), nullptr); module_inspector.SetConnectorForTesting( test_connector_factory_.GetDefaultConnector()); @@ -201,8 +201,8 @@ CreateInspectionResultsCacheWithEntry(module_key, inspection_result)); ModuleInspector module_inspector( - base::Bind(&ModuleInspectorTest::OnModuleInspected, - base::Unretained(this)), + base::BindRepeating(&ModuleInspectorTest::OnModuleInspected, + base::Unretained(this)), nullptr); module_inspector.AddModule(module_key); @@ -230,8 +230,8 @@ chrome::DIR_USER_DATA, scoped_temp_dir.GetPath()); ModuleInspector module_inspector( - base::Bind(&ModuleInspectorTest::OnModuleInspected, - base::Unretained(this)), + base::BindRepeating(&ModuleInspectorTest::OnModuleInspected, + base::Unretained(this)), nullptr); ModuleInfoKey module_key(GetKernel32DllFilePath(), 0, 0); @@ -271,8 +271,8 @@ chrome::DIR_USER_DATA, scoped_temp_dir.GetPath()); ModuleInspector module_inspector( - base::Bind(&ModuleInspectorTest::OnModuleInspected, - base::Unretained(this)), + base::BindRepeating(&ModuleInspectorTest::OnModuleInspected, + base::Unretained(this)), nullptr); ModuleInfoKey module_key(GetKernel32DllFilePath(), 0, 0);
diff --git a/chrome/browser/conflicts/uninstall_application_win.cc b/chrome/browser/conflicts/uninstall_application_win.cc index 4f35fea..04e22a4 100644 --- a/chrome/browser/conflicts/uninstall_application_win.cc +++ b/chrome/browser/conflicts/uninstall_application_win.cc
@@ -40,20 +40,19 @@ L"SystemSettings_StorageSense_AppSizesListFilter_DisplayStringValue"); Microsoft::WRL::ComPtr<IUIAutomationCondition> condition; HRESULT result = automation->CreatePropertyCondition( - UIA_AutomationIdPropertyId, search_box_id, condition.GetAddressOf()); + UIA_AutomationIdPropertyId, search_box_id, &condition); if (FAILED(result)) return false; Microsoft::WRL::ComPtr<IUIAutomationTreeWalker> tree_walker; - result = - automation->CreateTreeWalker(condition.Get(), tree_walker.GetAddressOf()); + result = automation->CreateTreeWalker(condition.Get(), &tree_walker); if (FAILED(result)) return false; // Setup a cache request so that the element contains the needed property // afterwards. Microsoft::WRL::ComPtr<IUIAutomationCacheRequest> cache_request; - result = automation->CreateCacheRequest(cache_request.GetAddressOf()); + result = automation->CreateCacheRequest(&cache_request); if (FAILED(result)) return false; cache_request->AddPattern(UIA_ValuePatternId); @@ -214,12 +213,12 @@ return; Microsoft::WRL::ComPtr<IUIAutomationElement> search_box; - if (!FindSearchBoxElement(automation, sender, search_box.GetAddressOf())) + if (!FindSearchBoxElement(automation, sender, &search_box)) return; Microsoft::WRL::ComPtr<IUIAutomationValuePattern> value_pattern; - HRESULT result = search_box->GetCachedPatternAs( - UIA_ValuePatternId, IID_PPV_ARGS(value_pattern.GetAddressOf())); + HRESULT result = search_box->GetCachedPatternAs(UIA_ValuePatternId, + IID_PPV_ARGS(&value_pattern)); if (FAILED(result)) return;
diff --git a/chrome/browser/data_reduction_proxy/data_reduction_proxy_browsertest.cc b/chrome/browser/data_reduction_proxy/data_reduction_proxy_browsertest.cc index 673416a..cf425e4 100644 --- a/chrome/browser/data_reduction_proxy/data_reduction_proxy_browsertest.cc +++ b/chrome/browser/data_reduction_proxy/data_reduction_proxy_browsertest.cc
@@ -5,6 +5,7 @@ #include <tuple> #include "base/bind.h" +#include "base/metrics/field_trial_param_associator.h" #include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" @@ -37,6 +38,7 @@ #include "components/prefs/pref_service.h" #include "components/proxy_config/proxy_config_dictionary.h" #include "components/proxy_config/proxy_config_pref_names.h" +#include "components/variations/variations_associated_data.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/network_service_instance.h" #include "content/public/browser/storage_partition.h" @@ -210,10 +212,15 @@ // headers. void MonitorAndVerifyRequestsToProxyServer( const net::test_server::HttpRequest& request) { + ++count_proxy_server_requests_received_; // All requests to proxy server should have at least these headers. EXPECT_NE(request.headers.end(), request.headers.find(data_reduction_proxy::chrome_proxy_header())) << " url=" << request.GetURL() << " path=" << request.GetURL().path(); + + VerifyChromeProxyRequestHeader( + request.headers.at(data_reduction_proxy::chrome_proxy_header())); + EXPECT_NE( request.headers.end(), request.headers.find(data_reduction_proxy::chrome_proxy_ect_header())) @@ -223,6 +230,26 @@ monitored_urls_.push_back(request.GetURL()); } + void VerifyChromeProxyRequestHeader( + const std::string& chrome_proxy_header_value) const { + bool exp_found = false; + for (const auto& attributes : base::SplitStringPiece( + chrome_proxy_header_value, ",", base::TRIM_WHITESPACE, + base::SPLIT_WANT_NONEMPTY)) { + if (base::StartsWith(attributes, + "exp=", base::CompareCase::INSENSITIVE_ASCII)) { + const auto attribute_split = base::SplitStringPiece( + attributes, "=", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + EXPECT_EQ(2u, attribute_split.size()); + EXPECT_EQ(expect_exp_value_in_request_header_, attribute_split[1]); + exp_found = true; + } + } + EXPECT_EQ(!expect_exp_value_in_request_header_.empty(), exp_found) + << " expect_exp_value_in_request_header_=" + << expect_exp_value_in_request_header_; + } + // Returns true if a request for URL with path |url_path| was observed by // |this|. The method only compares the path instead of the full URL since the // hostname may be different due to the use of mock host in the browsertests @@ -276,6 +303,10 @@ void WaitForConfig() { config_run_loop_->Run(); } + std::string expect_exp_value_in_request_header_; + + size_t count_proxy_server_requests_received_ = 0u; + private: std::unique_ptr<net::test_server::HttpResponse> GetConfigResponse( const net::test_server::HttpRequest& request) { @@ -633,6 +664,37 @@ DataReductionProxyWithHoldbackBrowsertest, ::testing::Values(false, true)); +class DataReductionProxyExpBrowsertest : public DataReductionProxyBrowsertest { + public: + void SetUp() override { + base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( + data_reduction_proxy::switches::kDataReductionProxyExperiment, + "foo_experiment"); + + DataReductionProxyBrowsertest::SetUp(); + } +}; + +IN_PROC_BROWSER_TEST_F(DataReductionProxyExpBrowsertest, + ChromeProxyExpHeaderSet) { + expect_exp_value_in_request_header_ = "foo_experiment"; + + net::EmbeddedTestServer proxy_server; + proxy_server.RegisterRequestMonitor(base::BindRepeating( + &DataReductionProxyBrowsertest::MonitorAndVerifyRequestsToProxyServer, + base::Unretained(this))); + proxy_server.RegisterRequestHandler( + base::BindRepeating(&BasicResponse, kPrimaryResponse)); + ASSERT_TRUE(proxy_server.Start()); + SetConfig(CreateConfigForServer(proxy_server)); + // A network change forces the config to be fetched. + SimulateNetworkChange(network::mojom::ConnectionType::CONNECTION_3G); + WaitForConfig(); + + ui_test_utils::NavigateToURL(browser(), GURL("http://does.not.resolve/foo")); + EXPECT_LE(1u, count_proxy_server_requests_received_); +} + class DataReductionProxyBrowsertestWithNetworkService : public DataReductionProxyBrowsertest { public: @@ -731,6 +793,12 @@ location_header_ = header; } + void TearDown() override { + if (IsNetworkServiceEnabled()) { + EXPECT_LE(1u, count_proxy_server_requests_received_); + } + } + private: std::unique_ptr<net::test_server::HttpResponse> AddChromeProxyHeader( const net::test_server::HttpRequest& request) {
diff --git a/chrome/browser/extensions/extension_util.cc b/chrome/browser/extensions/extension_util.cc index 1c3b890..c6c7064 100644 --- a/chrome/browser/extensions/extension_util.cc +++ b/chrome/browser/extensions/extension_util.cc
@@ -361,7 +361,7 @@ // TODO(loyso): Unify this check as a util (including // MaybeCreateHostedAppController). Browser* browser = chrome::FindBrowserWithWebContents(web_contents); - return browser && browser->web_app_controller(); + return browser && browser->app_controller(); } } // namespace util
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 89e7cf08..865e2d43 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -665,7 +665,7 @@ }, { "name": "enable-accessibility-tab-switcher", - // "owners": [ "your-team" ], + "owners": [ "dtrainor", "mdjones" ], "expiry_milestone": 76 }, { @@ -2022,11 +2022,6 @@ "expiry_milestone": 78 }, { - "name": "force-enable-stylus-tools", - // "owners": [ "your-team" ], - "expiry_milestone": 76 - }, - { "name": "force-enable-system-aec", "owners": [ "grunell" ], "expiry_milestone": 80
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 6ee24cd0..59fff89 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -3114,11 +3114,6 @@ const char kFirstRunUiTransitionsDescription[] = "Transitions during first-run tutorial are animated."; -const char kForceEnableStylusToolsName[] = "Force enable stylus features"; -const char kForceEnableStylusToolsDescription[] = - "Forces display of the stylus tools menu in the shelf and the stylus " - "section in settings, even if there is no attached stylus device."; - const char kForceUseChromeCameraName[] = "Open Chrome camera app when clicking on camera icon"; const char kForceUseChromeCameraDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 81157dc..59e22475 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1876,9 +1876,6 @@ extern const char kFirstRunUiTransitionsName[]; extern const char kFirstRunUiTransitionsDescription[]; -extern const char kForceEnableStylusToolsName[]; -extern const char kForceEnableStylusToolsDescription[]; - extern const char kForceUseChromeCameraName[]; extern const char kForceUseChromeCameraDescription[];
diff --git a/chrome/browser/page_load_metrics/observers/protocol_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/protocol_page_load_metrics_observer.cc index aeac2fb..657b1d5 100644 --- a/chrome/browser/page_load_metrics/observers/protocol_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/protocol_page_load_metrics_observer.cc
@@ -70,6 +70,7 @@ case net::HttpResponseInfo::CONNECTION_INFO_QUIC_46: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_47: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_99: + case net::HttpResponseInfo::CONNECTION_INFO_QUIC_999: PAGE_LOAD_HISTOGRAM( "PageLoad.Clients.Protocol.QUIC.ParseTiming.NavigationToParseStart", timing.parse_timing->parse_start.value()); @@ -130,6 +131,7 @@ case net::HttpResponseInfo::CONNECTION_INFO_QUIC_46: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_47: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_99: + case net::HttpResponseInfo::CONNECTION_INFO_QUIC_999: PAGE_LOAD_HISTOGRAM( "PageLoad.Clients.Protocol.QUIC.PaintTiming." "NavigationToFirstContentfulPaint", @@ -196,6 +198,7 @@ case net::HttpResponseInfo::CONNECTION_INFO_QUIC_46: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_47: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_99: + case net::HttpResponseInfo::CONNECTION_INFO_QUIC_999: PAGE_LOAD_HISTOGRAM( "PageLoad.Clients.Protocol.QUIC.Experimental.PaintTiming." "NavigationToFirstMeaningfulPaint", @@ -252,6 +255,7 @@ case net::HttpResponseInfo::CONNECTION_INFO_QUIC_46: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_47: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_99: + case net::HttpResponseInfo::CONNECTION_INFO_QUIC_999: PAGE_LOAD_HISTOGRAM( "PageLoad.Clients.Protocol.QUIC.DocumentTiming." "NavigationToDOMContentLoadedEventFired", @@ -303,6 +307,7 @@ case net::HttpResponseInfo::CONNECTION_INFO_QUIC_46: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_47: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_99: + case net::HttpResponseInfo::CONNECTION_INFO_QUIC_999: PAGE_LOAD_HISTOGRAM( "PageLoad.Clients.Protocol.QUIC.DocumentTiming." "NavigationToLoadEventFired",
diff --git a/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.cc index 0ab8c00..c4517bb 100644 --- a/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.cc
@@ -78,6 +78,7 @@ case net::HttpResponseInfo::CONNECTION_INFO_QUIC_46: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_47: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_99: + case net::HttpResponseInfo::CONNECTION_INFO_QUIC_999: return HttpProtocolScheme::kQuic; } }
diff --git a/chrome/browser/performance_manager/performance_manager_tab_helper.cc b/chrome/browser/performance_manager/performance_manager_tab_helper.cc index 8b40d36..fbf3c839e 100644 --- a/chrome/browser/performance_manager/performance_manager_tab_helper.cc +++ b/chrome/browser/performance_manager/performance_manager_tab_helper.cc
@@ -297,8 +297,7 @@ void PerformanceManagerTabHelper::UpdatePageNodeVisibility( content::Visibility visibility) { - // TODO(fdoray): An OCCLUDED tab should not be considered visible. - const bool is_visible = visibility != content::Visibility::HIDDEN; + const bool is_visible = visibility == content::Visibility::VISIBLE; PostToGraph(FROM_HERE, &PageNodeImpl::SetIsVisible, page_node_.get(), is_visible); }
diff --git a/chrome/browser/resource_coordinator/exponential_moving_average.cc b/chrome/browser/performance_manager/persistence/site_data/exponential_moving_average.cc similarity index 87% rename from chrome/browser/resource_coordinator/exponential_moving_average.cc rename to chrome/browser/performance_manager/persistence/site_data/exponential_moving_average.cc index 7eca8bf..82b6e24b 100644 --- a/chrome/browser/resource_coordinator/exponential_moving_average.cc +++ b/chrome/browser/performance_manager/persistence/site_data/exponential_moving_average.cc
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/resource_coordinator/exponential_moving_average.h" +#include "chrome/browser/performance_manager/persistence/site_data/exponential_moving_average.h" #include <cmath> #include "base/logging.h" -namespace resource_coordinator { +namespace performance_manager { ExponentialMovingAverage::ExponentialMovingAverage(float alpha) : alpha_(alpha) { @@ -50,4 +50,4 @@ num_datums_ = 0; } -} // namespace resource_coordinator +} // namespace performance_manager
diff --git a/chrome/browser/resource_coordinator/exponential_moving_average.h b/chrome/browser/performance_manager/persistence/site_data/exponential_moving_average.h similarity index 78% rename from chrome/browser/resource_coordinator/exponential_moving_average.h rename to chrome/browser/performance_manager/persistence/site_data/exponential_moving_average.h index 96beedd..5b7b62f3 100644 --- a/chrome/browser/resource_coordinator/exponential_moving_average.h +++ b/chrome/browser/performance_manager/persistence/site_data/exponential_moving_average.h
@@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_RESOURCE_COORDINATOR_EXPONENTIAL_MOVING_AVERAGE_H_ -#define CHROME_BROWSER_RESOURCE_COORDINATOR_EXPONENTIAL_MOVING_AVERAGE_H_ +#ifndef CHROME_BROWSER_PERFORMANCE_MANAGER_PERSISTENCE_SITE_DATA_EXPONENTIAL_MOVING_AVERAGE_H_ +#define CHROME_BROWSER_PERFORMANCE_MANAGER_PERSISTENCE_SITE_DATA_EXPONENTIAL_MOVING_AVERAGE_H_ #include <cstddef> -namespace resource_coordinator { +namespace performance_manager { // This class is an implementation of an exponential moving average, // as described in @@ -46,6 +46,6 @@ size_t num_datums_ = 0; }; -} // namespace resource_coordinator +} // namespace performance_manager -#endif // CHROME_BROWSER_RESOURCE_COORDINATOR_EXPONENTIAL_MOVING_AVERAGE_H_ +#endif // CHROME_BROWSER_PERFORMANCE_MANAGER_PERSISTENCE_SITE_DATA_EXPONENTIAL_MOVING_AVERAGE_H_
diff --git a/chrome/browser/resource_coordinator/exponential_moving_average_unittest.cc b/chrome/browser/performance_manager/persistence/site_data/exponential_moving_average_unittest.cc similarity index 93% rename from chrome/browser/resource_coordinator/exponential_moving_average_unittest.cc rename to chrome/browser/performance_manager/persistence/site_data/exponential_moving_average_unittest.cc index 74f5b11b..b8419b68 100644 --- a/chrome/browser/resource_coordinator/exponential_moving_average_unittest.cc +++ b/chrome/browser/performance_manager/persistence/site_data/exponential_moving_average_unittest.cc
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/resource_coordinator/exponential_moving_average.h" +#include "chrome/browser/performance_manager/persistence/site_data/exponential_moving_average.h" #include "testing/gtest/include/gtest/gtest.h" -namespace resource_coordinator { +namespace performance_manager { TEST(ExponentialMovingAverageTest, AppendDatum) { ExponentialMovingAverage avg(0.5); @@ -94,4 +94,4 @@ EXPECT_EQ(old_value, avg.value()); } -} // namespace resource_coordinator +} // namespace performance_manager
diff --git a/chrome/browser/performance_manager/persistence/site_data/feature_usage.h b/chrome/browser/performance_manager/persistence/site_data/feature_usage.h new file mode 100644 index 0000000..2496abb8 --- /dev/null +++ b/chrome/browser/performance_manager/persistence/site_data/feature_usage.h
@@ -0,0 +1,20 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_PERFORMANCE_MANAGER_PERSISTENCE_SITE_DATA_FEATURE_USAGE_H_ +#define CHROME_BROWSER_PERFORMANCE_MANAGER_PERSISTENCE_SITE_DATA_FEATURE_USAGE_H_ + +namespace performance_manager { + +// A tri-state return value for site feature usage. If a definitive decision +// can't be made then an "unknown" result can be returned. +enum class SiteFeatureUsage { + kSiteFeatureNotInUse, + kSiteFeatureInUse, + kSiteFeatureUsageUnknown, +}; + +} // namespace performance_manager + +#endif // CHROME_BROWSER_PERFORMANCE_MANAGER_PERSISTENCE_SITE_DATA_FEATURE_USAGE_H_
diff --git a/chrome/browser/performance_manager/persistence/site_data/tab_visibility.h b/chrome/browser/performance_manager/persistence/site_data/tab_visibility.h new file mode 100644 index 0000000..81c653e3 --- /dev/null +++ b/chrome/browser/performance_manager/persistence/site_data/tab_visibility.h
@@ -0,0 +1,14 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_PERFORMANCE_MANAGER_PERSISTENCE_SITE_DATA_TAB_VISIBILITY_H_ +#define CHROME_BROWSER_PERFORMANCE_MANAGER_PERSISTENCE_SITE_DATA_TAB_VISIBILITY_H_ + +namespace performance_manager { + +enum class TabVisibility { kBackground, kForeground }; + +} // namespace performance_manager + +#endif // CHROME_BROWSER_PERFORMANCE_MANAGER_PERSISTENCE_SITE_DATA_TAB_VISIBILITY_H_
diff --git a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc index 413e9e5f..bcd1b0f 100644 --- a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc +++ b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
@@ -70,7 +70,7 @@ // PictureInPictureWindowController: MOCK_METHOD0(Show, gfx::Size()); - MOCK_METHOD2(Close, void(bool, bool)); + MOCK_METHOD1(Close, void(bool)); MOCK_METHOD0(CloseAndFocusInitiator, void()); MOCK_METHOD0(OnWindowDestroyed, void()); MOCK_METHOD2(EmbedSurface, void(const viz::SurfaceId&, const gfx::Size&)); @@ -396,8 +396,7 @@ EXPECT_TRUE(active_web_contents->HasPictureInPictureVideo()); // Stop video being played Picture-in-Picture and check if that's tracked. - window_controller()->Close(true /* should_pause_video */, - true /* should_reset_pip_player */); + window_controller()->Close(true /* should_pause_video */); EXPECT_FALSE(active_web_contents->HasPictureInPictureVideo()); // Reload page should not crash. @@ -469,8 +468,7 @@ active_web_contents, "isInPictureInPicture();", &in_picture_in_picture)); EXPECT_TRUE(in_picture_in_picture); - window_controller()->Close(true /* should_pause_video */, - true /* should_reset_pip_player */); + window_controller()->Close(true /* should_pause_video */); base::string16 expected_title = base::ASCIIToUTF16("left"); EXPECT_EQ(expected_title, @@ -509,8 +507,7 @@ EXPECT_TRUE(in_picture_in_picture); ASSERT_TRUE(window_controller()); - window_controller()->Close(true /* should_pause_video */, - true /* should_reset_pip_player */); + window_controller()->Close(true /* should_pause_video */); base::string16 expected_title = base::ASCIIToUTF16("left"); EXPECT_EQ(expected_title, @@ -548,8 +545,7 @@ EXPECT_TRUE(in_picture_in_picture); ASSERT_TRUE(window_controller()); - window_controller()->Close(true /* should_pause_video */, - true /* should_reset_pip_player */); + window_controller()->Close(true /* should_pause_video */); base::string16 expected_title = base::ASCIIToUTF16("failed to enter Picture-in-Picture after leaving"); @@ -706,6 +702,8 @@ OverlayWindowViews* overlay_window = static_cast<OverlayWindowViews*>( window_controller()->GetWindowForTesting()); + EXPECT_TRUE(overlay_window->IsVisible()); + EXPECT_EQ(overlay_window->playback_state_for_testing(), OverlayWindowViews::PlaybackState::kPaused); } @@ -858,8 +856,7 @@ active_web_contents, "enterPictureInPicture();", &result)); EXPECT_TRUE(result); - window_controller()->Close(true /* should_pause_video */, - true /* should_reset_pip_player */); + window_controller()->Close(true /* should_pause_video */); // Wait for the window to close. base::string16 expected_title = base::ASCIIToUTF16("left"); @@ -881,8 +878,7 @@ EXPECT_FALSE(video_paused); // This should be a no-op because the window is not visible. - window_controller()->Close(true /* should_pause_video */, - true /* should_reset_pip_player */); + window_controller()->Close(true /* should_pause_video */); ASSERT_TRUE(content::ExecuteScriptAndExtractBool( active_web_contents, "isPaused();", &video_paused)); @@ -941,6 +937,146 @@ ASSERT_TRUE(window_controller()->GetWindowForTesting()->IsVisible()); } +// Closing a tab that lost Picture-in-Picture because a new tab entered it +// should not close the current Picture-in-Picture window. +IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest, + PictureInPictureDoNotCloseAfterClosingTab) { + GURL test_page_url = ui_test_utils::GetTestUrl( + base::FilePath(base::FilePath::kCurrentDirectory), + base::FilePath( + FILE_PATH_LITERAL("media/picture-in-picture/window-size.html"))); + ui_test_utils::NavigateToURL(browser(), test_page_url); + + content::WebContents* initial_web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_TRUE(initial_web_contents != nullptr); + + SetUpWindowController(initial_web_contents); + + { + bool result = false; + ASSERT_TRUE(content::ExecuteScriptAndExtractBool( + initial_web_contents, "enterPictureInPicture();", &result)); + EXPECT_TRUE(result); + } + + EXPECT_TRUE(window_controller()->GetWindowForTesting()->IsVisible()); + + // Open a new tab in the browser and starts Picture-in-Picture. + AddTabAtIndex(1, test_page_url, ui::PAGE_TRANSITION_TYPED); + EXPECT_EQ(2, browser()->tab_strip_model()->count()); + EXPECT_EQ(1, browser()->tab_strip_model()->active_index()); + + content::WebContents* new_web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_TRUE(new_web_contents != nullptr); + + { + content::PictureInPictureWindowController* pip_window_controller = + content::PictureInPictureWindowController::GetOrCreateForWebContents( + new_web_contents); + + bool result = false; + ASSERT_TRUE(content::ExecuteScriptAndExtractBool( + new_web_contents, "enterPictureInPicture();", &result)); + EXPECT_TRUE(result); + + EXPECT_TRUE(pip_window_controller->GetWindowForTesting()->IsVisible()); + + // 'left' is sent when the first tab leaves Picture-in-Picture. + base::string16 expected_title = base::ASCIIToUTF16("left"); + EXPECT_EQ(expected_title, + content::TitleWatcher(initial_web_contents, expected_title) + .WaitAndGetTitle()); + } + + // Closing the initial tab should not get the new tab to leave + // Picture-in-Picture. + browser()->tab_strip_model()->CloseWebContentsAt(0, 0); + EXPECT_EQ(1, browser()->tab_strip_model()->count()); + EXPECT_EQ(0, browser()->tab_strip_model()->active_index()); + + base::RunLoop().RunUntilIdle(); + + bool in_picture_in_picture = false; + ASSERT_TRUE(ExecuteScriptAndExtractBool( + new_web_contents, "isInPictureInPicture();", &in_picture_in_picture)); + EXPECT_TRUE(in_picture_in_picture); +} + +// Killing an iframe that lost Picture-in-Picture because the main frame entered +// it should not close the current Picture-in-Picture window. +IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest, + PictureInPictureDoNotCloseAfterKillingFrame) { + GURL test_page_url = ui_test_utils::GetTestUrl( + base::FilePath(base::FilePath::kCurrentDirectory), + base::FilePath( + FILE_PATH_LITERAL("media/picture-in-picture/iframe-test.html"))); + ui_test_utils::NavigateToURL(browser(), test_page_url); + + content::WebContents* active_web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_TRUE(active_web_contents != nullptr); + + SetUpWindowController(active_web_contents); + + std::vector<content::RenderFrameHost*> render_frame_hosts = + active_web_contents->GetAllFrames(); + ASSERT_EQ(2u, render_frame_hosts.size()); + + content::RenderFrameHost* iframe = + render_frame_hosts[0] == active_web_contents->GetMainFrame() + ? render_frame_hosts[1] + : render_frame_hosts[0]; + + { + bool result = false; + ASSERT_TRUE(content::ExecuteScriptAndExtractBool( + iframe, "enterPictureInPicture();", &result)); + EXPECT_TRUE(result); + } + + EXPECT_TRUE(window_controller()->GetWindowForTesting()->IsVisible()); + + bool result = false; + ASSERT_TRUE(content::ExecuteScriptAndExtractBool( + active_web_contents, "enterPictureInPicture();", &result)); + EXPECT_TRUE(result); + + EXPECT_TRUE(window_controller()->GetWindowForTesting()->IsVisible()); + + base::RunLoop().RunUntilIdle(); + + { + bool in_picture_in_picture = false; + ASSERT_TRUE( + ExecuteScriptAndExtractBool(iframe, + "window.domAutomationController.send(!!" + "document.pictureInPictureElement);", + &in_picture_in_picture)); + EXPECT_FALSE(in_picture_in_picture); + } + + // Removing the iframe should not lead to the main frame leaving + // Picture-in-Picture. + ASSERT_TRUE(content::ExecuteScript(active_web_contents, "removeFrame();")); + + EXPECT_EQ(1u, active_web_contents->GetAllFrames().size()); + EXPECT_TRUE(window_controller()->GetWindowForTesting()->IsVisible()); + + base::RunLoop().RunUntilIdle(); + + { + bool in_picture_in_picture = false; + ASSERT_TRUE( + ExecuteScriptAndExtractBool(active_web_contents, + "window.domAutomationController.send(!!" + "document.pictureInPictureElement);", + &in_picture_in_picture)); + EXPECT_TRUE(in_picture_in_picture); + } +} + // Checks setting disablePictureInPicture on video just after requesting // Picture-in-Picture doesn't result in a window opened. IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest, @@ -1321,12 +1457,14 @@ ASSERT_NE(nullptr, pip_window_manager); // Show the non-WebContents based Picture-in-Picture window controller. + EXPECT_CALL(mock_controller(), GetInitiatorWebContents()) + .WillOnce(testing::Return(nullptr)); EXPECT_CALL(mock_controller(), Show()); pip_window_manager->EnterPictureInPictureWithController(&mock_controller()); // Now show the WebContents based Picture-in-Picture window controller. // This should close the existing window and show the new one. - EXPECT_CALL(mock_controller(), Close(_, _)); + EXPECT_CALL(mock_controller(), Close(_)); LoadTabAndEnterPictureInPicture(browser()); OverlayWindowViews* overlay_window = static_cast<OverlayWindowViews*>( @@ -1368,8 +1506,7 @@ active_web_contents, "changeSrcAndLoad();", &result)); ASSERT_TRUE(result); - window_controller()->Close(true /* should_pause_video */, - true /* should_reset_pip_player */); + window_controller()->Close(true /* should_pause_video */); result = false; ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
diff --git a/chrome/browser/picture_in_picture/picture_in_picture_window_manager.cc b/chrome/browser/picture_in_picture/picture_in_picture_window_manager.cc index 6f5db71..c2b0ec0 100644 --- a/chrome/browser/picture_in_picture/picture_in_picture_window_manager.cc +++ b/chrome/browser/picture_in_picture/picture_in_picture_window_manager.cc
@@ -26,12 +26,10 @@ navigation_handle->IsSameDocument()) { return; } - owner_->CloseWindowInternal(true /* should_reset_pip_player */); + owner_->CloseWindowInternal(); } - void WebContentsDestroyed() final { - owner_->CloseWindowInternal(true /* should_reset_pip_player */); - } + void WebContentsDestroyed() final { owner_->CloseWindowInternal(); } private: // Owns |this|. @@ -47,7 +45,7 @@ // If there was already a controller, close the existing window before // creating the next one. if (pip_window_controller_) - CloseWindowInternal(false /* should_reset_pip_player */); + CloseWindowInternal(); pip_window_controller_ = pip_window_controller; @@ -58,16 +56,15 @@ content::WebContents* web_contents, const viz::SurfaceId& surface_id, const gfx::Size& natural_size) { - // If there was already a controller, close the existing window before - // creating the next one. - if (pip_window_controller_) - CloseWindowInternal(false /* should_reset_pip_player */); - // Create or update |pip_window_controller_| for the current WebContents, if // it is a WebContents based PIP. if (!pip_window_controller_ || - (pip_window_controller_->GetInitiatorWebContents() != nullptr && - pip_window_controller_->GetInitiatorWebContents() != web_contents)) { + pip_window_controller_->GetInitiatorWebContents() != web_contents) { + // If there was already a controller, close the existing window before + // creating the next one. + if (pip_window_controller_) + CloseWindowInternal(); + CreateWindowInternal(web_contents); } @@ -77,7 +74,7 @@ void PictureInPictureWindowManager::ExitPictureInPicture() { if (pip_window_controller_) - CloseWindowInternal(true /* should_reset_pip_player */); + CloseWindowInternal(); } content::WebContents* PictureInPictureWindowManager::GetWebContents() { @@ -95,13 +92,11 @@ web_contents); } -void PictureInPictureWindowManager::CloseWindowInternal( - bool should_reset_pip_player) { +void PictureInPictureWindowManager::CloseWindowInternal() { DCHECK(pip_window_controller_); contents_observer_.reset(); - pip_window_controller_->Close(false /* should_pause_video */, - should_reset_pip_player); + pip_window_controller_->Close(false /* should_pause_video */); pip_window_controller_ = nullptr; }
diff --git a/chrome/browser/picture_in_picture/picture_in_picture_window_manager.h b/chrome/browser/picture_in_picture/picture_in_picture_window_manager.h index 2889da03..97abe26 100644 --- a/chrome/browser/picture_in_picture/picture_in_picture_window_manager.h +++ b/chrome/browser/picture_in_picture/picture_in_picture_window_manager.h
@@ -54,7 +54,7 @@ // Closes the active Picture-in-Picture window. // There MUST be a window open. // This is suffixed with "Internal" to keep consistency with the method above. - void CloseWindowInternal(bool should_reset_pip_player); + void CloseWindowInternal(); PictureInPictureWindowManager(); ~PictureInPictureWindowManager();
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 56fb0cc7d..ca88397 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -270,6 +270,7 @@ #include "chrome/browser/chromeos/policy/dm_token_storage.h" #include "chrome/browser/chromeos/policy/policy_cert_service_factory.h" #include "chrome/browser/chromeos/policy/status_collector/device_status_collector.h" +#include "chrome/browser/chromeos/policy/status_collector/status_collector.h" #include "chrome/browser/chromeos/power/auto_screen_brightness/metrics_reporter.h" #include "chrome/browser/chromeos/power/power_metrics_reporter.h" #include "chrome/browser/chromeos/preferences.h" @@ -842,7 +843,7 @@ plugin_vm::prefs::RegisterProfilePrefs(registry); policy::AppInstallEventLogger::RegisterProfilePrefs(registry); policy::AppInstallEventLogManagerWrapper::RegisterProfilePrefs(registry); - policy::DeviceStatusCollector::RegisterProfilePrefs(registry); + policy::StatusCollector::RegisterProfilePrefs(registry); ::onc::RegisterProfilePrefs(registry); #if BUILDFLAG(ENABLE_CROS_ASSISTANT)
diff --git a/chrome/browser/previews/previews_lite_page_navigation_throttle.cc b/chrome/browser/previews/previews_lite_page_navigation_throttle.cc index 9ea332f..1995729 100644 --- a/chrome/browser/previews/previews_lite_page_navigation_throttle.cc +++ b/chrome/browser/previews/previews_lite_page_navigation_throttle.cc
@@ -338,16 +338,8 @@ GURL PreviewsLitePageNavigationThrottle::GetPreviewsURLForURL( const GURL& original_url) { DCHECK(original_url.is_valid()); - std::string experiment_id = variations::GetVariationParamValue( - data_reduction_proxy::params::GetServerExperimentsFieldTrialName(), - data_reduction_proxy::kExperimentsOption); - - // Allow the command line to override any variations-provided experiment. - std::string cmd_line_experiment = - base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( - data_reduction_proxy::switches::kDataReductionProxyExperiment); - if (!cmd_line_experiment.empty()) - experiment_id = cmd_line_experiment; + const std::string experiment_id = + data_reduction_proxy::params::GetDataSaverServerExperiments(); std::string experiment_query; if (!experiment_id.empty()) {
diff --git a/chrome/browser/previews/previews_lite_page_navigation_throttle_unittest.cc b/chrome/browser/previews/previews_lite_page_navigation_throttle_unittest.cc index 7ef57f5..13b739a 100644 --- a/chrome/browser/previews/previews_lite_page_navigation_throttle_unittest.cc +++ b/chrome/browser/previews/previews_lite_page_navigation_throttle_unittest.cc
@@ -134,12 +134,16 @@ {{"previews_host", test_case.previews_host}}); base::FieldTrialList::CreateFieldTrial( - data_reduction_proxy::params::GetServerExperimentsFieldTrialName(), + data_reduction_proxy::params:: + GetDataSaverServerExperimentsFieldTrialNameForTesting(), "enabled"); std::map<std::string, std::string> server_experiment; - server_experiment["exp"] = test_case.experiment_variation; + server_experiment[data_reduction_proxy::params:: + GetDataSaverServerExperimentsOptionName()] = + test_case.experiment_variation; variations::AssociateVariationParams( - data_reduction_proxy::params::GetServerExperimentsFieldTrialName(), + data_reduction_proxy::params:: + GetDataSaverServerExperimentsFieldTrialNameForTesting(), "enabled", server_experiment); EXPECT_EQ(PreviewsLitePageNavigationThrottle::GetPreviewsURLForURL(
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_impl.cc b/chrome/browser/resource_coordinator/local_site_characteristics_data_impl.cc index dea94bcc..43114981 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_data_impl.cc +++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_impl.cc
@@ -61,10 +61,10 @@ } void LocalSiteCharacteristicsDataImpl::NotifySiteUnloaded( - TabVisibility tab_visibility) { + performance_manager::TabVisibility tab_visibility) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (tab_visibility == TabVisibility::kBackground) + if (tab_visibility == performance_manager::TabVisibility::kBackground) DecrementNumLoadedBackgroundTabs(); loaded_tabs_count_--; @@ -94,28 +94,28 @@ DecrementNumLoadedBackgroundTabs(); } -SiteFeatureUsage LocalSiteCharacteristicsDataImpl::UpdatesFaviconInBackground() - const { +performance_manager::SiteFeatureUsage +LocalSiteCharacteristicsDataImpl::UpdatesFaviconInBackground() const { return GetFeatureUsage( site_characteristics_.updates_favicon_in_background(), GetSiteCharacteristicsDatabaseParams().favicon_update_observation_window); } -SiteFeatureUsage LocalSiteCharacteristicsDataImpl::UpdatesTitleInBackground() - const { +performance_manager::SiteFeatureUsage +LocalSiteCharacteristicsDataImpl::UpdatesTitleInBackground() const { return GetFeatureUsage( site_characteristics_.updates_title_in_background(), GetSiteCharacteristicsDatabaseParams().title_update_observation_window); } -SiteFeatureUsage LocalSiteCharacteristicsDataImpl::UsesAudioInBackground() - const { +performance_manager::SiteFeatureUsage +LocalSiteCharacteristicsDataImpl::UsesAudioInBackground() const { return GetFeatureUsage( site_characteristics_.uses_audio_in_background(), GetSiteCharacteristicsDatabaseParams().audio_usage_observation_window); } -SiteFeatureUsage +performance_manager::SiteFeatureUsage LocalSiteCharacteristicsDataImpl::UsesNotificationsInBackground() const { return GetFeatureUsage( site_characteristics_.uses_notifications_in_background(), @@ -286,7 +286,8 @@ TransitionToFullyInitialized(); } -SiteFeatureUsage LocalSiteCharacteristicsDataImpl::GetFeatureUsage( +performance_manager::SiteFeatureUsage +LocalSiteCharacteristicsDataImpl::GetFeatureUsage( const SiteDataFeatureProto& feature_proto, const base::TimeDelta min_obs_time) const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -299,12 +300,12 @@ // TODO(sebmarchand): Check the timestamp and reset features that haven't been // observed in a long time, https://crbug.com/826446. if (feature_proto.has_use_timestamp()) - return SiteFeatureUsage::kSiteFeatureInUse; + return performance_manager::SiteFeatureUsage::kSiteFeatureInUse; if (FeatureObservationDuration(feature_proto) >= min_obs_time) - return SiteFeatureUsage::kSiteFeatureNotInUse; + return performance_manager::SiteFeatureUsage::kSiteFeatureNotInUse; - return SiteFeatureUsage::kSiteFeatureUsageUnknown; + return performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown; } void LocalSiteCharacteristicsDataImpl::NotifyFeatureUsage(
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_impl.h b/chrome/browser/resource_coordinator/local_site_characteristics_data_impl.h index 4ef33b94..d455d2a77 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_data_impl.h +++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_impl.h
@@ -12,11 +12,11 @@ #include "base/memory/weak_ptr.h" #include "base/sequence_checker.h" #include "base/time/time.h" +#include "chrome/browser/performance_manager/persistence/site_data/exponential_moving_average.h" +#include "chrome/browser/performance_manager/persistence/site_data/feature_usage.h" #include "chrome/browser/performance_manager/persistence/site_data/site_data.pb.h" -#include "chrome/browser/resource_coordinator/exponential_moving_average.h" +#include "chrome/browser/performance_manager/persistence/site_data/tab_visibility.h" #include "chrome/browser/resource_coordinator/local_site_characteristics_database.h" -#include "chrome/browser/resource_coordinator/local_site_characteristics_feature_usage.h" -#include "chrome/browser/resource_coordinator/site_characteristics_tab_visibility.h" #include "chrome/browser/resource_coordinator/tab_manager_features.h" #include "url/origin.h" @@ -74,7 +74,7 @@ // Must be called when an unload event is received for this site, this can be // invoked several times if instances of this class are shared between // multiple tabs. - void NotifySiteUnloaded(TabVisibility tab_visibility); + void NotifySiteUnloaded(performance_manager::TabVisibility tab_visibility); // Must be called when a loaded tab gets backgrounded. void NotifyLoadedSiteBackgrounded(); @@ -83,10 +83,10 @@ void NotifyLoadedSiteForegrounded(); // Returns the usage of a given feature for this origin. - SiteFeatureUsage UpdatesFaviconInBackground() const; - SiteFeatureUsage UpdatesTitleInBackground() const; - SiteFeatureUsage UsesAudioInBackground() const; - SiteFeatureUsage UsesNotificationsInBackground() const; + performance_manager::SiteFeatureUsage UpdatesFaviconInBackground() const; + performance_manager::SiteFeatureUsage UpdatesTitleInBackground() const; + performance_manager::SiteFeatureUsage UsesAudioInBackground() const; + performance_manager::SiteFeatureUsage UsesNotificationsInBackground() const; // Returns true if the most authoritative data has been loaded from the // backing store. @@ -98,13 +98,15 @@ // Accessors for load-time performance measurement estimates. // If |num_datum| is zero, there's no estimate available. - const ExponentialMovingAverage& load_duration() const { + const performance_manager::ExponentialMovingAverage& load_duration() const { return load_duration_; } - const ExponentialMovingAverage& cpu_usage_estimate() const { + const performance_manager::ExponentialMovingAverage& cpu_usage_estimate() + const { return cpu_usage_estimate_; } - const ExponentialMovingAverage& private_footprint_kb_estimate() const { + const performance_manager::ExponentialMovingAverage& + private_footprint_kb_estimate() const { return private_footprint_kb_estimate_; } @@ -210,8 +212,9 @@ void ClearObservationsAndInvalidateReadOperation(); // Returns the usage of |site_feature| for this site. - SiteFeatureUsage GetFeatureUsage(const SiteDataFeatureProto& feature_proto, - const base::TimeDelta min_obs_time) const; + performance_manager::SiteFeatureUsage GetFeatureUsage( + const SiteDataFeatureProto& feature_proto, + const base::TimeDelta min_obs_time) const; // Helper function to update a given |SiteDataFeatureProto| when a // feature gets used. @@ -242,9 +245,11 @@ SiteDataProto site_characteristics_; // The in-memory storage for the moving performance averages. - ExponentialMovingAverage load_duration_; // microseconds. - ExponentialMovingAverage cpu_usage_estimate_; // microseconds. - ExponentialMovingAverage private_footprint_kb_estimate_; + performance_manager::ExponentialMovingAverage + load_duration_; // microseconds. + performance_manager::ExponentialMovingAverage + cpu_usage_estimate_; // microseconds. + performance_manager::ExponentialMovingAverage private_footprint_kb_estimate_; // This site's origin. const url::Origin origin_;
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_impl_unittest.cc b/chrome/browser/resource_coordinator/local_site_characteristics_data_impl_unittest.cc index 41f9492..0e4076d 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_data_impl_unittest.cc +++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_impl_unittest.cc
@@ -8,6 +8,7 @@ #include "base/memory/ref_counted.h" #include "base/test/bind_test_util.h" #include "base/test/simple_test_tick_clock.h" +#include "chrome/browser/performance_manager/persistence/site_data/feature_usage.h" #include "chrome/browser/resource_coordinator/local_site_characteristics_data_unittest_utils.h" #include "chrome/browser/resource_coordinator/time.h" #include "testing/gmock/include/gmock/gmock.h" @@ -158,7 +159,7 @@ local_site_data->NotifyLoadedSiteBackgrounded(); // Initially the feature usage should be reported as unknown. - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, local_site_data->UsesAudioInBackground()); // Advance the clock by a time lower than the miniumum observation time for @@ -169,12 +170,12 @@ // The audio feature usage is still unknown as the observation window hasn't // expired. - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, local_site_data->UsesAudioInBackground()); // Report that the audio feature has been used. local_site_data->NotifyUsesAudioInBackground(); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, local_site_data->UsesAudioInBackground()); // When a feature is in use it's expected that its recorded observation @@ -193,17 +194,18 @@ // reported as unused. test_clock_.Advance(GetStaticSiteCharacteristicsDatabaseParams() .notifications_usage_observation_window); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureNotInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureNotInUse, local_site_data->UsesNotificationsInBackground()); // Observating that a feature has been used after its observation window has // expired should still be recorded, the feature should then be reported as // used. local_site_data->NotifyUsesNotificationsInBackground(); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, local_site_data->UsesNotificationsInBackground()); - local_site_data->NotifySiteUnloaded(TabVisibility::kBackground); + local_site_data->NotifySiteUnloaded( + performance_manager::TabVisibility::kBackground); } TEST_F(LocalSiteCharacteristicsDataImplTest, LastLoadedTime) { @@ -228,12 +230,14 @@ // Unloading the site shouldn't update the last loaded time as there's still // a loaded instance. - local_site_data2->NotifySiteUnloaded(TabVisibility::kForeground); + local_site_data2->NotifySiteUnloaded( + performance_manager::TabVisibility::kForeground); EXPECT_EQ(last_loaded_time, local_site_data->last_loaded_time_for_testing()); test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - local_site_data->NotifySiteUnloaded(TabVisibility::kForeground); + local_site_data->NotifySiteUnloaded( + performance_manager::TabVisibility::kForeground); EXPECT_NE(last_loaded_time, local_site_data->last_loaded_time_for_testing()); } @@ -248,9 +252,9 @@ test_clock_.Advance(GetStaticSiteCharacteristicsDatabaseParams() .notifications_usage_observation_window - base::TimeDelta::FromSeconds(1)); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, local_site_data->UsesAudioInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, local_site_data->UsesNotificationsInBackground()); const base::TimeDelta observation_duration_before_unload = @@ -258,12 +262,13 @@ local_site_data->site_characteristics_for_testing() .uses_notifications_in_background()); - local_site_data->NotifySiteUnloaded(TabVisibility::kBackground); + local_site_data->NotifySiteUnloaded( + performance_manager::TabVisibility::kBackground); // Once unloaded the feature observations should still be accessible. - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, local_site_data->UsesAudioInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, local_site_data->UsesNotificationsInBackground()); // Advancing the clock shouldn't affect the observation duration for this @@ -273,7 +278,7 @@ local_site_data->FeatureObservationDuration( local_site_data->site_characteristics_for_testing() .uses_notifications_in_background())); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, local_site_data->UsesNotificationsInBackground()); local_site_data->NotifySiteLoaded(); @@ -281,12 +286,13 @@ test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, local_site_data->UsesAudioInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureNotInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureNotInUse, local_site_data->UsesNotificationsInBackground()); - local_site_data->NotifySiteUnloaded(TabVisibility::kBackground); + local_site_data->NotifySiteUnloaded( + performance_manager::TabVisibility::kBackground); } TEST_F(LocalSiteCharacteristicsDataImplTest, AllDurationGetSavedOnUnload) { @@ -314,7 +320,8 @@ // Makes use of a feature to make sure that the observation timestamps get // saved. local_site_data->NotifyUsesAudioInBackground(); - local_site_data->NotifySiteUnloaded(TabVisibility::kBackground); + local_site_data->NotifySiteUnloaded( + performance_manager::TabVisibility::kBackground); SiteDataProto expected_proto; @@ -385,19 +392,20 @@ local_site_data->NotifySiteLoaded(); local_site_data->NotifyLoadedSiteBackgrounded(); local_site_data->NotifyUsesAudioInBackground(); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, local_site_data->UsesAudioInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, local_site_data->UsesNotificationsInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, local_site_data->UpdatesFaviconInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, local_site_data->UpdatesTitleInBackground()); // Unload the site and save the last loaded time to make sure the // initialization doesn't overwrite it. test_clock_.Advance(base::TimeDelta::FromSeconds(1)); - local_site_data->NotifySiteUnloaded(TabVisibility::kBackground); + local_site_data->NotifySiteUnloaded( + performance_manager::TabVisibility::kBackground); test_clock_.Advance(base::TimeDelta::FromSeconds(1)); auto last_loaded = local_site_data->last_loaded_time_for_testing(); @@ -460,13 +468,13 @@ // Run the callback to indicate that the initialization has completed. std::move(read_cb).Run(test_proto); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, local_site_data->UsesAudioInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, local_site_data->UpdatesTitleInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, local_site_data->UpdatesFaviconInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, local_site_data->UsesNotificationsInBackground()); EXPECT_EQ(last_loaded, local_site_data->last_loaded_time_for_testing()); @@ -516,10 +524,11 @@ local_site_data_writer->NotifySiteLoaded(); local_site_data_writer->NotifyLoadedSiteBackgrounded(); local_site_data_writer->NotifyUsesAudioInBackground(); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, local_site_data_writer->UsesAudioInBackground()); - local_site_data_writer->NotifySiteUnloaded(TabVisibility::kBackground); + local_site_data_writer->NotifySiteUnloaded( + performance_manager::TabVisibility::kBackground); // Releasing |local_site_data_writer| should cause this object to get // destroyed but there shouldn't be any write operation as the read hasn't @@ -548,9 +557,10 @@ local_site_data->NotifySiteLoaded(); local_site_data->NotifyLoadedSiteBackgrounded(); local_site_data->NotifyUsesAudioInBackground(); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, local_site_data->UsesAudioInBackground()); - local_site_data->NotifySiteUnloaded(TabVisibility::kBackground); + local_site_data->NotifySiteUnloaded( + performance_manager::TabVisibility::kBackground); // TODO(sebmarchand): Test that data is cleared here. local_site_data->ClearObservationsAndInvalidateReadOperation(); @@ -609,8 +619,10 @@ local_site_data->background_session_begin_for_testing(); EXPECT_EQ(test_clock_.NowTicks(), background_session_begin); - local_site_data->NotifySiteUnloaded(TabVisibility::kBackground); - local_site_data_copy->NotifySiteUnloaded(TabVisibility::kForeground); + local_site_data->NotifySiteUnloaded( + performance_manager::TabVisibility::kBackground); + local_site_data_copy->NotifySiteUnloaded( + performance_manager::TabVisibility::kForeground); } TEST_F(LocalSiteCharacteristicsDataImplTest, @@ -647,7 +659,8 @@ ASSERT_FALSE(proto.has_load_time_estimates()); })); - local_site_data->NotifySiteUnloaded(TabVisibility::kBackground); + local_site_data->NotifySiteUnloaded( + performance_manager::TabVisibility::kBackground); local_site_data = nullptr; ::testing::Mock::VerifyAndClear(&mock_db); } @@ -690,8 +703,10 @@ local_site_data_ref->site_characteristics_for_testing() .updates_title_in_background())); - local_site_data->NotifySiteUnloaded(TabVisibility::kBackground); - local_site_data_ref->NotifySiteUnloaded(TabVisibility::kBackground); + local_site_data->NotifySiteUnloaded( + performance_manager::TabVisibility::kBackground); + local_site_data_ref->NotifySiteUnloaded( + performance_manager::TabVisibility::kBackground); } TEST_F(LocalSiteCharacteristicsDataImplTest, DataLoadedCallbackInvoked) {
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_reader.cc b/chrome/browser/resource_coordinator/local_site_characteristics_data_reader.cc index 17837fe..f04a723 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_data_reader.cc +++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_reader.cc
@@ -17,22 +17,22 @@ LocalSiteCharacteristicsDataReader::~LocalSiteCharacteristicsDataReader() {} -SiteFeatureUsage +performance_manager::SiteFeatureUsage LocalSiteCharacteristicsDataReader::UpdatesFaviconInBackground() const { return impl_->UpdatesFaviconInBackground(); } -SiteFeatureUsage LocalSiteCharacteristicsDataReader::UpdatesTitleInBackground() - const { +performance_manager::SiteFeatureUsage +LocalSiteCharacteristicsDataReader::UpdatesTitleInBackground() const { return impl_->UpdatesTitleInBackground(); } -SiteFeatureUsage LocalSiteCharacteristicsDataReader::UsesAudioInBackground() - const { +performance_manager::SiteFeatureUsage +LocalSiteCharacteristicsDataReader::UsesAudioInBackground() const { return impl_->UsesAudioInBackground(); } -SiteFeatureUsage +performance_manager::SiteFeatureUsage LocalSiteCharacteristicsDataReader::UsesNotificationsInBackground() const { return impl_->UsesNotificationsInBackground(); }
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_reader.h b/chrome/browser/resource_coordinator/local_site_characteristics_data_reader.h index 43d2a62..056e4b14 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_data_reader.h +++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_reader.h
@@ -28,10 +28,13 @@ ~LocalSiteCharacteristicsDataReader() override; // SiteCharacteristicsDataReader: - SiteFeatureUsage UpdatesFaviconInBackground() const override; - SiteFeatureUsage UpdatesTitleInBackground() const override; - SiteFeatureUsage UsesAudioInBackground() const override; - SiteFeatureUsage UsesNotificationsInBackground() const override; + performance_manager::SiteFeatureUsage UpdatesFaviconInBackground() + const override; + performance_manager::SiteFeatureUsage UpdatesTitleInBackground() + const override; + performance_manager::SiteFeatureUsage UsesAudioInBackground() const override; + performance_manager::SiteFeatureUsage UsesNotificationsInBackground() + const override; bool DataLoaded() const override; void RegisterDataLoadedCallback(base::OnceClosure&& callback) override;
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_reader_unittest.cc b/chrome/browser/resource_coordinator/local_site_characteristics_data_reader_unittest.cc index b406a3d..6e85c661 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_data_reader_unittest.cc +++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_reader_unittest.cc
@@ -88,7 +88,8 @@ } ~LocalSiteCharacteristicsDataReaderTest() override { - test_impl_->NotifySiteUnloaded(TabVisibility::kBackground); + test_impl_->NotifySiteUnloaded( + performance_manager::TabVisibility::kBackground); } base::SimpleTestTickClock test_clock_; @@ -115,32 +116,32 @@ TEST_F(LocalSiteCharacteristicsDataReaderTest, TestAccessors) { // Initially we have no information about any of the features. - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, reader_->UpdatesFaviconInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, reader_->UpdatesTitleInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, reader_->UsesAudioInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, reader_->UsesNotificationsInBackground()); // Simulates a title update event, make sure it gets reported directly. test_impl_->NotifyUpdatesTitleInBackground(); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, reader_->UpdatesTitleInBackground()); // Advance the clock by a large amount of time, enough for the unused features // observation windows to expire. test_clock_.Advance(base::TimeDelta::FromDays(31)); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureNotInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureNotInUse, reader_->UpdatesFaviconInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, reader_->UpdatesTitleInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureNotInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureNotInUse, reader_->UsesAudioInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureNotInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureNotInUse, reader_->UsesNotificationsInBackground()); }
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_store.cc b/chrome/browser/resource_coordinator/local_site_characteristics_data_store.cc index d379825..508196e 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_data_store.cc +++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_store.cc
@@ -67,7 +67,7 @@ std::unique_ptr<SiteCharacteristicsDataWriter> LocalSiteCharacteristicsDataStore::GetWriterForOrigin( const url::Origin& origin, - TabVisibility tab_visibility) { + performance_manager::TabVisibility tab_visibility) { internal::LocalSiteCharacteristicsDataImpl* impl = GetOrCreateFeatureImpl(origin); DCHECK(impl);
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_store.h b/chrome/browser/resource_coordinator/local_site_characteristics_data_store.h index a238962..913a82f6 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_data_store.h +++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_store.h
@@ -44,7 +44,7 @@ const url::Origin& origin) override; std::unique_ptr<SiteCharacteristicsDataWriter> GetWriterForOrigin( const url::Origin& origin, - TabVisibility tab_visibility) override; + performance_manager::TabVisibility tab_visibility) override; bool IsRecordingForTesting() override; const LocalSiteCharacteristicsMap& origin_data_map_for_testing() const {
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_store_unittest.cc b/chrome/browser/resource_coordinator/local_site_characteristics_data_store_unittest.cc index 246e8547..bd29874 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_data_store_unittest.cc +++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_store_unittest.cc
@@ -79,8 +79,8 @@ EXPECT_TRUE(reader_); ASSERT_FALSE(writer_); - writer_ = data_store_->GetWriterForOrigin(kTestOrigin, - TabVisibility::kBackground); + writer_ = data_store_->GetWriterForOrigin( + kTestOrigin, performance_manager::TabVisibility::kBackground); EXPECT_TRUE(writer_); ASSERT_FALSE(data_); @@ -88,11 +88,11 @@ data_store_->origin_data_map_for_testing().find(kTestOrigin)->second; EXPECT_TRUE(data_); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, reader_->UpdatesTitleInBackground()); writer_->NotifySiteLoaded(); writer_->NotifyUpdatesTitleInBackground(); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, reader_->UpdatesTitleInBackground()); test_clock_.Advance(kDelay); @@ -102,8 +102,8 @@ EXPECT_TRUE(reader2_); ASSERT_FALSE(writer2_); - writer2_ = data_store_->GetWriterForOrigin(kTestOrigin2, - TabVisibility::kBackground); + writer2_ = data_store_->GetWriterForOrigin( + kTestOrigin2, performance_manager::TabVisibility::kBackground); EXPECT_TRUE(writer2_); ASSERT_FALSE(data2_); @@ -111,11 +111,11 @@ data_store_->origin_data_map_for_testing().find(kTestOrigin2)->second; EXPECT_TRUE(data2_); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, reader2_->UpdatesFaviconInBackground()); writer2_->NotifySiteLoaded(); writer2_->NotifyUpdatesFaviconInBackground(); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, reader2_->UpdatesFaviconInBackground()); test_clock_.Advance(kDelay); } @@ -143,20 +143,20 @@ TEST_F(LocalSiteCharacteristicsDataStoreTest, EndToEnd) { auto reader = data_store_->GetReaderForOrigin(kTestOrigin); EXPECT_TRUE(reader); - auto writer = - data_store_->GetWriterForOrigin(kTestOrigin, TabVisibility::kBackground); + auto writer = data_store_->GetWriterForOrigin( + kTestOrigin, performance_manager::TabVisibility::kBackground); EXPECT_TRUE(writer); EXPECT_EQ(1U, data_store_->origin_data_map_for_testing().size()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, reader->UpdatesTitleInBackground()); writer->NotifySiteLoaded(); writer->NotifyUpdatesTitleInBackground(); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, reader->UpdatesTitleInBackground()); writer->NotifySiteUnloaded(); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, reader->UpdatesTitleInBackground()); auto reader_copy = data_store_->GetReaderForOrigin(kTestOrigin); @@ -209,12 +209,12 @@ // loaded time should be equal to the current time. EXPECT_EQ(data_->last_loaded_time_for_testing(), test_clock_.NowTicks() - base::TimeTicks::UnixEpoch()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, reader_->UpdatesTitleInBackground()); // The second site shouldn't have been cleared. EXPECT_EQ(data2_->last_loaded_time_for_testing(), last_loaded_time2_before_urls_deleted); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, reader2_->UpdatesFaviconInBackground()); writer_->NotifySiteUnloaded(); @@ -251,11 +251,11 @@ // Sites shouldn't have been cleared. EXPECT_EQ(data_->last_loaded_time_for_testing(), last_loaded_time_before_urls_deleted); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, reader_->UpdatesTitleInBackground()); EXPECT_EQ(data2_->last_loaded_time_for_testing(), last_loaded_time2_before_urls_deleted); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, reader2_->UpdatesFaviconInBackground()); writer_->NotifySiteUnloaded(); @@ -275,11 +275,11 @@ // The information for both sites should have been cleared. EXPECT_EQ(data_->last_loaded_time_for_testing(), test_clock_.NowTicks() - base::TimeTicks::UnixEpoch()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, reader_->UpdatesTitleInBackground()); EXPECT_EQ(data2_->last_loaded_time_for_testing(), test_clock_.NowTicks() - base::TimeTicks::UnixEpoch()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, reader2_->UpdatesFaviconInBackground()); writer_->NotifySiteUnloaded(); @@ -306,8 +306,8 @@ { // Add an entry, see that it's reflected in the inspector interface. - auto writer = data_store_->GetWriterForOrigin(kTestOrigin, - TabVisibility::kBackground); + auto writer = data_store_->GetWriterForOrigin( + kTestOrigin, performance_manager::TabVisibility::kBackground); EXPECT_EQ(1U, inspector->GetAllInMemoryOrigins().size()); EXPECT_TRUE(inspector->GetDataForOrigin(kTestOrigin, &is_dirty, &data));
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_writer.cc b/chrome/browser/resource_coordinator/local_site_characteristics_data_writer.cc index 0942147e..769930d 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_data_writer.cc +++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_writer.cc
@@ -19,7 +19,7 @@ is_loaded_ = true; impl_->NotifySiteLoaded(); - if (tab_visibility_ == TabVisibility::kBackground) + if (tab_visibility_ == performance_manager::TabVisibility::kBackground) impl_->NotifyLoadedSiteBackgrounded(); } @@ -33,7 +33,7 @@ } void LocalSiteCharacteristicsDataWriter::NotifySiteVisibilityChanged( - TabVisibility visibility) { + performance_manager::TabVisibility visibility) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Ignore this if we receive the same event multiple times. @@ -43,7 +43,7 @@ tab_visibility_ = visibility; if (is_loaded_) { - if (visibility == TabVisibility::kBackground) { + if (visibility == performance_manager::TabVisibility::kBackground) { impl_->NotifyLoadedSiteBackgrounded(); } else { impl_->NotifyLoadedSiteForegrounded(); @@ -53,19 +53,19 @@ void LocalSiteCharacteristicsDataWriter::NotifyUpdatesFaviconInBackground() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK_EQ(TabVisibility::kBackground, tab_visibility_); + DCHECK_EQ(performance_manager::TabVisibility::kBackground, tab_visibility_); impl_->NotifyUpdatesFaviconInBackground(); } void LocalSiteCharacteristicsDataWriter::NotifyUpdatesTitleInBackground() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK_EQ(TabVisibility::kBackground, tab_visibility_); + DCHECK_EQ(performance_manager::TabVisibility::kBackground, tab_visibility_); impl_->NotifyUpdatesTitleInBackground(); } void LocalSiteCharacteristicsDataWriter::NotifyUsesAudioInBackground() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK_EQ(TabVisibility::kBackground, tab_visibility_); + DCHECK_EQ(performance_manager::TabVisibility::kBackground, tab_visibility_); // TODO(sebmarchand): Do not advance the background audio observation time // when the WebContents has never played audio. impl_->NotifyUsesAudioInBackground(); @@ -73,7 +73,7 @@ void LocalSiteCharacteristicsDataWriter::NotifyUsesNotificationsInBackground() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK_EQ(TabVisibility::kBackground, tab_visibility_); + DCHECK_EQ(performance_manager::TabVisibility::kBackground, tab_visibility_); impl_->NotifyUsesNotificationsInBackground(); } @@ -88,7 +88,7 @@ LocalSiteCharacteristicsDataWriter::LocalSiteCharacteristicsDataWriter( scoped_refptr<internal::LocalSiteCharacteristicsDataImpl> impl, - TabVisibility tab_visibility) + performance_manager::TabVisibility tab_visibility) : impl_(std::move(impl)), tab_visibility_(tab_visibility), is_loaded_(false) {
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_writer.h b/chrome/browser/resource_coordinator/local_site_characteristics_data_writer.h index 2edeef80..5d9d42fce 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_data_writer.h +++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_writer.h
@@ -25,7 +25,8 @@ // SiteCharacteristicsDataWriter: void NotifySiteLoaded() override; void NotifySiteUnloaded() override; - void NotifySiteVisibilityChanged(TabVisibility visibility) override; + void NotifySiteVisibilityChanged( + performance_manager::TabVisibility visibility) override; void NotifyUpdatesFaviconInBackground() override; void NotifyUpdatesTitleInBackground() override; void NotifyUsesAudioInBackground() override; @@ -48,13 +49,13 @@ // characteristics data store. LocalSiteCharacteristicsDataWriter( scoped_refptr<internal::LocalSiteCharacteristicsDataImpl> impl, - TabVisibility tab_visibility); + performance_manager::TabVisibility tab_visibility); // The LocalSiteCharacteristicDataInternal object we delegate to. const scoped_refptr<internal::LocalSiteCharacteristicsDataImpl> impl_; // The visibility of the tab using this writer. - TabVisibility tab_visibility_; + performance_manager::TabVisibility tab_visibility_; // Indicates if the tab using this writer is loaded. bool is_loaded_;
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_writer_unittest.cc b/chrome/browser/resource_coordinator/local_site_characteristics_data_writer_unittest.cc index 7368cf9..8f1d450 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_data_writer_unittest.cc +++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_writer_unittest.cc
@@ -7,9 +7,9 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/time/time.h" +#include "chrome/browser/performance_manager/persistence/site_data/feature_usage.h" #include "chrome/browser/resource_coordinator/local_site_characteristics_data_impl.h" #include "chrome/browser/resource_coordinator/local_site_characteristics_data_unittest_utils.h" -#include "chrome/browser/resource_coordinator/local_site_characteristics_feature_usage.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -28,8 +28,8 @@ &delegate_, &database_))) { LocalSiteCharacteristicsDataWriter* writer = - new LocalSiteCharacteristicsDataWriter(test_impl_.get(), - TabVisibility::kBackground); + new LocalSiteCharacteristicsDataWriter( + test_impl_.get(), performance_manager::TabVisibility::kBackground); writer_ = base::WrapUnique(writer); } @@ -63,13 +63,13 @@ TEST_F(LocalSiteCharacteristicsDataWriterTest, TestModifiers) { // Make sure that we initially have no information about any of the features // and that the site is in an unloaded state. - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, test_impl_->UpdatesFaviconInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, test_impl_->UpdatesTitleInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, test_impl_->UsesAudioInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, test_impl_->UsesNotificationsInBackground()); // Test the OnTabLoaded function. @@ -80,43 +80,43 @@ // Test all the modifiers. writer_->NotifyUpdatesFaviconInBackground(); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, test_impl_->UpdatesFaviconInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, test_impl_->UpdatesTitleInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, test_impl_->UsesAudioInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, test_impl_->UsesNotificationsInBackground()); writer_->NotifyUpdatesTitleInBackground(); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, test_impl_->UpdatesFaviconInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, test_impl_->UpdatesTitleInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, test_impl_->UsesAudioInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, test_impl_->UsesNotificationsInBackground()); writer_->NotifyUsesAudioInBackground(); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, test_impl_->UpdatesFaviconInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, test_impl_->UpdatesTitleInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, test_impl_->UsesAudioInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, test_impl_->UsesNotificationsInBackground()); writer_->NotifyUsesNotificationsInBackground(); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, test_impl_->UpdatesFaviconInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, test_impl_->UpdatesTitleInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, test_impl_->UsesAudioInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, test_impl_->UsesNotificationsInBackground()); writer_->NotifyLoadTimePerformanceMeasurement( @@ -181,7 +181,8 @@ EXPECT_TRUE(TabIsLoadedAndInBackground()); // Transition #8: Loaded + Bg -> Loaded + Fg. - writer_->NotifySiteVisibilityChanged(TabVisibility::kForeground); + writer_->NotifySiteVisibilityChanged( + performance_manager::TabVisibility::kForeground); EXPECT_TRUE(TabIsLoaded()); EXPECT_FALSE(TabIsLoadedAndInBackground()); @@ -190,11 +191,13 @@ EXPECT_FALSE(TabIsLoaded()); // Transition #1: Unloaded + Fg -> Unloaded + Bg. - writer_->NotifySiteVisibilityChanged(TabVisibility::kBackground); + writer_->NotifySiteVisibilityChanged( + performance_manager::TabVisibility::kBackground); EXPECT_FALSE(TabIsLoaded()); // Transition #2: Unloaded + Bg -> Unloaded + Fg. - writer_->NotifySiteVisibilityChanged(TabVisibility::kForeground); + writer_->NotifySiteVisibilityChanged( + performance_manager::TabVisibility::kForeground); EXPECT_FALSE(TabIsLoaded()); // Transition #6: Unloaded + Fg -> Loaded + Fg. @@ -203,7 +206,8 @@ EXPECT_FALSE(TabIsLoadedAndInBackground()); // Transition #7: Loaded + Fg -> Loaded + Bg. - writer_->NotifySiteVisibilityChanged(TabVisibility::kBackground); + writer_->NotifySiteVisibilityChanged( + performance_manager::TabVisibility::kBackground); EXPECT_TRUE(TabIsLoaded()); EXPECT_TRUE(TabIsLoadedAndInBackground());
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_database_browsertest.cc b/chrome/browser/resource_coordinator/local_site_characteristics_database_browsertest.cc index 2bcb284..ea0b03f 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_database_browsertest.cc +++ b/chrome/browser/resource_coordinator/local_site_characteristics_database_browsertest.cc
@@ -160,7 +160,7 @@ // closure that should run before testing the feature usage (to allow it to // be used). void TestFeatureUsageDetection( - SiteFeatureUsage ( + performance_manager::SiteFeatureUsage ( SiteCharacteristicsDataReader::*feature_detection_method)() const, base::RepeatingClosure triggering_closure, base::RepeatingClosure allowing_closure = base::DoNothing::Repeatedly()) { @@ -243,7 +243,7 @@ private: void TestFeatureUsageDetectionImpl( - SiteFeatureUsage ( + performance_manager::SiteFeatureUsage ( SiteCharacteristicsDataReader::*feature_detection_method)() const, base::OnceClosure allowing_closure, base::RepeatingClosure triggering_closure, @@ -258,7 +258,7 @@ }; void LocalSiteCharacteristicsDatabaseTest::TestFeatureUsageDetectionImpl( - SiteFeatureUsage ( + performance_manager::SiteFeatureUsage ( SiteCharacteristicsDataReader::*feature_detection_method)() const, base::OnceClosure allowing_closure, base::RepeatingClosure triggering_closure, @@ -272,7 +272,7 @@ // Get the reader for this origin. auto reader = GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url)); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, (reader.get()->*feature_detection_method)()); // Navigate to the test url and background it. @@ -285,7 +285,7 @@ // If needed, wait for all feature observation windows to expire. if (wait_for_observation_window_to_expire) { test_clock_.Advance(GetLongestObservationWindow()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureNotInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureNotInUse, (reader.get()->*feature_detection_method)()); } @@ -295,10 +295,10 @@ // Ensure that the closure hasn't caused the feature usage status to // change. if (wait_for_observation_window_to_expire) { - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureNotInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureNotInUse, (reader.get()->*feature_detection_method)()); } else { - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, (reader.get()->*feature_detection_method)()); } @@ -306,7 +306,7 @@ triggering_closure.Run(); while ((reader.get()->*feature_detection_method)() != - SiteFeatureUsage::kSiteFeatureInUse) { + performance_manager::SiteFeatureUsage::kSiteFeatureInUse) { base::RunLoop().RunUntilIdle(); } @@ -314,7 +314,7 @@ // change. test_clock_.Advance(GetLongestObservationWindow()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, (reader.get()->*feature_detection_method)()); } @@ -333,24 +333,24 @@ auto reader = GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url)); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, reader->UpdatesFaviconInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, reader->UpdatesTitleInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, reader->UsesAudioInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, reader->UsesNotificationsInBackground()); test_clock().Advance(GetLongestObservationWindow()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureNotInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureNotInUse, reader->UpdatesFaviconInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureNotInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureNotInUse, reader->UpdatesTitleInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureNotInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureNotInUse, reader->UsesAudioInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureNotInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureNotInUse, reader->UsesNotificationsInBackground()); } @@ -372,21 +372,21 @@ auto reader = GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url)); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, reader->UpdatesFaviconInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, reader->UpdatesTitleInBackground()); // Advance the clock while the tab is still in foreground and make sure that // the state hasn't changed. test_clock().Advance(GetLongestObservationWindow()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, reader->UpdatesFaviconInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, reader->UpdatesTitleInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, reader->UsesAudioInBackground()); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, reader->UsesNotificationsInBackground()); } @@ -509,7 +509,7 @@ // Get the reader for this origin. auto reader = GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url)); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, reader->UpdatesTitleInBackground()); // Navigate to the test url and background it. @@ -525,7 +525,7 @@ ChangeTitleOfActiveWebContents(); while (reader->UpdatesTitleInBackground() != - SiteFeatureUsage::kSiteFeatureInUse) { + performance_manager::SiteFeatureUsage::kSiteFeatureInUse) { base::RunLoop().RunUntilIdle(); } } @@ -539,7 +539,7 @@ GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url)); // We should remember the observation made previously. - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, reader->UpdatesTitleInBackground()); } @@ -550,7 +550,7 @@ // Get the reader for this origin. auto reader = GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url)); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, reader->UpdatesTitleInBackground()); // Navigate to the test url and background it. @@ -566,7 +566,7 @@ ChangeTitleOfActiveWebContents(); while (reader->UpdatesTitleInBackground() != - SiteFeatureUsage::kSiteFeatureInUse) { + performance_manager::SiteFeatureUsage::kSiteFeatureInUse) { base::RunLoop().RunUntilIdle(); } @@ -575,7 +575,7 @@ ->DeleteURL(test_url); // The history gets cleared asynchronously. while (reader->UpdatesTitleInBackground() != - SiteFeatureUsage::kSiteFeatureUsageUnknown) { + performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown) { base::RunLoop().RunUntilIdle(); } } @@ -588,7 +588,7 @@ GetReaderForOrigin(browser()->profile(), url::Origin::Create(test_url)); // The history has been cleared, we shouldn't know if this feature is used. - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, reader->UpdatesTitleInBackground()); }
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_feature_usage.h b/chrome/browser/resource_coordinator/local_site_characteristics_feature_usage.h deleted file mode 100644 index d2f34182..0000000 --- a/chrome/browser/resource_coordinator/local_site_characteristics_feature_usage.h +++ /dev/null
@@ -1,20 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_RESOURCE_COORDINATOR_LOCAL_SITE_CHARACTERISTICS_FEATURE_USAGE_H_ -#define CHROME_BROWSER_RESOURCE_COORDINATOR_LOCAL_SITE_CHARACTERISTICS_FEATURE_USAGE_H_ - -namespace resource_coordinator { - -// A tri-state return value for site feature usage. If a definitive decision -// can't be made then an "unknown" result can be returned. -enum class SiteFeatureUsage { - kSiteFeatureNotInUse, - kSiteFeatureInUse, - kSiteFeatureUsageUnknown, -}; - -} // namespace resource_coordinator - -#endif // CHROME_BROWSER_RESOURCE_COORDINATOR_LOCAL_SITE_CHARACTERISTICS_FEATURE_USAGE_H_
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store.cc b/chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store.cc index 9ff1b217..d1e8db3 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store.cc +++ b/chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store.cc
@@ -37,7 +37,7 @@ std::unique_ptr<SiteCharacteristicsDataWriter> LocalSiteCharacteristicsNonRecordingDataStore::GetWriterForOrigin( const url::Origin& origin, - TabVisibility tab_visibility) { + performance_manager::TabVisibility tab_visibility) { // Return a fake data writer. SiteCharacteristicsDataWriter* writer = new LocalSiteCharacteristicsNoopDataWriter();
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store.h b/chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store.h index 602b524..4bed7e4 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store.h +++ b/chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store.h
@@ -37,7 +37,7 @@ const url::Origin& origin) override; std::unique_ptr<SiteCharacteristicsDataWriter> GetWriterForOrigin( const url::Origin& origin, - TabVisibility tab_visibility) override; + performance_manager::TabVisibility tab_visibility) override; bool IsRecordingForTesting() override; // LocalSiteCharacteristicsDataStoreInspector:
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store_unittest.cc b/chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store_unittest.cc index a076bb8..ed4b80fd 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store_unittest.cc +++ b/chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store_unittest.cc
@@ -57,22 +57,22 @@ auto reader = non_recording_data_store_->GetReaderForOrigin(kTestOrigin); EXPECT_TRUE(reader); auto fake_writer = non_recording_data_store_->GetWriterForOrigin( - kTestOrigin, TabVisibility::kBackground); + kTestOrigin, performance_manager::TabVisibility::kBackground); EXPECT_TRUE(fake_writer); auto real_writer = recording_data_store_->GetWriterForOrigin( - kTestOrigin, TabVisibility::kBackground); + kTestOrigin, performance_manager::TabVisibility::kBackground); EXPECT_TRUE(real_writer); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, reader->UpdatesTitleInBackground()); fake_writer->NotifySiteLoaded(); fake_writer->NotifyUpdatesTitleInBackground(); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureUsageUnknown, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureUsageUnknown, reader->UpdatesTitleInBackground()); real_writer->NotifySiteLoaded(); real_writer->NotifyUpdatesTitleInBackground(); - EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse, + EXPECT_EQ(performance_manager::SiteFeatureUsage::kSiteFeatureInUse, reader->UpdatesTitleInBackground()); // These unload events shouldn't be registered, make sure that they aren't by @@ -118,7 +118,7 @@ // Add an entry through the writing data store, see that it's reflected in // the inspector interface. auto writer = recording_data_store_->GetWriterForOrigin( - kTestOrigin, TabVisibility::kBackground); + kTestOrigin, performance_manager::TabVisibility::kBackground); EXPECT_EQ(1U, inspector->GetAllInMemoryOrigins().size()); EXPECT_TRUE(inspector->GetDataForOrigin(kTestOrigin, &is_dirty, &data));
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_noop_data_writer.cc b/chrome/browser/resource_coordinator/local_site_characteristics_noop_data_writer.cc index 36953d6..4693495 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_noop_data_writer.cc +++ b/chrome/browser/resource_coordinator/local_site_characteristics_noop_data_writer.cc
@@ -16,7 +16,7 @@ void LocalSiteCharacteristicsNoopDataWriter::NotifySiteUnloaded() {} void LocalSiteCharacteristicsNoopDataWriter::NotifySiteVisibilityChanged( - TabVisibility visibility) {} + performance_manager::TabVisibility visibility) {} void LocalSiteCharacteristicsNoopDataWriter:: NotifyUpdatesFaviconInBackground() {}
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_noop_data_writer.h b/chrome/browser/resource_coordinator/local_site_characteristics_noop_data_writer.h index 47bc1fb..09255b7 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_noop_data_writer.h +++ b/chrome/browser/resource_coordinator/local_site_characteristics_noop_data_writer.h
@@ -21,7 +21,8 @@ // SiteCharacteristicsDataWriter: void NotifySiteLoaded() override; void NotifySiteUnloaded() override; - void NotifySiteVisibilityChanged(TabVisibility visibility) override; + void NotifySiteVisibilityChanged( + performance_manager::TabVisibility visibility) override; void NotifyUpdatesFaviconInBackground() override; void NotifyUpdatesTitleInBackground() override; void NotifyUsesAudioInBackground() override;
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_webcontents_observer.cc b/chrome/browser/resource_coordinator/local_site_characteristics_webcontents_observer.cc index 51cbd13..f749399 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_webcontents_observer.cc +++ b/chrome/browser/resource_coordinator/local_site_characteristics_webcontents_observer.cc
@@ -26,10 +26,11 @@ using LoadingState = TabLoadTracker::LoadingState; -TabVisibility ContentVisibilityToRCVisibility(content::Visibility visibility) { +performance_manager::TabVisibility ContentVisibilityToRCVisibility( + content::Visibility visibility) { if (visibility == content::Visibility::VISIBLE) - return TabVisibility::kForeground; - return TabVisibility::kBackground; + return performance_manager::TabVisibility::kForeground; + return performance_manager::TabVisibility::kBackground; } } // namespace @@ -248,7 +249,7 @@ // Ignore events if the tab is not in background. if (ContentVisibilityToRCVisibility(web_contents()->GetVisibility()) != - TabVisibility::kBackground) { + performance_manager::TabVisibility::kBackground) { return true; } @@ -289,8 +290,8 @@ } void LocalSiteCharacteristicsWebContentsObserver::UpdateBackgroundedTime( - TabVisibility visibility) { - if (visibility == TabVisibility::kBackground) { + performance_manager::TabVisibility visibility) { + if (visibility == performance_manager::TabVisibility::kBackground) { backgrounded_time_ = NowTicks(); } else { backgrounded_time_ = base::TimeTicks();
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_webcontents_observer.h b/chrome/browser/resource_coordinator/local_site_characteristics_webcontents_observer.h index 630511bc1..458c18a 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_webcontents_observer.h +++ b/chrome/browser/resource_coordinator/local_site_characteristics_webcontents_observer.h
@@ -88,7 +88,7 @@ void OnSiteLoaded(); // Updates |backgrounded_time_| based on |visibility|. - void UpdateBackgroundedTime(TabVisibility visibility); + void UpdateBackgroundedTime(performance_manager::TabVisibility visibility); // The writer that processes the event received by this class. std::unique_ptr<SiteCharacteristicsDataWriter> writer_;
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_webcontents_observer_unittest.cc b/chrome/browser/resource_coordinator/local_site_characteristics_webcontents_observer_unittest.cc index c4be104..864c05c1 100644 --- a/chrome/browser/resource_coordinator/local_site_characteristics_webcontents_observer_unittest.cc +++ b/chrome/browser/resource_coordinator/local_site_characteristics_webcontents_observer_unittest.cc
@@ -34,7 +34,8 @@ MOCK_METHOD0(NotifySiteLoaded, void()); MOCK_METHOD0(NotifySiteUnloaded, void()); - MOCK_METHOD1(NotifySiteVisibilityChanged, void(TabVisibility)); + MOCK_METHOD1(NotifySiteVisibilityChanged, + void(performance_manager::TabVisibility)); MOCK_METHOD0(NotifyUpdatesFaviconInBackground, void()); MOCK_METHOD0(NotifyUpdatesTitleInBackground, void()); MOCK_METHOD0(NotifyUsesAudioInBackground, void()); @@ -64,7 +65,7 @@ } std::unique_ptr<SiteCharacteristicsDataWriter> GetWriterForOrigin( const url::Origin& origin, - TabVisibility tab_visibility) override { + performance_manager::TabVisibility tab_visibility) override { return std::make_unique<MockDataWriter>(origin); } bool IsRecordingForTesting() override { return true; } @@ -184,7 +185,8 @@ TabLoadTracker::Get()->TransitionStateForTesting(web_contents(), LoadingState::LOADED); EXPECT_CALL(*mock_writer, - NotifySiteVisibilityChanged(TabVisibility::kForeground)); + NotifySiteVisibilityChanged( + performance_manager::TabVisibility::kForeground)); EXPECT_CALL(*mock_writer, NotifySiteLoaded()); web_contents()->WasShown(); observer()->OnLoadingStateChange(web_contents(), @@ -204,7 +206,8 @@ ::testing::Mock::VerifyAndClear(mock_writer); EXPECT_CALL(*mock_writer, - NotifySiteVisibilityChanged(TabVisibility::kBackground)); + NotifySiteVisibilityChanged( + performance_manager::TabVisibility::kBackground)); web_contents()->WasHidden(); ::testing::Mock::VerifyAndClear(mock_writer); @@ -230,9 +233,11 @@ // Brievly switch the tab to foreground to reset the last backgrounded time. EXPECT_CALL(*mock_writer, - NotifySiteVisibilityChanged(TabVisibility::kForeground)); + NotifySiteVisibilityChanged( + performance_manager::TabVisibility::kForeground)); EXPECT_CALL(*mock_writer, - NotifySiteVisibilityChanged(TabVisibility::kBackground)); + NotifySiteVisibilityChanged( + performance_manager::TabVisibility::kBackground)); web_contents()->WasShown(); web_contents()->WasHidden(); ::testing::Mock::VerifyAndClear(mock_writer); @@ -263,7 +268,8 @@ LoadingState::LOADING); EXPECT_CALL(*mock_writer, - NotifySiteVisibilityChanged(TabVisibility::kBackground)); + NotifySiteVisibilityChanged( + performance_manager::TabVisibility::kBackground)); web_contents()->WasHidden(); ::testing::Mock::VerifyAndClear(mock_writer); @@ -285,7 +291,8 @@ LoadingState::LOADING); EXPECT_CALL(*mock_writer, - NotifySiteVisibilityChanged(TabVisibility::kBackground)); + NotifySiteVisibilityChanged( + performance_manager::TabVisibility::kBackground)); web_contents()->WasHidden(); ::testing::Mock::VerifyAndClear(mock_writer); @@ -302,14 +309,16 @@ // Test that the visibility events get forwarded to the writer. EXPECT_CALL(*mock_writer, - NotifySiteVisibilityChanged(TabVisibility::kBackground)) + NotifySiteVisibilityChanged( + performance_manager::TabVisibility::kBackground)) .Times(2); observer()->OnVisibilityChanged(content::Visibility::OCCLUDED); observer()->OnVisibilityChanged(content::Visibility::HIDDEN); ::testing::Mock::VerifyAndClear(mock_writer); EXPECT_CALL(*mock_writer, - NotifySiteVisibilityChanged(TabVisibility::kForeground)); + NotifySiteVisibilityChanged( + performance_manager::TabVisibility::kForeground)); observer()->OnVisibilityChanged(content::Visibility::VISIBLE); ::testing::Mock::VerifyAndClear(mock_writer);
diff --git a/chrome/browser/resource_coordinator/session_restore_policy.cc b/chrome/browser/resource_coordinator/session_restore_policy.cc index d0247222..3f92e3d7 100644 --- a/chrome/browser/resource_coordinator/session_restore_policy.cc +++ b/chrome/browser/resource_coordinator/session_restore_policy.cc
@@ -308,7 +308,8 @@ // static void SessionRestorePolicy::SetUsedInBg(TabData* tab_data) { - static const SiteFeatureUsage kInUse = SiteFeatureUsage::kSiteFeatureInUse; + static const performance_manager::SiteFeatureUsage kInUse = + performance_manager::SiteFeatureUsage::kSiteFeatureInUse; auto& reader = tab_data->reader; DCHECK(reader->DataLoaded());
diff --git a/chrome/browser/resource_coordinator/site_characteristics_data_reader.h b/chrome/browser/resource_coordinator/site_characteristics_data_reader.h index cfa8c46..671b5e9 100644 --- a/chrome/browser/resource_coordinator/site_characteristics_data_reader.h +++ b/chrome/browser/resource_coordinator/site_characteristics_data_reader.h
@@ -5,7 +5,7 @@ #ifndef CHROME_BROWSER_RESOURCE_COORDINATOR_SITE_CHARACTERISTICS_DATA_READER_H_ #define CHROME_BROWSER_RESOURCE_COORDINATOR_SITE_CHARACTERISTICS_DATA_READER_H_ -#include "chrome/browser/resource_coordinator/local_site_characteristics_feature_usage.h" +#include "chrome/browser/performance_manager/persistence/site_data/feature_usage.h" #include "base/callback_forward.h" @@ -19,10 +19,14 @@ virtual ~SiteCharacteristicsDataReader() {} // Accessors for the site characteristics usage. - virtual SiteFeatureUsage UpdatesFaviconInBackground() const = 0; - virtual SiteFeatureUsage UpdatesTitleInBackground() const = 0; - virtual SiteFeatureUsage UsesAudioInBackground() const = 0; - virtual SiteFeatureUsage UsesNotificationsInBackground() const = 0; + virtual performance_manager::SiteFeatureUsage UpdatesFaviconInBackground() + const = 0; + virtual performance_manager::SiteFeatureUsage UpdatesTitleInBackground() + const = 0; + virtual performance_manager::SiteFeatureUsage UsesAudioInBackground() + const = 0; + virtual performance_manager::SiteFeatureUsage UsesNotificationsInBackground() + const = 0; // Returns true if this reader is fully initialized and serving the most // authoritative data. This can initially return false as the backing store is
diff --git a/chrome/browser/resource_coordinator/site_characteristics_data_store.h b/chrome/browser/resource_coordinator/site_characteristics_data_store.h index 2050fd7..2345fb8c 100644 --- a/chrome/browser/resource_coordinator/site_characteristics_data_store.h +++ b/chrome/browser/resource_coordinator/site_characteristics_data_store.h
@@ -8,9 +8,9 @@ #include <memory> #include "base/macros.h" +#include "chrome/browser/performance_manager/persistence/site_data/tab_visibility.h" #include "chrome/browser/resource_coordinator/site_characteristics_data_reader.h" #include "chrome/browser/resource_coordinator/site_characteristics_data_writer.h" -#include "chrome/browser/resource_coordinator/site_characteristics_tab_visibility.h" #include "components/keyed_service/core/keyed_service.h" #include "url/origin.h" @@ -33,7 +33,7 @@ // afterwards if the site is loaded. virtual std::unique_ptr<SiteCharacteristicsDataWriter> GetWriterForOrigin( const url::Origin& origin, - TabVisibility tab_visibility) = 0; + performance_manager::TabVisibility tab_visibility) = 0; // Indicate if the SiteCharacteristicsDataWriter served by this data store // actually persist informations.
diff --git a/chrome/browser/resource_coordinator/site_characteristics_data_writer.h b/chrome/browser/resource_coordinator/site_characteristics_data_writer.h index a974e04..62a7da8 100644 --- a/chrome/browser/resource_coordinator/site_characteristics_data_writer.h +++ b/chrome/browser/resource_coordinator/site_characteristics_data_writer.h
@@ -6,7 +6,7 @@ #define CHROME_BROWSER_RESOURCE_COORDINATOR_SITE_CHARACTERISTICS_DATA_WRITER_H_ #include "base/time/time.h" -#include "chrome/browser/resource_coordinator/site_characteristics_tab_visibility.h" +#include "chrome/browser/performance_manager/persistence/site_data/tab_visibility.h" namespace resource_coordinator { @@ -21,7 +21,8 @@ virtual void NotifySiteUnloaded() = 0; // Records visibility change events. - virtual void NotifySiteVisibilityChanged(TabVisibility visibility) = 0; + virtual void NotifySiteVisibilityChanged( + performance_manager::TabVisibility visibility) = 0; // Records feature usage. virtual void NotifyUpdatesFaviconInBackground() = 0;
diff --git a/chrome/browser/resource_coordinator/site_characteristics_tab_visibility.h b/chrome/browser/resource_coordinator/site_characteristics_tab_visibility.h deleted file mode 100644 index e366c8be..0000000 --- a/chrome/browser/resource_coordinator/site_characteristics_tab_visibility.h +++ /dev/null
@@ -1,14 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_RESOURCE_COORDINATOR_SITE_CHARACTERISTICS_TAB_VISIBILITY_H_ -#define CHROME_BROWSER_RESOURCE_COORDINATOR_SITE_CHARACTERISTICS_TAB_VISIBILITY_H_ - -namespace resource_coordinator { - -enum class TabVisibility { kBackground, kForeground }; - -} // namespace resource_coordinator - -#endif // CHROME_BROWSER_RESOURCE_COORDINATOR_SITE_CHARACTERISTICS_TAB_VISIBILITY_H_
diff --git a/chrome/browser/resource_coordinator/tab_helper.cc b/chrome/browser/resource_coordinator/tab_helper.cc index e8e4b48b..68a1c9d 100644 --- a/chrome/browser/resource_coordinator/tab_helper.cc +++ b/chrome/browser/resource_coordinator/tab_helper.cc
@@ -13,7 +13,10 @@ #include "base/strings/string_number_conversions.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/resource_coordinator/lifecycle_unit_state.mojom-shared.h" #include "chrome/browser/resource_coordinator/resource_coordinator_parts.h" +#include "chrome/browser/resource_coordinator/tab_lifecycle_unit_external.h" +#include "chrome/browser/resource_coordinator/tab_lifecycle_unit_source.h" #include "chrome/browser/resource_coordinator/tab_load_tracker.h" #include "chrome/browser/resource_coordinator/tab_memory_metrics_reporter.h" #include "chrome/browser/resource_coordinator/utils.h" @@ -53,6 +56,28 @@ ResourceCoordinatorTabHelper::~ResourceCoordinatorTabHelper() = default; +bool ResourceCoordinatorTabHelper::IsLoaded(content::WebContents* contents) { + if (resource_coordinator::ResourceCoordinatorTabHelper::FromWebContents( + contents)) { + return resource_coordinator::TabLoadTracker::Get()->GetLoadingState( + contents) == ::mojom::LifecycleUnitLoadingState::LOADED; + } + return true; +} + +bool ResourceCoordinatorTabHelper::IsFrozen(content::WebContents* contents) { +#if !defined(OS_ANDROID) + if (resource_coordinator::ResourceCoordinatorTabHelper::FromWebContents( + contents)) { + auto* tab_lifecycle_unit = resource_coordinator::TabLifecycleUnitSource:: + GetTabLifecycleUnitExternal(contents); + if (tab_lifecycle_unit) + return tab_lifecycle_unit->IsFrozen(); + } +#endif + return false; +} + void ResourceCoordinatorTabHelper::DidStartLoading() { TabLoadTracker::Get()->DidStartLoading(web_contents()); }
diff --git a/chrome/browser/resource_coordinator/tab_helper.h b/chrome/browser/resource_coordinator/tab_helper.h index 4fc4e744..ada74f4c 100644 --- a/chrome/browser/resource_coordinator/tab_helper.h +++ b/chrome/browser/resource_coordinator/tab_helper.h
@@ -13,6 +13,7 @@ #include "base/process/kill.h" #include "base/time/time.h" #include "build/build_config.h" +#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" #include "services/metrics/public/cpp/ukm_source_id.h" @@ -28,6 +29,14 @@ public: ~ResourceCoordinatorTabHelper() override; + // Helper function to check if a given WebContents is loaded. Returns true by + // default if there's no TabHelper for this content. + static bool IsLoaded(content::WebContents* contents); + + // Helper function to check if a given WebContents is frozen. Returns false by + // default if there's no TabHelper for this content. + static bool IsFrozen(content::WebContents* contents); + // WebContentsObserver overrides. void DidStartLoading() override; void DidReceiveResponse() override;
diff --git a/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc b/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc index d6b9ee3e..0928a14 100644 --- a/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc +++ b/chrome/browser/resource_coordinator/tab_lifecycle_unit.cc
@@ -180,7 +180,7 @@ } struct FeatureUsageEntry { - SiteFeatureUsage usage; + performance_manager::SiteFeatureUsage usage; DecisionFailureReason failure_reason; }; @@ -200,9 +200,10 @@ const auto* last = features + base::size(features); for (const auto* f = features; f != last; f++) { - if (f->usage == SiteFeatureUsage::kSiteFeatureInUse) { + if (f->usage == performance_manager::SiteFeatureUsage::kSiteFeatureInUse) { details->AddReason(f->failure_reason); - } else if (f->usage == SiteFeatureUsage::kSiteFeatureUsageUnknown) { + } else if (f->usage == performance_manager::SiteFeatureUsage:: + kSiteFeatureUsageUnknown) { insufficient_observation = true; } }
diff --git a/chrome/browser/resource_coordinator/tab_lifecycle_unit_unittest.cc b/chrome/browser/resource_coordinator/tab_lifecycle_unit_unittest.cc index b3d98d8a..c5b7507 100644 --- a/chrome/browser/resource_coordinator/tab_lifecycle_unit_unittest.cc +++ b/chrome/browser/resource_coordinator/tab_lifecycle_unit_unittest.cc
@@ -238,7 +238,7 @@ } testing::GetLocalSiteCharacteristicsDataImplForWC(web_contents_) - ->NotifySiteUnloaded(TabVisibility::kBackground); + ->NotifySiteUnloaded(performance_manager::TabVisibility::kBackground); } TEST_F(TabLifecycleUnitTest, AsTabLifecycleUnitExternal) {
diff --git a/chrome/browser/resource_coordinator/tab_manager_unittest.cc b/chrome/browser/resource_coordinator/tab_manager_unittest.cc index 870937ff..45b3734 100644 --- a/chrome/browser/resource_coordinator/tab_manager_unittest.cc +++ b/chrome/browser/resource_coordinator/tab_manager_unittest.cc
@@ -514,6 +514,7 @@ ->DidStartNavigation(nav_handle1_.get()); EXPECT_TRUE(tab_manager_->IsTabLoadingForTest(contents1_.get())); + EXPECT_FALSE(ResourceCoordinatorTabHelper::IsLoaded(contents1_.get())); EXPECT_FALSE(tab_manager_->IsTabLoadingForTest(contents2_.get())); EXPECT_TRUE(tab_manager_->IsNavigationDelayedForTest(nav_handle2_.get())); @@ -524,6 +525,7 @@ // After tab 1 has finished loading, TabManager starts loading the next tab. EXPECT_FALSE(tab_manager_->IsTabLoadingForTest(contents1_.get())); EXPECT_TRUE(tab_manager_->IsTabLoadingForTest(contents2_.get())); + EXPECT_TRUE(ResourceCoordinatorTabHelper::IsLoaded(contents1_.get())); EXPECT_FALSE(tab_manager_->IsNavigationDelayedForTest(nav_handle2_.get())); } @@ -1402,12 +1404,24 @@ EXPECT_FALSE(IsTabFrozen(tab_strip->GetWebContentsAt(0))); EXPECT_FALSE(IsTabFrozen(tab_strip->GetWebContentsAt(1))); EXPECT_TRUE(IsTabFrozen(tab_strip->GetWebContentsAt(2))); + EXPECT_FALSE( + ResourceCoordinatorTabHelper::IsFrozen(tab_strip->GetWebContentsAt(0))); + EXPECT_FALSE( + ResourceCoordinatorTabHelper::IsFrozen(tab_strip->GetWebContentsAt(1))); + EXPECT_TRUE( + ResourceCoordinatorTabHelper::IsFrozen(tab_strip->GetWebContentsAt(2))); // After half the freeze timeout, the 1st tab should be frozen. task_runner_->FastForwardBy(kFreezeTimeout / 2); EXPECT_TRUE(IsTabFrozen(tab_strip->GetWebContentsAt(0))); EXPECT_FALSE(IsTabFrozen(tab_strip->GetWebContentsAt(1))); EXPECT_TRUE(IsTabFrozen(tab_strip->GetWebContentsAt(2))); + EXPECT_TRUE( + ResourceCoordinatorTabHelper::IsFrozen(tab_strip->GetWebContentsAt(0))); + EXPECT_FALSE( + ResourceCoordinatorTabHelper::IsFrozen(tab_strip->GetWebContentsAt(1))); + EXPECT_TRUE( + ResourceCoordinatorTabHelper::IsFrozen(tab_strip->GetWebContentsAt(2))); tab_strip->CloseAllTabs(); }
diff --git a/chrome/browser/resources/chromeos/BUILD.gn b/chrome/browser/resources/chromeos/BUILD.gn index ff60572..587c3ab 100644 --- a/chrome/browser/resources/chromeos/BUILD.gn +++ b/chrome/browser/resources/chromeos/BUILD.gn
@@ -36,6 +36,7 @@ group("closure_compile") { deps = [ + "add_supervision:closure_compile", "bluetooth_pairing_dialog:closure_compile", "braille_ime:closure_compile", "internet_config_dialog:closure_compile",
diff --git a/chrome/browser/resources/chromeos/add_supervision/BUILD.gn b/chrome/browser/resources/chromeos/add_supervision/BUILD.gn new file mode 100644 index 0000000..ce80af1 --- /dev/null +++ b/chrome/browser/resources/chromeos/add_supervision/BUILD.gn
@@ -0,0 +1,35 @@ +# 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("//third_party/closure_compiler/compile_js.gni") + +js_type_check("closure_compile") { + deps = [ + ":add_supervision", + ":add_supervision_api_server", + ":post_message_api", + ] +} + +js_library("post_message_api") { + deps = [] +} + +js_library("add_supervision_api_server") { + deps = [ + ":post_message_api", + "//chrome/browser/ui/webui/chromeos/add_supervision:mojo_bindings_js_library_for_compile", + ] +} + +js_library("add_supervision") { + deps = [ + ":add_supervision_api_server", + "//ui/webui/resources/js:load_time_data", + ] + externs_list = [ + "$externs_path/chrome_extensions.js", + "$externs_path/webview_tag.js", + ] +}
diff --git a/chrome/browser/resources/chromeos/add_supervision/add_supervision.html b/chrome/browser/resources/chromeos/add_supervision/add_supervision.html new file mode 100644 index 0000000..55ac2da2 --- /dev/null +++ b/chrome/browser/resources/chromeos/add_supervision/add_supervision.html
@@ -0,0 +1,26 @@ +<!doctype html> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> + <head> + <title>$i18n{pageTitle}</title> + <meta charset="utf-8"> + <script src="chrome://resources/js/cr.js"></script> + <script src="chrome://resources/js/assert.js"></script> + <script src="chrome://resources/js/load_time_data.js"></script> + <script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js"></script> + <script src="strings.js"></script> + <script src="chrome/browser/ui/webui/chromeos/add_supervision/add_supervision.mojom-lite.js"></script> + <script src="post_message_api.js"></script> + <script src="add_supervision_api_server.js"></script> + <script src="add_supervision.js"></script> + <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> + <style> + html, + body { + height: 100%; + } + </style> + </head> + <body> + <webview id="webview"></webview> + </body> +</html>
diff --git a/chrome/browser/resources/chromeos/add_supervision/add_supervision.js b/chrome/browser/resources/chromeos/add_supervision/add_supervision.js new file mode 100644 index 0000000..11e91365 --- /dev/null +++ b/chrome/browser/resources/chromeos/add_supervision/add_supervision.js
@@ -0,0 +1,35 @@ +// 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. + +let server = null; +const proxy = addSupervision.mojom.AddSupervisionHandler.getProxy(); + +document.addEventListener('DOMContentLoaded', () => { + proxy.getOAuthToken().then((result) => { + const url = loadTimeData.getString('webviewUrl'); + const eventOriginFilter = loadTimeData.getString('eventOriginFilter'); + const webview = + /** @type {!WebView} */ (document.querySelector('#webview')); + const oauthToken = result.oauthToken; + + // Block any requests to URLs other than one specified + // by eventOriginFilter. + webview.request.onBeforeRequest.addListener(function(details) { + return {cancel: !details.url.startsWith(eventOriginFilter)}; + }, {urls: ['<all_urls>']}, ['blocking']); + + // Add the Authorizaton header, but only for URLs that prefix match the + // eventOrigin filter. + webview.request.onBeforeSendHeaders.addListener(function(details) { + details.requestHeaders.push( + {name: 'Authorization', value: 'Bearer ' + oauthToken}); + return {requestHeaders: details.requestHeaders}; + }, {urls: [eventOriginFilter + '/*']}, ['blocking', 'requestHeaders']); + + webview.src = url; + + // Set up the server. + server = new AddSupervisionAPIServer(webview, url, eventOriginFilter); + }); +});
diff --git a/chrome/browser/resources/chromeos/add_supervision/add_supervision_api_client.js b/chrome/browser/resources/chromeos/add_supervision/add_supervision_api_client.js new file mode 100644 index 0000000..bf71b93 --- /dev/null +++ b/chrome/browser/resources/chromeos/add_supervision/add_supervision_api_client.js
@@ -0,0 +1,21 @@ +// 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. + +const METHOD_LIST = ['logOut', 'getInstalledArcApps', 'uninstallArcApps']; + +/** + * Class that implements the client side of the AddSupervision postMessage API. + * All of the actual functionality is in the superclass. Family Link uses + * its own implementation of this client library to meet their separate + * google dev and deployment processes and standards, so this file serves + * as a reference implementation, and can be used by end-to-end tests of the + * API's behavior. It is not used in the build, but it is included by + * webview-example.html and webview-example2.html, which demonstrate how + * to use the API from an embedded webview. + */ +class AddSupervisionAPIClient extends PostMessageAPIClient { + constructor() { + super(METHOD_LIST); + } +}
diff --git a/chrome/browser/resources/chromeos/add_supervision/add_supervision_api_server.js b/chrome/browser/resources/chromeos/add_supervision/add_supervision_api_server.js new file mode 100644 index 0000000..49fcd5ac0 --- /dev/null +++ b/chrome/browser/resources/chromeos/add_supervision/add_supervision_api_server.js
@@ -0,0 +1,66 @@ +// 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. + +/** + * The methods to expose to the client. + */ +const METHOD_LIST = ['logOut', 'getInstalledArcApps', 'uninstallArcApps']; + +/** + * Class that implements the server side of the AddSupervision postMessage + * API. In the case of this API, the Add Supervision WebUI is the server, and + * the remote website that calls the API is the client. This is the opposite + * of the normal browser/web-server client/server relationship. + */ +class AddSupervisionAPIServer extends PostMessageAPIServer { + /* + * @constructor + * @param {!Element} webviewElement The <webview> element to listen to as a + * client. + * @param {string} targetURL The target URL to use for outgoing messages. + * This should be the same as the URL loaded in the webview. + * @param {string} originURLPrefix The URL prefix to use to filter incoming + * messages via the postMessage API. + */ + constructor(webviewElement, targetURL, originURLPrefix) { + super(webviewElement, METHOD_LIST, targetURL, originURLPrefix); + + this.proxy_ = addSupervision.mojom.AddSupervisionHandler.getProxy(); + + this.registerMethod('logOut', this.logOut.bind(this)); + this.registerMethod( + 'getInstalledArcApps', this.getInstalledArcApps.bind(this)); + this.registerMethod('uninstallArcApps', this.uninstallArcApps.bind(this)); + } + + /** + * Logs out of the device. + * @param {!Array} unused Placeholder unused empty parameter. + * @return {Promise} This promise is never actually resolved. + */ + logOut(unused) { + return this.proxy_.logOut(); + } + + /** + * @param {!Array} unused Placeholder unused empty parameter. + * @return {Promise<{ + * packageNames: !Array<string>, + * }>} a promise whose success result is an array of package names of ARC + * apps installed on the device. + */ + getInstalledArcApps(unused) { + return this.proxy_.getInstalledArcApps(); + } + + /** + * Uninstall the specified ARC apps. + * @param {!Array<!string>} apps List of app package names to uninstall. + * @return {Promise} a promise whose successful result indicates the apps were + * uninstalled. + */ + uninstallArcApps(apps) { + return this.proxy_.uninstallArcApps(apps); + } +}
diff --git a/chrome/browser/resources/chromeos/add_supervision/post_message_api.js b/chrome/browser/resources/chromeos/add_supervision/post_message_api.js new file mode 100644 index 0000000..330716b --- /dev/null +++ b/chrome/browser/resources/chromeos/add_supervision/post_message_api.js
@@ -0,0 +1,260 @@ +// 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. + +/** + * Class that provides the functionality for talking to a client + * over the PostMessageAPI. This should be subclassed and the + * methods provided in methodList should be implemented as methods + * of the subclass. + */ +class PostMessageAPIServer { + constructor(clientElement, methodList, targetURL, messageOriginURLFilter) { + /** + * The Window type element to which this server will listen for messages, + * probably a <webview>, but also could be an <iframe> or a browser window + * object. + * @private @const {!Element} + */ + this.clientElement_ = clientElement; + + /** + * The guest URL embedded in the element above. Used for message targeting. + * This should be same as the URL loaded in the clientElement, i.e. the + * "src" attribute of a <webview>. + * @private @const {!URL} + */ + this.targetURL_ = new URL(targetURL); + + /** + * Incoming messages received from origin URLs without this prefix + * will not be accepted. This should be used to restrict the API access + * to the intended guest content. + * @private @const {!URL} + */ + this.messageOriginURLFilter_ = new URL(messageOriginURLFilter); + + /** + * Map that stores references to the methods implemented by the API. + * @private {!Map<string, Function>} + */ + this.apiFns_ = new Map(); + + // Listen for the embedding element to finish loading, then + // tell it to initialize by sending it a message, which will include + // a handle for it to use to send messages back. + this.clientElement_.addEventListener('contentload', () => { + this.clientElement_.contentWindow.postMessage( + 'init', this.targetURL_.toString()); + }); + + // Listen for events. + window.addEventListener('message', (event) => { + this.onMessage_(event); + }); + } + + /** + * Registers the specified method name with the specified + * function. + * + * @param {!string} methodName name of the method to register. + * @param {!Function} method The function to associate with the name. + */ + registerMethod(methodName, method) { + this.apiFns_.set(methodName, method); + } + + /** + * Determines if the specified origin matches the origin filter. + * @private + * @param {!string} origin The origin URL to match with the filter. + * @return {boolean} whether the specified origin matches the filter. + */ + originMatchesFilter_(origin) { + const originURL = new URL(origin); + + // We allow the pathname portion of the URL to be a prefix filter, + // to permit for different paths communicating with this server. + return originURL.protocol == this.messageOriginURLFilter_.protocol && + originURL.host == this.messageOriginURLFilter_.host && + originURL.pathname.startsWith(this.messageOriginURLFilter_.pathname); + } + + /** + * Handles postMessage events from the client. + * @private + * @param {Event} event The postMessage event to handle. + */ + onMessage_(event) { + if (!this.originMatchesFilter_(event.origin)) { + console.error( + 'Message received from unauthorized origin: ' + event.origin); + return; + } + const fn = event.data.fn; + const args = event.data.args || []; + + if (!this.apiFns_.has(fn)) { + console.error('Unknown function requested: ' + fn); + return; + } + + this.apiFns_.get(fn)(args).then(result => { + this.clientElement_.contentWindow.postMessage( + { + methodId: event.data.methodId, + result: result, + }, + this.targetURL_.toString()); + }); + } +} + +/** + * Class that provides the functionality for talking to a PostMessageAPIServer + * over the postMessage API. This should be subclassed and the methods in the + * server that the client needs to access should be provided in methodList. + */ +class PostMessageAPIClient { + /** + * @param {!Array<string>} methodList The list of methods accessible via the + * client. + * @param {!string} serverOriginURLFilter Only messages from this origin + * will be accepted. + */ + constructor(methodList, serverOriginURLFilter) { + /** + * @private @const {!string} Filter to use to validate + * the origin of received messages. The origin of messages + * must exactly match this value. + */ + this.serverOriginURLFilter_ = serverOriginURLFilter; + + /** + * The parent window. + * @private {Window} + */ + this.parentWindow_ = null; + /* + * @private {number} + */ + this.nextMethodId_ = 0; + /** + * Map of methods awaiting a response. + * @private {!Map} + */ + this.methodsAwaitingResponse_ = new Map; + /** + * Function property that tracks whether client has + * been initialized by the server. + * @private {Function} + */ + this.boundOnInitialize_ = null; + + // Generate the client-callable methods. + this.generateAPIMethods_(methodList); + } + + /* + * Generates methods for the specified method names. + * @private + * @param {!Array<string>} methods The names of the methods. + */ + generateAPIMethods_(methods) { + methods.forEach((method) => { + Object.getPrototypeOf(this)[method] = function(args) { + return this.callApiFn_(method, args); + }; + }); + } + + initialize() { + this.boundOnInitialize_ = this.onInitialize_.bind(this); + // Wait for an init message from the server. + window.addEventListener('message', this.boundOnInitialize_); + } + + // + // Private implementation: + // + + /** + * Handles initialization event sent from the server to establish + * communication. + * @private + * @param {!Event} event An event received when the initialization message is + * sent from the server. + */ + onInitialize_(event) { + if (!this.originMatchesFilter_(event.origin)) { + console.error( + 'Initialization event received from non-authorized origin: ' + + event.origin); + return; + } + this.parentWindow_ = event.source; + window.removeEventListener('message', this.boundOnInitialize_); + this.boundOnInitialize_ = null; + window.addEventListener('message', this.onMessage_.bind(this)); + } + + /** + * Determine if the specified server origin URL matches the origin filter. + * @param {!string} origin The origin URL to match with the filter. + * @return {boolean} whether the specified origin matches the filter. + */ + originMatchesFilter_(origin) { + return origin == this.serverOriginURLFilter_; + } + + /** + * Handles postMessage events sent from the server. + * @param {Event} event An event received from the server via the postMessage + * API. + */ + onMessage_(event) { + if (!this.originMatchesFilter_(event.origin)) { + console.error( + 'Message received from non-authorized origin: ' + event.origin); + return; + } + if (event.source != this.parentWindow_) { + console.error('discarding event whose source is not the parent window'); + return; + } + if (!this.methodsAwaitingResponse_.has(event.data.methodId)) { + console.error('discarding event method is not waiting for a response'); + return; + } + let method = this.methodsAwaitingResponse_.get(event.data.methodId); + this.methodsAwaitingResponse_.delete(event.data.methodId); + method(event.data.result); + } + + /** + * Converts a function call with arguments into a postMessage event + * and sends it to the server via the postMessage API. + * @param {string} fn The function to call. + * @param {!Array<Object>} args The arguments to pass to the function. + * @return {!Promise} A promise capturing the executing of the function. + */ + callApiFn_(fn, args) { + let newMethodId = this.nextMethodId_++; + let promise = new Promise((resolve, reject) => { + if (!this.parentWindow_) { + reject('No parent window defined'); + } + this.parentWindow_.postMessage( + { + methodId: newMethodId, + fn: fn, + args: args, + }, + '*'); + + this.methodsAwaitingResponse_.set(newMethodId, resolve); + }); + return promise; + } +}
diff --git a/chrome/browser/resources/chromeos/add_supervision/webview-example.html b/chrome/browser/resources/chromeos/add_supervision/webview-example.html new file mode 100644 index 0000000..400fe30 --- /dev/null +++ b/chrome/browser/resources/chromeos/add_supervision/webview-example.html
@@ -0,0 +1,70 @@ +<!doctype html> +<head> + <script src="post_message_api.js"></script> + <script src="add_supervision_api_client.js"></script> + <script> + /** @type {AddSupervisionAPIClient} */ + let api = new AddSupervisionAPIClient(); + api.initialize(); + + // + // UI implementation: + // + document.addEventListener('DOMContentLoaded', () => { + const logoutBtn = document.querySelector('#logout'); + + logoutBtn.addEventListener('click', () => { + api.logOut().then(() => { + // This won't get reached. + }, (error) => { + console.error(error.message); + }); + }); + + const getArcAppsBtn = document.querySelector('#get_arc_apps'); + + getArcAppsBtn.addEventListener('click', () => { + api.getInstalledArcApps() + .then(result => { + console.error("Installed apps: " + result); + const arc_apps_text = document.querySelector('#arc_apps'); + arc_apps_text.value = result.apps; + }, err => { + console.error(err); + }) + }); + + const uninstallArcAppsBtn = document.querySelector('#uninstall_arc_apps'); + + uninstallArcAppsBtn.addEventListener('click', () => { + api.uninstallArcApps( + ['com.netflix.mediaclient', 'com.google.android.videos']) + .then(() => { + console.log('uninstalled arc apps'); + }, (error) => { + console.error(error.message); + }); + }); + }); + </script> +</head> +<body> + <h2>Add Supervision Webview</h2> + + <div> + <button id="logout">Logout</button> + </div> + <div> + <button id="get_arc_apps">Get ARC Apps</button> + </div> + <div> + <button id="uninstall_arc_apps">Uninstall ARC Apps</button> + </div> + <div> + <input type="text" id="arc_apps" + minlength="0" maxlength="128" size="128"> + </div> + <div> + <a href="webview-example2.html">Link to another page</a> + </div> +</body>
diff --git a/chrome/browser/resources/chromeos/add_supervision/webview-example2.html b/chrome/browser/resources/chromeos/add_supervision/webview-example2.html new file mode 100644 index 0000000..b7d7202 --- /dev/null +++ b/chrome/browser/resources/chromeos/add_supervision/webview-example2.html
@@ -0,0 +1,67 @@ +<!doctype html> +<head> + <script src="post_message_api.js"></script> + <script src="add_supervision_api_client.js"></script> + <script> + /** @type {AddSupervisionAPIClient} */ + let api = new AddSupervisionAPIClient(); + api.initialize(); + + // + // UI implementation: + // + document.addEventListener('DOMContentLoaded', () => { + const logoutBtn = document.querySelector('#logout'); + + logoutBtn.addEventListener('click', () => { + api.logOut().then(() => { + // This won't get reached. + }, (error) => { + console.error(error.message); + }); + }); + + const getArcAppsBtn = document.querySelector('#get_arc_apps'); + + getArcAppsBtn.addEventListener('click', () => { + api.getInstalledArcApps() + .then(result => { + console.error("Installed apps: " + result); + const arc_apps_text = document.querySelector('#arc_apps'); + arc_apps_text.value = result.apps; + }, err => { + console.error(err); + }) + }); + + const uninstallArcAppsBtn = document.querySelector('#uninstall_arc_apps'); + + uninstallArcAppsBtn.addEventListener('click', () => { + api.uninstallArcApps( + ['com.netflix.mediaclient', 'com.google.android.videos']) + .then(() => { + console.log('uninstalled arc apps'); + }, (error) => { + console.error(error.message); + }); + }); + }); + </script> +</head> +<body> + <h2>Add Supervision Webview</h2> + + <div> + <button id="logout">Logout</button> + </div> + <div> + <button id="get_arc_apps">Get ARC Apps</button> + </div> + <div> + <button id="uninstall_arc_apps">Uninstall ARC Apps</button> + </div> + <div> + <input type="text" id="arc_apps" + minlength="0" maxlength="128" size="128"> + </div> +</body>
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js index d7dea9e5..287a098 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js +++ b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js
@@ -265,7 +265,6 @@ var gaiaParams = {}; gaiaParams.gaiaUrl = data.gaiaUrl; gaiaParams.clientId = data.clientId; - gaiaParams.isNewGaiaFlow = true; gaiaParams.needPassword = false; gaiaParams.hl = data.hl; if (data.management_domain) {
diff --git a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js index 467ec357..9da47f2 100644 --- a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js +++ b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
@@ -711,7 +711,6 @@ params[name] = data[name]; } - params.isNewGaiaFlow = true; params.doSamlRedirect = (this.screenMode_ == ScreenMode.SAML_INTERSTITIAL); params.menuGuestMode = data.guestSignin;
diff --git a/chrome/browser/resources/gaia_auth_host/authenticator.js b/chrome/browser/resources/gaia_auth_host/authenticator.js index 8967806..a165c0d 100644 --- a/chrome/browser/resources/gaia_auth_host/authenticator.js +++ b/chrome/browser/resources/gaia_auth_host/authenticator.js
@@ -21,7 +21,6 @@ // of hardcoding the prod URL here. As is, this does not work with staging // environments. const IDP_ORIGIN = 'https://accounts.google.com/'; - const IDP_PATH = 'ServiceLogin?skipvpage=true&sarp=1&rm=hide'; const CONTINUE_URL = 'chrome-extension://mfffpogegjflfpflabcdkioaeobkgjik/success.html'; const SIGN_IN_HEADER = 'google-accounts-signin'; @@ -292,7 +291,6 @@ this.continueUrl_.substring(0, this.continueUrl_.indexOf('?')) || this.continueUrl_; this.isConstrainedWindow_ = data.constrained == '1'; - this.isNewGaiaFlow = data.isNewGaiaFlow; this.clientId_ = data.clientId; this.dontResizeNonEmbeddedPages = data.dontResizeNonEmbeddedPages; @@ -306,11 +304,9 @@ data.extractSamlPasswordAttributes; this.needPassword = !('needPassword' in data) || data.needPassword; - if (this.isNewGaiaFlow) { - this.webview_.contextMenus.onShow.addListener(function(e) { - e.preventDefault(); - }); - } + this.webview_.contextMenus.onShow.addListener(function(e) { + e.preventDefault(); + }); this.webview_.src = this.reloadUrl_; this.isLoaded_ = true; @@ -346,60 +342,53 @@ let url; if (data.gaiaPath) { url = this.idpOrigin_ + data.gaiaPath; - } else if (this.isNewGaiaFlow) { - url = this.constructChromeOSAPIUrl_(); } else { - url = this.idpOrigin_ + IDP_PATH; + url = this.constructChromeOSAPIUrl_(); } - if (this.isNewGaiaFlow) { - if (data.chromeType) { - url = appendParam(url, 'chrometype', data.chromeType); - } - if (data.clientId) { - url = appendParam(url, 'client_id', data.clientId); - } - if (data.enterpriseDisplayDomain) { - url = appendParam(url, 'manageddomain', data.enterpriseDisplayDomain); - } - if (data.clientVersion) { - url = appendParam(url, 'client_version', data.clientVersion); - } - if (data.platformVersion) { - url = appendParam(url, 'platform_version', data.platformVersion); - } - if (data.releaseChannel) { - url = appendParam(url, 'release_channel', data.releaseChannel); - } - if (data.endpointGen) { - url = appendParam(url, 'endpoint_gen', data.endpointGen); - } - let mi = ''; - if (data.menuGuestMode) { - mi += 'gm,'; - } - if (data.menuKeyboardOptions) { - mi += 'ko,'; - } - if (data.menuEnterpriseEnrollment) { - mi += 'ee,'; - } - if (mi.length) { - url = appendParam(url, 'mi', mi); - } + if (data.chromeType) { + url = appendParam(url, 'chrometype', data.chromeType); + } + if (data.clientId) { + url = appendParam(url, 'client_id', data.clientId); + } + if (data.enterpriseDisplayDomain) { + url = appendParam(url, 'manageddomain', data.enterpriseDisplayDomain); + } + if (data.clientVersion) { + url = appendParam(url, 'client_version', data.clientVersion); + } + if (data.platformVersion) { + url = appendParam(url, 'platform_version', data.platformVersion); + } + if (data.releaseChannel) { + url = appendParam(url, 'release_channel', data.releaseChannel); + } + if (data.endpointGen) { + url = appendParam(url, 'endpoint_gen', data.endpointGen); + } + let mi = ''; + if (data.menuGuestMode) { + mi += 'gm,'; + } + if (data.menuKeyboardOptions) { + mi += 'ko,'; + } + if (data.menuEnterpriseEnrollment) { + mi += 'ee,'; + } + if (mi.length) { + url = appendParam(url, 'mi', mi); + } - if (data.lsbReleaseBoard) { - url = appendParam(url, 'chromeos_board', data.lsbReleaseBoard); - } - if (data.isFirstUser) { - url = appendParam(url, 'is_first_user', true); - } - if (data.obfuscatedOwnerId) { - url = appendParam(url, 'obfuscated_owner_id', data.obfuscatedOwnerId); - } - } else { - url = appendParam(url, 'continue', this.continueUrl_); - url = appendParam(url, 'service', data.service || SERVICE_ID); + if (data.lsbReleaseBoard) { + url = appendParam(url, 'chromeos_board', data.lsbReleaseBoard); + } + if (data.isFirstUser) { + url = appendParam(url, 'is_first_user', true); + } + if (data.obfuscatedOwnerId) { + url = appendParam(url, 'obfuscated_owner_id', data.obfuscatedOwnerId); } if (data.hl) { url = appendParam(url, 'hl', data.hl); @@ -448,16 +437,6 @@ onRequestCompleted_(details) { const currentUrl = details.url; - if (!this.isNewGaiaFlow && - currentUrl.lastIndexOf(this.continueUrlWithoutParams_, 0) == 0) { - if (currentUrl.indexOf('ntp=1') >= 0) { - this.skipForNow_ = true; - } - - this.maybeCompleteAuth_(); - return; - } - if (!currentUrl.startsWith('https')) { this.trusted_ = false; }
diff --git a/chrome/browser/resources/local_ntp/local_ntp.css b/chrome/browser/resources/local_ntp/local_ntp.css index 051aa98..159f3bc 100644 --- a/chrome/browser/resources/local_ntp/local_ntp.css +++ b/chrome/browser/resources/local_ntp/local_ntp.css
@@ -1099,7 +1099,7 @@ width: 100%; } -.bg-sel-tile .selected-circle { +#customization-menu .bg-sel-tile .selected-circle { height: 20px; left: initial; right: 10px; @@ -1107,12 +1107,12 @@ width: 20px; } -html[dir=rtl] .bg-sel-tile .selected-circle { +html[dir=rtl] #customization-menu .bg-sel-tile .selected-circle { left: 10px; right: initial; } -.bg-sel-tile .selected-check { +#customization-menu .bg-sel-tile .selected-check { height: 24px; left: initial; right: 0; @@ -1120,7 +1120,7 @@ width: 24px; } -html[dir=rtl] .bg-sel-tile .selected-check { +html[dir=rtl] #customization-menu .bg-sel-tile .selected-check { left: 0; right: initial; }
diff --git a/chrome/browser/resources/local_ntp/local_ntp.js b/chrome/browser/resources/local_ntp/local_ntp.js index c686fc88..d5e2748 100644 --- a/chrome/browser/resources/local_ntp/local_ntp.js +++ b/chrome/browser/resources/local_ntp/local_ntp.js
@@ -59,8 +59,8 @@ */ const NTP_DESIGN = { numTitleLines: 1, - titleColor: [50, 50, 50, 255], - titleColorAgainstDark: [210, 210, 210, 255], + titleColor: [60, 64, 67, 255], /** GG800 */ + titleColorAgainstDark: [248, 249, 250, 255], /** GG050 */ }; @@ -481,7 +481,8 @@ const message = {cmd: 'updateTheme'}; message.isThemeDark = info.isNtpBackgroundDark; - message.isUsingTheme = !info.usingDefaultTheme; + message.customBackground = info.customBackgroundConfigured; + message.useTitleContainer = info.useTitleContainer; message.isDarkMode = getUseDarkChips(info); let titleColor = NTP_DESIGN.titleColor;
diff --git a/chrome/browser/resources/local_ntp/most_visited_single.css b/chrome/browser/resources/local_ntp/most_visited_single.css index 9362a7b..4b0ef15 100644 --- a/chrome/browser/resources/local_ntp/most_visited_single.css +++ b/chrome/browser/resources/local_ntp/most_visited_single.css
@@ -25,7 +25,7 @@ --md-title-max-height: 28px; /* May be overridden by themes (on the body element). */ - --tile-title-color: #323232; + --tile-title-color: rgb(var(--GG800-rgb)); } body { @@ -255,7 +255,7 @@ } .md-title { - color: rgb(var(--GG800-rgb)); + color: rgb(var(--tile-title-color)); font-size: var(--md-title-font-size); font-weight: 500; max-height: var(--md-title-max-height); @@ -276,42 +276,24 @@ font-weight: 400; } -/* Apply when Chrome is in dark mode. */ -html[darkmode=true] .md-title { - color: rgb(var(--GG200-rgb)); -} - /* Apply when a custom background is set. */ -body.dark-theme .md-tile-container:not(.reorder) .md-title { - color: rgb(var(--GG050-rgb)); +body.custom-background .md-tile-container:not(.reorder) .md-title { filter: drop-shadow(0 0 6px rgba(0, 0, 0, 0.35)); } -/* Apply only when a theme is installed. */ -body.using-theme .md-title-container { +/* Apply only when a theme with image is installed. */ +body.use-title-container .md-title-container { background-color: white; /* Necessary for a "pill" shape. Using 50% creates an oval. */ border-radius: 500px; padding: 0 8px; } -html[darkmode=true] body.using-theme .md-title-container { - background-color: rgb(var(--GG900-rgb)); -} - -html[darkmode=true] body.using-theme .md-tile-container.reorder .md-title-container { - background-color: rgb(var(--dark-mode-bg-rgb)); -} - -body.using-theme .md-tile-container:not(.reorder) .md-title { +body.use-title-container .md-tile-container:not(.reorder) .md-title { color: rgb(var(--GG800-rgb)); filter: unset; } -html[darkmode=true] body.using-theme .md-tile-container:not(.reorder) .md-title { - color: rgb(var(--GG200-rgb)); -} - .md-menu { background-color: transparent; border: none;
diff --git a/chrome/browser/resources/local_ntp/most_visited_single.js b/chrome/browser/resources/local_ntp/most_visited_single.js index c671a77..7f02c2e 100644 --- a/chrome/browser/resources/local_ntp/most_visited_single.js +++ b/chrome/browser/resources/local_ntp/most_visited_single.js
@@ -808,13 +808,14 @@ function updateTheme(info) { document.body.style.setProperty('--tile-title-color', info.tileTitleColor); document.body.classList.toggle('dark-theme', info.isThemeDark); - document.body.classList.toggle('using-theme', info.isUsingTheme); + document.body.classList.toggle('use-title-container', info.useTitleContainer); + document.body.classList.toggle('custom-background', info.customBackground); document.documentElement.setAttribute('darkmode', info.isDarkMode); // Reduce font weight on the default(white) background for Mac and CrOS. document.body.classList.toggle( CLASSES.MAC_CHROMEOS, - !info.isThemeDark && !info.isUsingTheme && + !info.isThemeDark && !info.useTitleContainer && (navigator.userAgent.indexOf('Mac') > -1 || navigator.userAgent.indexOf('CrOS') > -1)); }
diff --git a/chrome/browser/resources/management/management_ui.js b/chrome/browser/resources/management/management_ui.js index 13f177d..1df3609 100644 --- a/chrome/browser/resources/management/management_ui.js +++ b/chrome/browser/resources/management/management_ui.js
@@ -240,7 +240,11 @@ /** @private */ onTapBack_() { - window.location.href = `chrome://settings/help`; + if (history.length > 1) { + history.back(); + } else { + window.location.href = 'chrome://settings/help'; + } }, /** @private */
diff --git a/chrome/browser/tracing/background_tracing_field_trial_unittest.cc b/chrome/browser/tracing/background_tracing_field_trial_unittest.cc index fb759138..c935d54 100644 --- a/chrome/browser/tracing/background_tracing_field_trial_unittest.cc +++ b/chrome/browser/tracing/background_tracing_field_trial_unittest.cc
@@ -21,7 +21,7 @@ BackgroundTracingTest() = default; void TearDown() override { - content::BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + content::BackgroundTracingManager::GetInstance()->AbortScenario(); } private:
diff --git a/chrome/browser/tracing/background_tracing_metrics_provider_unittest.cc b/chrome/browser/tracing/background_tracing_metrics_provider_unittest.cc index efd39f1..7ef8bc5 100644 --- a/chrome/browser/tracing/background_tracing_metrics_provider_unittest.cc +++ b/chrome/browser/tracing/background_tracing_metrics_provider_unittest.cc
@@ -34,7 +34,7 @@ EXPECT_FALSE(provider.HasIndependentMetrics()); content::BackgroundTracingManager::GetInstance()->SetTraceToUploadForTesting( - std::make_unique<std::string>(kDummyTrace)); + kDummyTrace); EXPECT_TRUE(provider.HasIndependentMetrics()); metrics::ChromeUserMetricsExtension uma_proto; @@ -57,11 +57,11 @@ EXPECT_FALSE(provider.HasIndependentMetrics()); content::BackgroundTracingManager::GetInstance()->SetTraceToUploadForTesting( - std::make_unique<std::string>(kDummyTrace)); + kDummyTrace); EXPECT_TRUE(provider.HasIndependentMetrics()); content::BackgroundTracingManager::GetInstance()->SetTraceToUploadForTesting( - nullptr); + ""); metrics::ChromeUserMetricsExtension uma_proto; uma_proto.set_client_id(100); uma_proto.set_session_id(15);
diff --git a/chrome/browser/tracing/chrome_tracing_delegate_browsertest.cc b/chrome/browser/tracing/chrome_tracing_delegate_browsertest.cc index 507d18f..4c56c23 100644 --- a/chrome/browser/tracing/chrome_tracing_delegate_browsertest.cc +++ b/chrome/browser/tracing/chrome_tracing_delegate_browsertest.cc
@@ -148,7 +148,7 @@ local_state->GetInt64(prefs::kBackgroundTracingLastUpload)); EXPECT_FALSE(last_upload_time.is_null()); - content::BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + content::BackgroundTracingManager::GetInstance()->AbortScenario(); base::RunLoop wait_for_abort; content::BackgroundTracingManager::GetInstance()->WhenIdle( wait_for_abort.QuitClosure()); @@ -188,7 +188,7 @@ local_state->GetInt64(prefs::kBackgroundTracingLastUpload)); EXPECT_FALSE(last_upload_time.is_null()); - content::BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + content::BackgroundTracingManager::GetInstance()->AbortScenario(); base::RunLoop wait_for_abort; content::BackgroundTracingManager::GetInstance()->WhenIdle( wait_for_abort.QuitClosure());
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index f7d66f5..aa196357 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1539,6 +1539,8 @@ "webui/chromeos/add_supervision/add_supervision_handler.h", "webui/chromeos/add_supervision/add_supervision_handler_utils.cc", "webui/chromeos/add_supervision/add_supervision_handler_utils.h", + "webui/chromeos/add_supervision/add_supervision_ui.cc", + "webui/chromeos/add_supervision/add_supervision_ui.h", "webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc", "webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.h", "webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_ui.cc",
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index b03f30f..b62cd84 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -2625,10 +2625,8 @@ // current page can be shown when browsing a url that is not inside the app. // Note: Final determination of whether or not the toolbar is shown is made by // the |AppBrowserController|. - if (web_app_controller() && - web_app_controller()->IsForExperimentalWebAppBrowser()) { + if (app_controller() && app_controller()->IsForExperimentalWebAppBrowser()) features |= FEATURE_TOOLBAR; - } return !!(features & feature); }
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index 55d5012..e91cedc 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h
@@ -323,10 +323,10 @@ BrowserInstantController* instant_controller() { return instant_controller_.get(); } - const web_app::AppBrowserController* web_app_controller() const { + const web_app::AppBrowserController* app_controller() const { return app_controller_.get(); } - web_app::AppBrowserController* web_app_controller() { + web_app::AppBrowserController* app_controller() { return app_controller_.get(); }
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc index 0c29520..2819711 100644 --- a/chrome/browser/ui/browser_commands.cc +++ b/chrome/browser/ui/browser_commands.cc
@@ -1268,7 +1268,7 @@ } Browser* OpenInChrome(Browser* hosted_app_browser) { - DCHECK(hosted_app_browser->web_app_controller()); + DCHECK(hosted_app_browser->app_controller()); // Find a non-incognito browser. Browser* target_browser = chrome::FindTabbedBrowser(hosted_app_browser->profile(), false);
diff --git a/chrome/browser/ui/extensions/application_launch.cc b/chrome/browser/ui/extensions/application_launch.cc index 9a1d8a2..e90984e0 100644 --- a/chrome/browser/ui/extensions/application_launch.cc +++ b/chrome/browser/ui/extensions/application_launch.cc
@@ -417,7 +417,7 @@ WebContents* web_contents = nav_params.navigated_or_inserted_contents; extensions::HostedAppBrowserController::SetAppPrefsForWebContents( - browser->web_app_controller(), web_contents); + browser->app_controller(), web_contents); if (extension) { web_app::WebAppTabHelperBase* tab_helper = web_app::WebAppTabHelperBase::FromWebContents(web_contents);
diff --git a/chrome/browser/ui/extensions/hosted_app_browsertest.cc b/chrome/browser/ui/extensions/hosted_app_browsertest.cc index f4c8d5a..be0c086 100644 --- a/chrome/browser/ui/extensions/hosted_app_browsertest.cc +++ b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
@@ -162,7 +162,7 @@ bool proceed_through_interstitial = false) { NavigateToURLAndWait(browser, url, proceed_through_interstitial); EXPECT_EQ(expected_visibility, - browser->web_app_controller()->ShouldShowToolbar()); + browser->app_controller()->ShouldShowToolbar()); } void CheckWebContentsHasAppPrefs(content::WebContents* web_contents) { @@ -240,7 +240,7 @@ }; AppMenuCommandState GetAppMenuCommandState(int command_id, Browser* browser) { - DCHECK(!browser->web_app_controller()) + DCHECK(!browser->app_controller()) << "This check only applies to regular browser windows."; auto app_menu_model = std::make_unique<AppMenuModel>(nullptr, browser); app_menu_model->Init(); @@ -624,7 +624,7 @@ app_browser_->tab_strip_model()->GetActiveWebContents(); EXPECT_TRUE(TryToLoadImage( web_contents, embedded_test_server()->GetURL("foo.com", kImagePath))); - EXPECT_TRUE(app_browser_->web_app_controller()->ShouldShowToolbar()); + EXPECT_TRUE(app_browser_->app_controller()->ShouldShowToolbar()); } IN_PROC_BROWSER_TEST_P(HostedAppTest, ShouldShowToolbarForHTTPAppSameOrigin) { @@ -1096,7 +1096,7 @@ NavigateToURLAndWait(app_browser_, GetSecureAppURL()); - ASSERT_TRUE(app_browser_->web_app_controller()); + ASSERT_TRUE(app_browser_->app_controller()); NavigateAndCheckForToolbar(app_browser_, GURL(kExampleURL), true); } @@ -1118,7 +1118,7 @@ NavigateToURLAndWait(app_browser_, GetSecureAppURL()); - ASSERT_TRUE(app_browser_->web_app_controller()); + ASSERT_TRUE(app_browser_->app_controller()); TestAppActionOpensForegroundTab( base::BindOnce( @@ -1153,7 +1153,7 @@ InstallSecurePWA(); // Toolbar should not be visible in the app. - ASSERT_FALSE(app_browser_->web_app_controller()->ShouldShowToolbar()); + ASSERT_FALSE(app_browser_->app_controller()->ShouldShowToolbar()); // The installed PWA's scope is app.com:{PORT}/ssl, // so app.com:{PORT}/accessibility_fail.html is out of scope. @@ -1162,7 +1162,7 @@ NavigateToURLAndWait(app_browser_, out_of_scope); // Location should be visible off scope. - ASSERT_TRUE(app_browser_->web_app_controller()->ShouldShowToolbar()); + ASSERT_TRUE(app_browser_->app_controller()->ShouldShowToolbar()); } // Tests that PWA menus have an uninstall option. @@ -1308,7 +1308,7 @@ Browser* app_browser = ReparentSecureActiveTabIntoPwaWindow(browser()); ASSERT_EQ(static_cast<extensions::HostedAppBrowserController*>( - app_browser->web_app_controller()) + app_browser->app_controller()) ->GetExtensionForTesting(), app_); } @@ -1323,7 +1323,7 @@ Browser* app_browser = ReparentSecureActiveTabIntoPwaWindow(browser()); ASSERT_EQ(static_cast<extensions::HostedAppBrowserController*>( - app_browser->web_app_controller()) + app_browser->app_controller()) ->GetExtensionForTesting(), app_); @@ -1555,7 +1555,7 @@ Browser* app_browser = LaunchAppBrowser(app); EXPECT_FALSE(static_cast<extensions::HostedAppBrowserController*>( - app_browser->web_app_controller()) + app_browser->app_controller()) ->CreatedForInstalledPwa()); } @@ -1563,7 +1563,7 @@ SetupApp("https_app"); EXPECT_FALSE(static_cast<extensions::HostedAppBrowserController*>( - app_browser_->web_app_controller()) + app_browser_->app_controller()) ->CreatedForInstalledPwa()); } @@ -1576,7 +1576,7 @@ Browser* app_browser = LaunchAppBrowser(app); EXPECT_TRUE(static_cast<extensions::HostedAppBrowserController*>( - app_browser->web_app_controller()) + app_browser->app_controller()) ->CreatedForInstalledPwa()); } @@ -2732,7 +2732,7 @@ EXPECT_EQ(web_app::GetAppIdFromApplicationName(app_browser->app_name()), app->id()); EXPECT_EQ(SkColorSetA(*web_app_info.theme_color, SK_AlphaOPAQUE), - app_browser->web_app_controller()->GetThemeColor()); + app_browser->app_controller()->GetThemeColor()); } { WebApplicationInfo web_app_info; @@ -2744,8 +2744,7 @@ EXPECT_EQ(web_app::GetAppIdFromApplicationName(app_browser->app_name()), app->id()); - EXPECT_EQ(base::nullopt, - app_browser->web_app_controller()->GetThemeColor()); + EXPECT_EQ(base::nullopt, app_browser->app_controller()->GetThemeColor()); } }
diff --git a/chrome/browser/ui/extensions/hosted_app_menu_model.cc b/chrome/browser/ui/extensions/hosted_app_menu_model.cc index bca9e1c..1378971 100644 --- a/chrome/browser/ui/extensions/hosted_app_menu_model.cc +++ b/chrome/browser/ui/extensions/hosted_app_menu_model.cc
@@ -46,14 +46,14 @@ // Chrome OS's app list is prominent enough to not need a separate uninstall // option in the app menu. #if !defined(OS_CHROMEOS) - DCHECK(browser()->web_app_controller()); - if (browser()->web_app_controller()->IsInstalled()) { + DCHECK(browser()->app_controller()); + if (browser()->app_controller()->IsInstalled()) { AddSeparator(ui::NORMAL_SEPARATOR); - AddItem(kUninstallAppCommandId, - l10n_util::GetStringFUTF16( - IDS_UNINSTALL_FROM_OS_LAUNCH_SURFACE, - base::UTF8ToUTF16( - browser()->web_app_controller()->GetAppShortName()))); + AddItem( + kUninstallAppCommandId, + l10n_util::GetStringFUTF16( + IDS_UNINSTALL_FROM_OS_LAUNCH_SURFACE, + base::UTF8ToUTF16(browser()->app_controller()->GetAppShortName()))); } #endif // !defined(OS_CHROMEOS) AddSeparator(ui::LOWER_SEPARATOR); @@ -70,13 +70,13 @@ bool HostedAppMenuModel::IsCommandIdEnabled(int command_id) const { return command_id == kUninstallAppCommandId - ? browser()->web_app_controller()->CanUninstall() + ? browser()->app_controller()->CanUninstall() : AppMenuModel::IsCommandIdEnabled(command_id); } void HostedAppMenuModel::ExecuteCommand(int command_id, int event_flags) { if (command_id == kUninstallAppCommandId) { - browser()->web_app_controller()->Uninstall(); + browser()->app_controller()->Uninstall(); } else { AppMenuModel::ExecuteCommand(command_id, event_flags); }
diff --git a/chrome/browser/ui/settings_window_manager_chromeos.cc b/chrome/browser/ui/settings_window_manager_chromeos.cc index 3f2e2598..6924138 100644 --- a/chrome/browser/ui/settings_window_manager_chromeos.cc +++ b/chrome/browser/ui/settings_window_manager_chromeos.cc
@@ -147,9 +147,9 @@ base::Optional<std::string> settings_app_id = web_app::GetAppIdForSystemWebApp(profile, web_app::SystemAppType::SETTINGS); - return settings_app_id && browser->web_app_controller() && + return settings_app_id && browser->app_controller() && static_cast<extensions::HostedAppBrowserController*>( - browser->web_app_controller()) + browser->app_controller()) ->GetAppId() == settings_app_id.value(); } else { auto iter = settings_session_map_.find(profile);
diff --git a/chrome/browser/ui/views/autofill/payments/card_unmask_prompt_views.cc b/chrome/browser/ui/views/autofill/payments/card_unmask_prompt_views.cc index b0306b2..b1323a99 100644 --- a/chrome/browser/ui/views/autofill/payments/card_unmask_prompt_views.cc +++ b/chrome/browser/ui/views/autofill/payments/card_unmask_prompt_views.cc
@@ -310,7 +310,7 @@ year_input_->visible() ? year_input_->GetTextForRow(year_input_->GetSelectedIndex()) : base::string16(), - storage_checkbox_ ? storage_checkbox_->checked() : false); + storage_checkbox_ ? storage_checkbox_->GetChecked() : false); return false; }
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 2f45d85..3c72542 100644 --- a/chrome/browser/ui/views/autofill/payments/migratable_card_view.cc +++ b/chrome/browser/ui/views/autofill/payments/migratable_card_view.cc
@@ -74,7 +74,7 @@ MigratableCardView::~MigratableCardView() = default; bool MigratableCardView::IsSelected() { - return !checkbox_ || checkbox_->checked(); + return !checkbox_ || checkbox_->GetChecked(); } std::string MigratableCardView::GetGuid() { @@ -201,7 +201,7 @@ // button if needed. parent_dialog_->DialogModelChanged(); // The warning text will be visible only when user unchecks the checkbox. - checkbox_uncheck_text_container_->SetVisible(!checkbox_->checked()); + checkbox_uncheck_text_container_->SetVisible(!checkbox_->GetChecked()); InvalidateLayout(); parent_dialog_->UpdateLayout(); } else {
diff --git a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc index f836c2e5a0..d762118 100644 --- a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc +++ b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc
@@ -75,7 +75,7 @@ } void ChromeBrowserMainExtraPartsViews::PreCreateThreads() { -#if defined(USE_AURA) +#if defined(USE_AURA) && !defined(OS_CHROMEOS) views::InstallDesktopScreenIfNecessary(); #endif }
diff --git a/chrome/browser/ui/views/chrome_cleaner_dialog_win.cc b/chrome/browser/ui/views/chrome_cleaner_dialog_win.cc index 6936443..6f1d640 100644 --- a/chrome/browser/ui/views/chrome_cleaner_dialog_win.cc +++ b/chrome/browser/ui/views/chrome_cleaner_dialog_win.cc
@@ -193,7 +193,7 @@ if (sender == details_button_) { if (dialog_controller_) { dialog_controller_->DetailsButtonClicked( - /*logs_enabled=*/logs_permission_checkbox_->checked()); + /*logs_enabled=*/logs_permission_checkbox_->GetChecked()); dialog_controller_ = nullptr; } GetWidget()->Close(); @@ -203,7 +203,7 @@ DCHECK_EQ(logs_permission_checkbox_, sender); if (dialog_controller_) - dialog_controller_->SetLogsEnabled(logs_permission_checkbox_->checked()); + dialog_controller_->SetLogsEnabled(logs_permission_checkbox_->GetChecked()); } // safe_browsing::ChromeCleanerController::Observer overrides @@ -240,7 +240,7 @@ switch (result) { case DialogInteractionResult::kAccept: dialog_controller_->Accept( - /*logs_enabled=*/logs_permission_checkbox_->checked()); + /*logs_enabled=*/logs_permission_checkbox_->GetChecked()); break; case DialogInteractionResult::kCancel: dialog_controller_->Cancel();
diff --git a/chrome/browser/ui/views/content_setting_bubble_contents.cc b/chrome/browser/ui/views/content_setting_bubble_contents.cc index 177267c6..b6333c99 100644 --- a/chrome/browser/ui/views/content_setting_bubble_contents.cc +++ b/chrome/browser/ui/views/content_setting_bubble_contents.cc
@@ -410,7 +410,7 @@ int ContentSettingBubbleContents::GetSelectedRadioOption() { for (RadioGroup::const_iterator i(radio_group_.begin()); i != radio_group_.end(); ++i) { - if ((*i)->checked()) + if ((*i)->GetChecked()) return i - radio_group_.begin(); } NOTREACHED(); @@ -646,7 +646,7 @@ DCHECK(content_setting_bubble_model_); if (sender == manage_checkbox_) { content_setting_bubble_model_->OnManageCheckboxChecked( - manage_checkbox_->checked()); + manage_checkbox_->GetChecked()); // Toggling the check state may change the dialog button text. DialogModelChanged();
diff --git a/chrome/browser/ui/views/create_application_shortcut_view.cc b/chrome/browser/ui/views/create_application_shortcut_view.cc index 2c83d361..adc2abd1 100644 --- a/chrome/browser/ui/views/create_application_shortcut_view.cc +++ b/chrome/browser/ui/views/create_application_shortcut_view.cc
@@ -164,11 +164,10 @@ bool CreateChromeApplicationShortcutView::IsDialogButtonEnabled( ui::DialogButton button) const { if (button == ui::DIALOG_BUTTON_OK) - return desktop_check_box_->checked() || - ((menu_check_box_ != nullptr) && - menu_check_box_->checked()) || + return desktop_check_box_->GetChecked() || + ((menu_check_box_ != nullptr) && menu_check_box_->GetChecked()) || ((quick_launch_check_box_ != nullptr) && - quick_launch_check_box_->checked()); + quick_launch_check_box_->GetChecked()); return true; } @@ -194,15 +193,15 @@ return false; web_app::ShortcutLocations creation_locations; - creation_locations.on_desktop = desktop_check_box_->checked(); - if (menu_check_box_ != nullptr && menu_check_box_->checked()) { + creation_locations.on_desktop = desktop_check_box_->GetChecked(); + if (menu_check_box_ != nullptr && menu_check_box_->GetChecked()) { creation_locations.applications_menu_location = web_app::APP_MENU_LOCATION_SUBDIR_CHROMEAPPS; } #if defined(OS_WIN) - creation_locations.in_quick_launch_bar = quick_launch_check_box_ == nullptr ? - false : quick_launch_check_box_->checked(); + creation_locations.in_quick_launch_bar = + quick_launch_check_box_ && quick_launch_check_box_->GetChecked(); #elif defined(OS_POSIX) // Create shortcut in Mac dock or as Linux (gnome/kde) application launcher // are not implemented yet. @@ -226,13 +225,13 @@ const ui::Event& event) { if (sender == desktop_check_box_) { profile_->GetPrefs()->SetBoolean(prefs::kWebAppCreateOnDesktop, - desktop_check_box_->checked()); + desktop_check_box_->GetChecked()); } else if (sender == menu_check_box_) { profile_->GetPrefs()->SetBoolean(prefs::kWebAppCreateInAppsMenu, - menu_check_box_->checked()); + menu_check_box_->GetChecked()); } else if (sender == quick_launch_check_box_) { profile_->GetPrefs()->SetBoolean(prefs::kWebAppCreateInQuickLaunchBar, - quick_launch_check_box_->checked()); + quick_launch_check_box_->GetChecked()); } // When no checkbox is checked we should not have the action button enabled.
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc index 0bbf9b2..d7c1eed 100644 --- a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc +++ b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc
@@ -338,7 +338,7 @@ DesktopMediaID source = source_optional.value(); source.audio_share = audio_share_checkbox_ && audio_share_checkbox_->visible() && - audio_share_checkbox_->checked(); + audio_share_checkbox_->GetChecked(); if (source.type == DesktopMediaID::TYPE_WEB_CONTENTS) { // Activate the selected tab and bring the browser window for the selected
diff --git a/chrome/browser/ui/views/extensions/bookmark_app_confirmation_view.cc b/chrome/browser/ui/views/extensions/bookmark_app_confirmation_view.cc index 0c85cb1..f90bd01 100644 --- a/chrome/browser/ui/views/extensions/bookmark_app_confirmation_view.cc +++ b/chrome/browser/ui/views/extensions/bookmark_app_confirmation_view.cc
@@ -127,7 +127,7 @@ bool BookmarkAppConfirmationView::Accept() { web_app_info_.title = GetTrimmedTitle(); web_app_info_.open_as_window = - open_as_window_checkbox_ && open_as_window_checkbox_->checked(); + open_as_window_checkbox_ && open_as_window_checkbox_->GetChecked(); std::move(callback_).Run(true, std::make_unique<WebApplicationInfo>(web_app_info_)); return true;
diff --git a/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view.cc b/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view.cc index 884e8f4..02a904d 100644 --- a/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view.cc +++ b/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view.cc
@@ -259,7 +259,7 @@ bool ExtensionUninstallDialogDelegateView::Accept() { if (dialog_) - dialog_->DialogAccepted(checkbox_ && checkbox_->checked()); + dialog_->DialogAccepted(checkbox_ && checkbox_->GetChecked()); return true; }
diff --git a/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc b/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc index c3b16cb..356a563b 100644 --- a/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc +++ b/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc
@@ -286,7 +286,7 @@ iter != checkbox_map_.end(); ++iter) { if (sender == iter->second->checkbox()) { controller_->DidToggleEntry(iter->first, - iter->second->checkbox()->checked()); + iter->second->checkbox()->GetChecked()); return; } }
diff --git a/chrome/browser/ui/views/extensions/media_galleries_dialog_views_unittest.cc b/chrome/browser/ui/views/extensions/media_galleries_dialog_views_unittest.cc index 2c206a8..060600d5 100644 --- a/chrome/browser/ui/views/extensions/media_galleries_dialog_views_unittest.cc +++ b/chrome/browser/ui/views/extensions/media_galleries_dialog_views_unittest.cc
@@ -81,10 +81,10 @@ EXPECT_EQ(2U, dialog.checkbox_map_.size()); MediaGalleryCheckboxView* checkbox_view1 = dialog.checkbox_map_[1]; - EXPECT_TRUE(checkbox_view1->checkbox()->checked()); + EXPECT_TRUE(checkbox_view1->checkbox()->GetChecked()); MediaGalleryCheckboxView* checkbox_view2 = dialog.checkbox_map_[2]; - EXPECT_FALSE(checkbox_view2->checkbox()->checked()); + EXPECT_FALSE(checkbox_view2->checkbox()->GetChecked()); } // Tests that toggling checkboxes updates the controller. @@ -98,7 +98,7 @@ MediaGalleriesDialogViews dialog(controller()); EXPECT_EQ(1U, dialog.checkbox_map_.size()); views::Checkbox* checkbox = dialog.checkbox_map_[1]->checkbox(); - EXPECT_TRUE(checkbox->checked()); + EXPECT_TRUE(checkbox->GetChecked()); ui::KeyEvent dummy_event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE); EXPECT_CALL(*controller(), DidToggleEntry(1, false));
diff --git a/chrome/browser/ui/views/external_protocol_dialog.cc b/chrome/browser/ui/views/external_protocol_dialog.cc index b227680..d4c186e 100644 --- a/chrome/browser/ui/views/external_protocol_dialog.cc +++ b/chrome/browser/ui/views/external_protocol_dialog.cc
@@ -81,7 +81,7 @@ UMA_HISTOGRAM_LONG_TIMES("clickjacking.launch_url", base::TimeTicks::Now() - creation_time_); - const bool remember = remember_decision_checkbox_->checked(); + const bool remember = remember_decision_checkbox_->GetChecked(); ExternalProtocolHandler::RecordHandleStateMetrics( remember, ExternalProtocolHandler::DONT_BLOCK);
diff --git a/chrome/browser/ui/views/first_run_dialog.cc b/chrome/browser/ui/views/first_run_dialog.cc index 2f6ba063..f92c4f4 100644 --- a/chrome/browser/ui/views/first_run_dialog.cc +++ b/chrome/browser/ui/views/first_run_dialog.cc
@@ -111,10 +111,10 @@ bool FirstRunDialog::Accept() { GetWidget()->Hide(); - ChangeMetricsReportingStateWithReply(report_crashes_->checked(), + ChangeMetricsReportingStateWithReply(report_crashes_->GetChecked(), base::Bind(&InitCrashReporterIfEnabled)); - if (make_default_->checked()) + if (make_default_->GetChecked()) shell_integration::SetAsDefaultBrowser(); Done();
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc index d2ee8ebc..2fed8a5 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc
@@ -134,7 +134,7 @@ bool BrowserNonClientFrameView::CanDrawStrokes() const { // Hosted apps should not draw strokes, as they don't have a tab strip. - return !browser_view_->browser()->web_app_controller(); + return !browser_view_->browser()->app_controller(); } SkColor BrowserNonClientFrameView::GetCaptionColor( @@ -153,10 +153,10 @@ if (frame_->ShouldUseTheme()) return GetThemeProviderForProfile()->GetColor(color_id); - web_app::AppBrowserController* web_app_controller = - browser_view_->browser()->web_app_controller(); - if (web_app_controller && web_app_controller->GetThemeColor()) - return *web_app_controller->GetThemeColor(); + web_app::AppBrowserController* app_controller = + browser_view_->browser()->app_controller(); + if (app_controller && app_controller->GetThemeColor()) + return *app_controller->GetThemeColor(); return ThemeProperties::GetDefaultColor(color_id, browser_view_->IsIncognito());
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc index cece4d2..76afb9b 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc
@@ -270,7 +270,7 @@ // Hosted apps apply a theme color if specified by the extension. Browser* browser = browser_view()->browser(); base::Optional<SkColor> theme_color = - browser->web_app_controller()->GetThemeColor(); + browser->app_controller()->GetThemeColor(); if (theme_color) active_color = views::FrameCaptionButton::GetButtonColor(*theme_color); @@ -683,7 +683,7 @@ void BrowserNonClientFrameViewAsh::SetUpForHostedApp() { Browser* browser = browser_view()->browser(); - if (!browser->web_app_controller()->ShouldShowHostedAppButtonContainer()) + if (!browser->app_controller()->ShouldShowHostedAppButtonContainer()) return; // Add the container for extra hosted app buttons (e.g app menu button). @@ -700,8 +700,7 @@ active_color = GetFrameColor(kActive); inactive_color = GetFrameColor(kInactive); } else if (browser_view()->IsBrowserTypeHostedApp()) { - active_color = - browser_view()->browser()->web_app_controller()->GetThemeColor(); + active_color = browser_view()->browser()->app_controller()->GetThemeColor(); } else if (!browser_view()->browser()->is_app()) { active_color = base::FeatureList::IsEnabled(chromeos::features::kSplitSettings)
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm index 218b9b8..123b6733 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm
@@ -69,7 +69,7 @@ if (browser_view->IsBrowserTypeHostedApp()) { if (browser_view->browser() - ->web_app_controller() + ->app_controller() ->ShouldShowHostedAppButtonContainer()) { set_hosted_app_button_container(new HostedAppButtonContainer( frame, browser_view, GetCaptionColor(kActive),
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index b3656fc0..0cbc985 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -2017,7 +2017,7 @@ // The logic of this function needs to be same as GetWindowIcon(). if (browser_->is_devtools()) return false; - if (browser_->web_app_controller()) + if (browser_->app_controller()) return true; #if defined(OS_CHROMEOS) // On ChromeOS, the tabbed browser always use a static image for the window @@ -2045,8 +2045,7 @@ } gfx::ImageSkia BrowserView::GetWindowAppIcon() { - web_app::AppBrowserController* app_controller = - browser()->web_app_controller(); + web_app::AppBrowserController* app_controller = browser()->app_controller(); return app_controller ? app_controller->GetWindowAppIcon() : GetWindowIcon(); } @@ -2056,8 +2055,7 @@ return gfx::ImageSkia(); // Hosted apps always show their app icon. - web_app::AppBrowserController* app_controller = - browser()->web_app_controller(); + web_app::AppBrowserController* app_controller = browser()->app_controller(); if (app_controller) return app_controller->GetWindowIcon();
diff --git a/chrome/browser/ui/views/frame/glass_browser_frame_view.cc b/chrome/browser/ui/views/frame/glass_browser_frame_view.cc index 32e506e9..0a92b2c 100644 --- a/chrome/browser/ui/views/frame/glass_browser_frame_view.cc +++ b/chrome/browser/ui/views/frame/glass_browser_frame_view.cc
@@ -112,7 +112,7 @@ } web_app::AppBrowserController* controller = - browser_view->browser()->web_app_controller(); + browser_view->browser()->app_controller(); if (controller && controller->ShouldShowHostedAppButtonContainer()) { // TODO(alancutter): Avoid snapshotting GetCaptionColor() values here and // call it on demand in HostedAppButtonContainer::UpdateIconsColor() via a
diff --git a/chrome/browser/ui/views/frame/hosted_app_button_container.cc b/chrome/browser/ui/views/frame/hosted_app_button_container.cc index ec811872..5d6562a 100644 --- a/chrome/browser/ui/views/frame/hosted_app_button_container.cc +++ b/chrome/browser/ui/views/frame/hosted_app_button_container.cc
@@ -184,7 +184,7 @@ inactive_color_(inactive_color) { DCHECK(browser_view_); DCHECK(browser_view_->browser() - ->web_app_controller() + ->app_controller() ->IsForExperimentalWebAppBrowser()); SetID(VIEW_ID_HOSTED_APP_BUTTON_CONTAINER);
diff --git a/chrome/browser/ui/views/frame/hosted_app_menu_button.cc b/chrome/browser/ui/views/frame/hosted_app_menu_button.cc index 9d44e078..2ae7f6b 100644 --- a/chrome/browser/ui/views/frame/hosted_app_menu_button.cc +++ b/chrome/browser/ui/views/frame/hosted_app_menu_button.cc
@@ -39,7 +39,7 @@ // Get the app name only, aka "Google Docs" instead of "My Doc - Google Docs", // because the menu applies to the entire app. base::string16 app_name = base::UTF8ToUTF16( - browser_view->browser()->web_app_controller()->GetAppShortName()); + browser_view->browser()->app_controller()->GetAppShortName()); SetAccessibleName(app_name); SetTooltipText( l10n_util::GetStringFUTF16(IDS_HOSTED_APPMENU_TOOLTIP, app_name));
diff --git a/chrome/browser/ui/views/frame/hosted_app_origin_text.cc b/chrome/browser/ui/views/frame/hosted_app_origin_text.cc index 1397c33..0d1a0c4 100644 --- a/chrome/browser/ui/views/frame/hosted_app_origin_text.cc +++ b/chrome/browser/ui/views/frame/hosted_app_origin_text.cc
@@ -31,7 +31,7 @@ SetLayoutManager(std::make_unique<views::FillLayout>()); label_ = std::make_unique<views::Label>( - browser->web_app_controller()->GetFormattedUrlOrigin(), + browser->app_controller()->GetFormattedUrlOrigin(), ChromeTextContext::CONTEXT_BODY_TEXT_SMALL, ChromeTextStyle::STYLE_EMPHASIZED) .release();
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc index b607780..7e9f705 100644 --- a/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc +++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc
@@ -182,7 +182,7 @@ AddChildView(window_title_); web_app::AppBrowserController* controller = - browser_view()->browser()->web_app_controller(); + browser_view()->browser()->app_controller(); if (controller && controller->ShouldShowHostedAppButtonContainer()) { set_hosted_app_button_container(new HostedAppButtonContainer( frame(), browser_view(), GetCaptionColor(kActive),
diff --git a/chrome/browser/ui/views/ime/ime_warning_bubble_view.cc b/chrome/browser/ui/views/ime/ime_warning_bubble_view.cc index e371066..995278f5 100644 --- a/chrome/browser/ui/views/ime/ime_warning_bubble_view.cc +++ b/chrome/browser/ui/views/ime/ime_warning_bubble_view.cc
@@ -51,7 +51,7 @@ } bool ImeWarningBubbleView::Accept() { - if (never_show_checkbox_->checked()) { + if (never_show_checkbox_->GetChecked()) { std::move(response_callback_) .Run(ImeWarningBubblePermissionStatus::GRANTED_AND_NEVER_SHOW); } else {
diff --git a/chrome/browser/ui/views/intent_picker_bubble_view.cc b/chrome/browser/ui/views/intent_picker_bubble_view.cc index 2f24b8ad..f9b7e33a 100644 --- a/chrome/browser/ui/views/intent_picker_bubble_view.cc +++ b/chrome/browser/ui/views/intent_picker_bubble_view.cc
@@ -207,9 +207,8 @@ } bool IntentPickerBubbleView::Accept() { - bool should_persist = remember_selection_checkbox_ - ? remember_selection_checkbox_->checked() - : false; + bool should_persist = remember_selection_checkbox_ && + remember_selection_checkbox_->GetChecked(); RunCallback(app_info_[selected_app_tag_].launch_name, app_info_[selected_app_tag_].type, apps::IntentPickerCloseReason::OPEN_APP, should_persist); @@ -223,9 +222,8 @@ #else kInvalidLaunchName; #endif - bool should_persist = remember_selection_checkbox_ - ? remember_selection_checkbox_->checked() - : false; + bool should_persist = remember_selection_checkbox_ && + remember_selection_checkbox_->GetChecked(); RunCallback(launch_name, apps::mojom::AppType::kUnknown, apps::IntentPickerCloseReason::STAY_IN_CHROME, should_persist); return true;
diff --git a/chrome/browser/ui/views/location_bar/custom_tab_bar_view.cc b/chrome/browser/ui/views/location_bar/custom_tab_bar_view.cc index 65fde94..7a58c63 100644 --- a/chrome/browser/ui/views/location_bar/custom_tab_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/custom_tab_bar_view.cc
@@ -178,7 +178,7 @@ tab_strip_model_observer_(this) { Browser* browser = browser_view->browser(); base::Optional<SkColor> optional_theme_color = - browser->web_app_controller()->GetThemeColor(); + browser->app_controller()->GetThemeColor(); // If we have a theme color, use that, otherwise fall back to the default // frame color. @@ -250,7 +250,7 @@ // scope (it doesn't make sense to show a 'back-to-scope' button in scope). close_button_->SetVisible(!extensions::IsSameScope( chrome::FindBrowserWithWebContents(contents) - ->web_app_controller() + ->app_controller() ->GetAppLaunchURL(), contents->GetVisibleURL(), contents->GetBrowserContext())); @@ -361,7 +361,7 @@ void CustomTabBarView::GoBackToApp() { content::WebContents* web_contents = GetWebContents(); Browser* browser = chrome::FindBrowserWithWebContents(web_contents); - GURL launch_url = browser->web_app_controller()->GetAppLaunchURL(); + GURL launch_url = browser->app_controller()->GetAppLaunchURL(); content::NavigationController& controller = web_contents->GetController(); content::BrowserContext* context = web_contents->GetBrowserContext();
diff --git a/chrome/browser/ui/views/location_bar/custom_tab_bar_view_browsertest.cc b/chrome/browser/ui/views/location_bar/custom_tab_bar_view_browsertest.cc index 839a3bc0..73df22b 100644 --- a/chrome/browser/ui/views/location_bar/custom_tab_bar_view_browsertest.cc +++ b/chrome/browser/ui/views/location_bar/custom_tab_bar_view_browsertest.cc
@@ -225,7 +225,7 @@ BrowserView* browser_view_; LocationBarView* location_bar_; CustomTabBarView* custom_tab_bar_; - web_app::AppBrowserController* web_app_controller_; + web_app::AppBrowserController* app_controller_; net::EmbeddedTestServer* https_server() { return &https_server_; } @@ -241,8 +241,8 @@ DCHECK(app_browser_); DCHECK(app_browser_ != browser()); - web_app_controller_ = app_browser_->web_app_controller(); - DCHECK(web_app_controller_); + app_controller_ = app_browser_->app_controller(); + DCHECK(app_controller_); } base::test::ScopedFeatureList scoped_feature_list_; @@ -365,11 +365,11 @@ const GURL& other_app_url = https_server()->GetURL("app.com", "/ssl/blank_page.html"); NavigateAndWait(web_contents, other_app_url); - EXPECT_FALSE(web_app_controller_->ShouldShowToolbar()); + EXPECT_FALSE(app_controller_->ShouldShowToolbar()); // Navigate out of scope. NavigateAndWait(web_contents, GURL("http://example.test/")); - EXPECT_TRUE(web_app_controller_->ShouldShowToolbar()); + EXPECT_TRUE(app_controller_->ShouldShowToolbar()); // Simulate clicking the close button and wait for navigation to finish. content::TestNavigationObserver nav_observer(web_contents); @@ -400,12 +400,12 @@ const GURL& other_app_url = https_server()->GetURL("app.com", "/ssl/blank_page.html"); NavigateAndWait(web_contents, other_app_url); - EXPECT_FALSE(web_app_controller_->ShouldShowToolbar()); + EXPECT_FALSE(app_controller_->ShouldShowToolbar()); // Navigate above the scope of the app, on the same origin. NavigateAndWait(web_contents, https_server()->GetURL( "app.com", "/accessibility_fail.html")); - EXPECT_TRUE(web_app_controller_->ShouldShowToolbar()); + EXPECT_TRUE(app_controller_->ShouldShowToolbar()); // Simulate clicking the close button and wait for navigation to finish. content::TestNavigationObserver nav_observer(web_contents); @@ -439,7 +439,7 @@ EXPECT_TRUE(content::ExecuteScript( web_contents, "window.location.replace('http://example.com');")); nav_observer.Wait(); - EXPECT_TRUE(web_app_controller_->ShouldShowToolbar()); + EXPECT_TRUE(app_controller_->ShouldShowToolbar()); } { // Simulate clicking the close button and wait for navigation to finish.
diff --git a/chrome/browser/ui/views/media_router/media_remoting_dialog_view.cc b/chrome/browser/ui/views/media_router/media_remoting_dialog_view.cc index fbfdfc9de..5f153ef 100644 --- a/chrome/browser/ui/views/media_router/media_remoting_dialog_view.cc +++ b/chrome/browser/ui/views/media_router/media_remoting_dialog_view.cc
@@ -158,7 +158,7 @@ void MediaRemotingDialogView::ReportPermission(bool allowed) { DCHECK(remember_choice_checkbox_); DCHECK(permission_callback_); - if (remember_choice_checkbox_->checked()) { + if (remember_choice_checkbox_->GetChecked()) { pref_service_->SetBoolean(::prefs::kMediaRouterMediaRemotingEnabled, allowed); }
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views.cc b/chrome/browser/ui/views/overlay/overlay_window_views.cc index 02709569..40754ab 100644 --- a/chrome/browser/ui/views/overlay/overlay_window_views.cc +++ b/chrome/browser/ui/views/overlay/overlay_window_views.cc
@@ -867,8 +867,7 @@ #if defined(OS_WIN) if (event->type() == ui::ET_KEY_PRESSED && event->IsAltDown() && event->key_code() == ui::VKEY_F4) { - controller_->Close(true /* should_pause_video */, - true /* should_reset_pip_player */); + controller_->Close(true /* should_pause_video */); event->SetHandled(); } #endif // OS_WIN @@ -933,8 +932,7 @@ RecordTapGesture(OverlayWindowControl::kSkipAd); event->SetHandled(); } else if (GetCloseControlsBounds().Contains(event->location())) { - controller_->Close(true /* should_pause_video */, - true /* should_reset_pip_player */); + controller_->Close(true /* should_pause_video */); RecordTapGesture(OverlayWindowControl::kClose); event->SetHandled(); } else if (GetPlayPauseControlsBounds().Contains(event->location())) { @@ -970,8 +968,7 @@ } if (sender == close_controls_view_.get()) { - controller_->Close(true /* should_pause_video */, - true /* should_reset_pip_player */); + controller_->Close(true /* should_pause_video */); RecordButtonPressed(OverlayWindowControl::kClose); }
diff --git a/chrome/browser/ui/views/session_crashed_bubble_view.cc b/chrome/browser/ui/views/session_crashed_bubble_view.cc index 1342197..43cfe98 100644 --- a/chrome/browser/ui/views/session_crashed_bubble_view.cc +++ b/chrome/browser/ui/views/session_crashed_bubble_view.cc
@@ -357,7 +357,7 @@ void SessionCrashedBubbleView::MaybeEnableUma() { // Record user's choice for opt-in in to UMA. // There's no opt-out choice in the crash restore bubble. - if (uma_option_ && uma_option_->checked()) { + if (uma_option_ && uma_option_->GetChecked()) { ChangeMetricsReportingState(true); RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_UMA_OPTIN); }
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc index 38fc679..0f8ec8b 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc +++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc
@@ -140,6 +140,7 @@ base::TimeDelta::FromMilliseconds(200); set_animation_state(FadeAnimationState::FADE_IN); widget_->SetOpacity(0); + widget_->Show(); fade_animation_ = std::make_unique<gfx::LinearAnimation>(this); fade_animation_->SetDuration(kFadeInDuration); fade_animation_->Start(); @@ -329,6 +330,16 @@ TabHoverCardBubbleView::~TabHoverCardBubbleView() = default; void TabHoverCardBubbleView::UpdateAndShow(Tab* tab) { + // If less than |kShowWithoutDelayTimeBuffer| time has passed since the hover + // card was last visible then it is shown immediately. This is to account for + // if hover unintentionally leaves the tab strip. + constexpr base::TimeDelta kShowWithoutDelayTimeBuffer = + base::TimeDelta::FromMilliseconds(500); + base::TimeDelta elapsed_time = + base::TimeTicks::Now() - last_visible_timestamp_; + bool show_immediately = !last_visible_timestamp_.is_null() && + elapsed_time <= kShowWithoutDelayTimeBuffer; + if (preview_image_) preview_image_->SetVisible(!tab->IsActive()); @@ -341,18 +352,22 @@ fade_animation_delegate_->CancelFadeOut(); - // Start trigger timer if necessary. if (!widget_->IsVisible()) { - // Note that this will restart the timer if it is already running. If the - // hover cards are not yet visible, moving the cursor within the tabstrip - // will not trigger the hover cards. - delayed_show_timer_.Start(FROM_HERE, GetDelay(tab->width()), this, - &TabHoverCardBubbleView::FadeInToShow); + if (disable_animations_for_testing_ || show_immediately) { + widget_->Show(); + } else { + // Note that this will restart the timer if it is already running. If the + // hover cards are not yet visible, moving the cursor within the tabstrip + // will not trigger the hover cards. + delayed_show_timer_.Start(FROM_HERE, GetDelay(tab->width()), this, + &TabHoverCardBubbleView::FadeInToShow); + } } } void TabHoverCardBubbleView::FadeOutToHide() { delayed_show_timer_.Stop(); + last_visible_timestamp_ = base::TimeTicks::Now(); if (disable_animations_for_testing_) { widget_->Hide(); } else { @@ -402,9 +417,7 @@ } void TabHoverCardBubbleView::FadeInToShow() { - widget_->Show(); - if (!disable_animations_for_testing_) - fade_animation_delegate_->FadeIn(); + fade_animation_delegate_->FadeIn(); } void TabHoverCardBubbleView::UpdateCardContent(TabRendererData data) {
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h index 8df3137..75b38d8 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h +++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h
@@ -70,6 +70,8 @@ // Used to animate the tab hover card's movement between tabs. std::unique_ptr<WidgetSlideAnimationDelegate> slide_animation_delegate_; + base::TimeTicks last_visible_timestamp_; + views::Widget* widget_ = nullptr; views::Label* title_label_ = nullptr; views::Label* domain_label_ = nullptr;
diff --git a/chrome/browser/ui/views/tabs/tab_icon.cc b/chrome/browser/ui/views/tabs/tab_icon.cc index abc8f3a..660f6da 100644 --- a/chrome/browser/ui/views/tabs/tab_icon.cc +++ b/chrome/browser/ui/views/tabs/tab_icon.cc
@@ -31,10 +31,6 @@ namespace { -bool UseNewLoadingAnimation() { - return base::FeatureList::IsEnabled(features::kNewTabLoadingAnimation); -} - constexpr int kAttentionIndicatorRadius = 3; constexpr int kNewLoadingAnimationStrokeWidthDp = 2; @@ -84,6 +80,8 @@ TabIcon::TabIcon() : clock_(base::DefaultTickClock::GetInstance()), + use_new_loading_animation_( + base::FeatureList::IsEnabled(features::kNewTabLoadingAnimation)), favicon_fade_in_animation_(base::TimeDelta::FromMilliseconds(250), gfx::LinearAnimation::kDefaultFrameRate, this) { @@ -183,7 +181,7 @@ std::min(gfx::kFaviconSize, contents_bounds.height())); // The old animation replaces the favicon and should early-abort. - if (!UseNewLoadingAnimation() && ShowingLoadingAnimation()) { + if (!use_new_loading_animation_ && ShowingLoadingAnimation()) { PaintLoadingAnimation(canvas, icon_bounds); return; } @@ -251,7 +249,7 @@ void TabIcon::PaintLoadingAnimation(gfx::Canvas* canvas, gfx::Rect bounds) { const ui::ThemeProvider* tp = GetThemeProvider(); base::Optional<SkScalar> stroke_width; - if (UseNewLoadingAnimation()) + if (use_new_loading_animation_) stroke_width = kNewLoadingAnimationStrokeWidthDp; if (network_state_ == TabNetworkState::kWaiting) { @@ -370,7 +368,7 @@ const bool was_animated = NetworkStateIsAnimated(network_state_); network_state_ = network_state; const bool is_animated = NetworkStateIsAnimated(network_state_); - if (UseNewLoadingAnimation() && was_animated != is_animated) { + if (use_new_loading_animation_ && was_animated != is_animated) { if (was_animated && HasNonDefaultFavicon()) { favicon_fade_in_animation_.Start(); } else {
diff --git a/chrome/browser/ui/views/tabs/tab_icon.h b/chrome/browser/ui/views/tabs/tab_icon.h index 1acd727..6d9bf147 100644 --- a/chrome/browser/ui/views/tabs/tab_icon.h +++ b/chrome/browser/ui/views/tabs/tab_icon.h
@@ -123,6 +123,8 @@ bool is_crashed_ = false; int attention_types_ = 0; // Bitmask of AttentionType. + const bool use_new_loading_animation_; + // Value from last call to SetNetworkState. When true, the network loading // animation will not be shown. bool inhibit_loading_animation_ = false;
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.cc b/chrome/browser/ui/views/toolbar/toolbar_view.cc index f7628b7d..2360e30 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_view.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_view.cc
@@ -106,7 +106,7 @@ if (browser->SupportsWindowFeature(Browser::FEATURE_TABSTRIP)) return ToolbarView::DisplayMode::NORMAL; - if (browser->web_app_controller() && + if (browser->app_controller() && web_app::AppBrowserController::IsForExperimentalWebAppBrowser(browser) && base::FeatureList::IsEnabled(features::kDesktopPWAsCustomTabUI)) return ToolbarView::DisplayMode::CUSTOM_TAB;
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view.cc b/chrome/browser/ui/views/translate/translate_bubble_view.cc index f883cde..5ce3232c 100644 --- a/chrome/browser/ui/views/translate/translate_bubble_view.cc +++ b/chrome/browser/ui/views/translate/translate_bubble_view.cc
@@ -234,7 +234,7 @@ case BUTTON_ID_ALWAYS_TRANSLATE: { views::Checkbox* always_checkbox = GetAlwaysTranslateCheckbox(); DCHECK(always_checkbox); - should_always_translate_ = always_checkbox->checked(); + should_always_translate_ = always_checkbox->GetChecked(); translate::ReportUiAction(should_always_translate_ ? translate::ALWAYS_TRANSLATE_CHECKED : translate::ALWAYS_TRANSLATE_UNCHECKED);
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view_unittest.cc b/chrome/browser/ui/views/translate/translate_bubble_view_unittest.cc index fe9b666..58ed13c2 100644 --- a/chrome/browser/ui/views/translate/translate_bubble_view_unittest.cc +++ b/chrome/browser/ui/views/translate/translate_bubble_view_unittest.cc
@@ -289,7 +289,7 @@ // Check the initial state. EXPECT_FALSE(mock_model_->should_always_translate_); EXPECT_EQ(0, mock_model_->set_always_translate_called_count_); - EXPECT_FALSE(bubble_->advanced_always_translate_checkbox_->checked()); + EXPECT_FALSE(bubble_->advanced_always_translate_checkbox_->GetChecked()); // Click the checkbox. The state is not saved yet. bubble_->advanced_always_translate_checkbox_->SetChecked(true); @@ -313,7 +313,7 @@ // Check the initial state. EXPECT_FALSE(mock_model_->should_always_translate_); EXPECT_EQ(0, mock_model_->set_always_translate_called_count_); - EXPECT_FALSE(bubble_->advanced_always_translate_checkbox_->checked()); + EXPECT_FALSE(bubble_->advanced_always_translate_checkbox_->GetChecked()); // Click the checkbox. The state is not saved yet. bubble_->advanced_always_translate_checkbox_->SetChecked(true);
diff --git a/chrome/browser/ui/views/uninstall_view.cc b/chrome/browser/ui/views/uninstall_view.cc index 45e6891..a48ef7b4 100644 --- a/chrome/browser/ui/views/uninstall_view.cc +++ b/chrome/browser/ui/views/uninstall_view.cc
@@ -126,9 +126,9 @@ bool UninstallView::Accept() { user_selection_ = service_manager::RESULT_CODE_NORMAL_EXIT; - if (delete_profile_->checked()) + if (delete_profile_->GetChecked()) user_selection_ = chrome::RESULT_CODE_UNINSTALL_DELETE_PROFILE; - if (change_default_browser_ && change_default_browser_->checked()) { + if (change_default_browser_ && change_default_browser_->GetChecked()) { BrowsersMap::const_iterator i = browsers_->begin(); std::advance(i, browsers_combo_->GetSelectedIndex()); base::LaunchOptions options; @@ -156,7 +156,7 @@ if (change_default_browser_ == sender) { // Disable the browsers combobox if the user unchecks the checkbox. DCHECK(browsers_combo_); - browsers_combo_->SetEnabled(change_default_browser_->checked()); + browsers_combo_->SetEnabled(change_default_browser_->GetChecked()); } }
diff --git a/chrome/browser/ui/web_applications/app_browser_controller.cc b/chrome/browser/ui/web_applications/app_browser_controller.cc index c3c2c870..64d1252 100644 --- a/chrome/browser/ui/web_applications/app_browser_controller.cc +++ b/chrome/browser/ui/web_applications/app_browser_controller.cc
@@ -23,8 +23,8 @@ // static bool AppBrowserController::IsForExperimentalWebAppBrowser( const Browser* browser) { - return browser && browser->web_app_controller() && - browser->web_app_controller()->IsForExperimentalWebAppBrowser(); + return browser && browser->app_controller() && + browser->app_controller()->IsForExperimentalWebAppBrowser(); } // static
diff --git a/chrome/browser/ui/web_applications/bookmark_app_browsertest.cc b/chrome/browser/ui/web_applications/bookmark_app_browsertest.cc index 0a6f876..62e4a7ba 100644 --- a/chrome/browser/ui/web_applications/bookmark_app_browsertest.cc +++ b/chrome/browser/ui/web_applications/bookmark_app_browsertest.cc
@@ -261,7 +261,7 @@ InstallBookmarkAppAndCountApps(web_app_info); Browser* browser = LaunchBrowserForAppInTab(app); - EXPECT_FALSE(browser->web_app_controller()); + EXPECT_FALSE(browser->app_controller()); NavigateToURLAndWait(browser, example_url); Histograms histograms; @@ -292,7 +292,7 @@ EXPECT_EQ(web_app::GetAppIdFromApplicationName(browser->app_name()), app->id()); - EXPECT_TRUE(browser->web_app_controller()); + EXPECT_TRUE(browser->app_controller()); NavigateToURLAndWait(browser, example_url); Histograms histograms; @@ -433,7 +433,7 @@ InstallBookmarkAppAndCountApps(web_app_info); Browser* browser = LaunchBrowserForAppInTab(app); - EXPECT_FALSE(browser->web_app_controller()); + EXPECT_FALSE(browser->app_controller()); NavigateToURLAndWait(browser, app_url); {
diff --git a/chrome/browser/ui/web_applications/web_app_metrics.cc b/chrome/browser/ui/web_applications/web_app_metrics.cc index a2605c3..a57382b 100644 --- a/chrome/browser/ui/web_applications/web_app_metrics.cc +++ b/chrome/browser/ui/web_applications/web_app_metrics.cc
@@ -102,7 +102,7 @@ return; // No HostedAppBrowserController if app is running as a tab in common browser. - const bool in_window = !!browser->web_app_controller(); + const bool in_window = !!browser->app_controller(); const bool from_install_button = tab_helper->IsFromInstallButton(); const bool user_installed = tab_helper->IsUserInstalled();
diff --git a/chrome/browser/ui/web_applications/web_app_ui_delegate_impl.cc b/chrome/browser/ui/web_applications/web_app_ui_delegate_impl.cc index 64cbe8b..5ef0980 100644 --- a/chrome/browser/ui/web_applications/web_app_ui_delegate_impl.cc +++ b/chrome/browser/ui/web_applications/web_app_ui_delegate_impl.cc
@@ -99,10 +99,10 @@ if (browser->profile() != profile_) return base::nullopt; - if (!browser->web_app_controller()) + if (!browser->app_controller()) return base::nullopt; - return browser->web_app_controller()->GetAppId(); + return browser->app_controller()->GetAppId(); } } // namespace web_app
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc index 7027356..d5baaad 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -147,6 +147,7 @@ #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_service.h" #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_service_factory.h" #include "chrome/browser/chromeos/secure_channel/secure_channel_client_provider.h" +#include "chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_ui.h" #include "chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_ui.h" #include "chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_ui.h" #include "chrome/browser/ui/webui/chromeos/bluetooth_pairing_dialog.h" @@ -174,6 +175,7 @@ #include "chromeos/components/multidevice/debug_webui/proximity_auth_ui.h" #include "chromeos/components/multidevice/debug_webui/url_constants.h" #include "chromeos/constants/chromeos_features.h" +#include "chromeos/constants/chromeos_switches.h" #include "components/arc/arc_features.h" #endif @@ -499,6 +501,10 @@ } if (url.host_piece() == chrome::kChromeUIAccountManagerWelcomeHost) return &NewWebUI<chromeos::AccountManagerWelcomeUI>; + if (chromeos::switches::IsAddSupervisionEnabled()) { + if (url.host_piece() == chrome::kChromeUIAddSupervisionHost) + return &NewWebUI<chromeos::AddSupervisionUI>; + } if (url.host_piece() == chrome::kChromeUIBluetoothPairingHost) return &NewWebUI<chromeos::BluetoothPairingDialogUI>; if (url.host_piece() == chrome::kChromeUICellularSetupHost)
diff --git a/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_ui.cc b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_ui.cc new file mode 100644 index 0000000..bcabd38 --- /dev/null +++ b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_ui.cc
@@ -0,0 +1,72 @@ +// 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/ui/webui/chromeos/add_supervision/add_supervision_ui.h" + +#include <memory> +#include <utility> + +#include "base/bind.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_handler.h" +#include "chrome/common/webui_url_constants.h" +#include "chrome/grit/browser_resources.h" +#include "chrome/grit/generated_resources.h" +#include "content/public/browser/web_ui.h" +#include "content/public/browser/web_ui_data_source.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/resources/grit/ui_resources.h" + +namespace chromeos { + +const char kAddSupervisionURL[] = + "https://families.google.com/supervision/chrome"; +const char kAddSupervisionEventOriginFilter[] = "https://families.google.com"; + +AddSupervisionUI::AddSupervisionUI(content::WebUI* web_ui) + : ui::MojoWebUIController(web_ui) { + // Register the Mojo API handler. + AddHandlerToRegistry(base::BindRepeating( + &AddSupervisionUI::BindAddSupervisionHandler, base::Unretained(this))); + + // Set up the basic page framework. + SetupResources(); +} + +void AddSupervisionUI::SetupResources() { + Profile* profile = Profile::FromWebUI(web_ui()); + std::unique_ptr<content::WebUIDataSource> source( + content::WebUIDataSource::Create(chrome::kChromeUIAddSupervisionHost)); + + source->AddResourcePath("post_message_api.js", + IDR_ADD_SUPERVISION_POST_MESSAGE_API_JS); + source->AddResourcePath("add_supervision_api_server.js", + IDR_ADD_SUPERVISION_API_SERVER_JS); + source->AddResourcePath("add_supervision.js", IDR_ADD_SUPERVISION_JS); + source->AddLocalizedString("pageTitle", IDS_ADD_SUPERVISION_PAGE_TITLE); + + // Full paths (relative to src) are important for Mojom generated files. + source->AddResourcePath( + "chrome/browser/ui/webui/chromeos/add_supervision/" + "add_supervision.mojom-lite.js", + IDR_ADD_SUPERVISION_MOJOM_LITE_JS); + + source->SetJsonPath("strings.js"); + source->SetDefaultResource(IDR_ADD_SUPERVISION_HTML); + source->AddString("webviewUrl", kAddSupervisionURL); + source->AddString("eventOriginFilter", kAddSupervisionEventOriginFilter); + + content::WebUIDataSource::Add(profile, source.release()); +} + +AddSupervisionUI::~AddSupervisionUI() = default; + +void AddSupervisionUI::BindAddSupervisionHandler( + add_supervision::mojom::AddSupervisionHandlerRequest request) { + mojo_api_handler_.reset( + new AddSupervisionHandler(std::move(request), web_ui())); +} + +} // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_ui.h b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_ui.h new file mode 100644 index 0000000..336956d --- /dev/null +++ b/chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_ui.h
@@ -0,0 +1,35 @@ +// 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_UI_WEBUI_CHROMEOS_ADD_SUPERVISION_ADD_SUPERVISION_UI_H_ +#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_ADD_SUPERVISION_ADD_SUPERVISION_UI_H_ + +#include <memory> + +#include "base/macros.h" +#include "chrome/browser/ui/webui/chromeos/add_supervision/add_supervision.mojom.h" +#include "ui/webui/mojo_web_ui_controller.h" + +namespace chromeos { + +// Controller for chrome://add-supervision +class AddSupervisionUI : public ui::MojoWebUIController { + public: + explicit AddSupervisionUI(content::WebUI* web_ui); + ~AddSupervisionUI() override; + + private: + void BindAddSupervisionHandler( + add_supervision::mojom::AddSupervisionHandlerRequest request); + void SetupResources(); + + std::unique_ptr<add_supervision::mojom::AddSupervisionHandler> + mojo_api_handler_; + + DISALLOW_COPY_AND_ASSIGN(AddSupervisionUI); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_UI_WEBUI_CHROMEOS_ADD_SUPERVISION_ADD_SUPERVISION_UI_H_
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc b/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc index 27a76ee..344eb15 100644 --- a/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc +++ b/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc
@@ -116,7 +116,6 @@ void InlineLoginHandlerChromeOS::SetExtraInitParams( base::DictionaryValue& params) { const GaiaUrls* const gaia_urls = GaiaUrls::GetInstance(); - params.SetKey("isNewGaiaFlow", base::Value(true)); params.SetKey("clientId", base::Value(gaia_urls->oauth2_chrome_client_id())); const GURL& url = gaia_urls->embedded_setup_chromeos_url(2U);
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc index 2559da7..51db0a4a 100644 --- a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc +++ b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
@@ -503,7 +503,6 @@ HandlerSigninReason reason = GetHandlerSigninReason(current_url); const GURL& url = GaiaUrls::GetInstance()->embedded_signin_url(); - params.SetBoolean("isNewGaiaFlow", true); params.SetString("clientId", GaiaUrls::GetInstance()->oauth2_chrome_client_id()); params.SetString("gaiaPath", url.path().substr(1));
diff --git a/chrome/browser/vr/service/OWNERS b/chrome/browser/vr/service/OWNERS index 84a66d7..bff1dd1a 100644 --- a/chrome/browser/vr/service/OWNERS +++ b/chrome/browser/vr/service/OWNERS
@@ -1,3 +1,4 @@ +alcooper@chromium.org billorr@chromium.org # TEAM: xr-dev@chromium.org
diff --git a/chrome/browser/web_applications/bookmark_apps/system_web_app_manager_browsertest.cc b/chrome/browser/web_applications/bookmark_apps/system_web_app_manager_browsertest.cc index cb297e6d..db54e111 100644 --- a/chrome/browser/web_applications/bookmark_apps/system_web_app_manager_browsertest.cc +++ b/chrome/browser/web_applications/bookmark_apps/system_web_app_manager_browsertest.cc
@@ -180,7 +180,7 @@ IN_PROC_BROWSER_TEST_F(SystemWebAppManagerBrowserTest, Install) { const extensions::Extension* app = static_cast<extensions::HostedAppBrowserController*>( - WaitForSystemAppInstallAndLaunch()->web_app_controller()) + WaitForSystemAppInstallAndLaunch()->app_controller()) ->GetExtensionForTesting(); EXPECT_EQ("Test System App", app->name()); EXPECT_EQ(SkColorSetRGB(0, 0xFF, 0),
diff --git a/chrome/browser/web_applications/components/web_app_shortcut_mac.h b/chrome/browser/web_applications/components/web_app_shortcut_mac.h index 13e4ac1..7f888b0 100644 --- a/chrome/browser/web_applications/components/web_app_shortcut_mac.h +++ b/chrome/browser/web_applications/components/web_app_shortcut_mac.h
@@ -124,7 +124,8 @@ std::string GetInternalBundleIdentifier() const; // Copies the app loader template into a temporary directory and fills in all - // relevant information. + // relevant information. This works around a Finder bug where the app's icon + // doesn't properly update. bool BuildShortcut(const base::FilePath& staging_path) const; // Builds a shortcut and copies it to the specified app paths. Populates
diff --git a/chrome/browser/web_applications/components/web_app_shortcut_mac.mm b/chrome/browser/web_applications/components/web_app_shortcut_mac.mm index 878bf53..d67902f 100644 --- a/chrome/browser/web_applications/components/web_app_shortcut_mac.mm +++ b/chrome/browser/web_applications/components/web_app_shortcut_mac.mm
@@ -19,6 +19,7 @@ #include "base/files/file_enumerator.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" +#include "base/mac/bundle_locations.h" #include "base/mac/foundation_util.h" #import "base/mac/launch_services_util.h" #include "base/mac/mac_util.h" @@ -427,11 +428,6 @@ base::BindOnce(std::move(launched_callback), base::Process())); } -base::FilePath GetAppLoaderPath() { - return base::mac::PathForFrameworkBundleResource( - base::mac::NSToCFCast(@"app_mode_loader.app")); -} - base::FilePath GetLocalizableAppShortcutsSubdirName() { static const char kChromiumAppDirName[] = "Chromium Apps.localized"; static const char kChromeAppDirName[] = "Chrome Apps.localized"; @@ -713,11 +709,62 @@ bool WebAppShortcutCreator::BuildShortcut( const base::FilePath& staging_path) const { - // Update the app's plist and icon in a temp directory. This works around - // a Finder bug where the app's icon doesn't properly update. - if (!base::CopyDirectory(GetAppLoaderPath(), staging_path, true)) { - LOG(ERROR) << "Copying app to staging path: " << staging_path.value() - << " failed."; + if (!base::DirectoryExists(staging_path.DirName())) { + LOG(ERROR) << "Staging path directory does not exit: " + << staging_path.DirName(); + return false; + } + + const base::FilePath framework_bundle_path = base::mac::FrameworkBundlePath(); + + const base::FilePath executable_path = + framework_bundle_path.Append("Helpers").Append("app_mode_loader"); + const base::FilePath plist_path = + framework_bundle_path.Append("Resources").Append("app_mode-Info.plist"); + + const base::FilePath destination_contents_path = + staging_path.Append("Contents"); + const base::FilePath destination_executable_path = + destination_contents_path.Append("MacOS"); + + // First create the .app bundle directory structure. + // Use NSFileManager so that the permissions can be set appropriately. The + // base::CreateDirectory() routine forces mode 0700. + NSError* error = nil; + if (![[NSFileManager defaultManager] + createDirectoryAtURL:base::mac::FilePathToNSURL( + destination_executable_path) + withIntermediateDirectories:YES + attributes:@{ + NSFilePosixPermissions : @(0755) + } + error:&error]) { + LOG(ERROR) << "Failed to create destination executable path: " + << destination_executable_path + << ", error=" << base::SysNSStringToUTF8([error description]); + return false; + } + + // Copy the executable file. + if (!base::CopyFile(executable_path, destination_executable_path.Append( + executable_path.BaseName()))) { + LOG(ERROR) << "Failed to copy executable: " << executable_path; + return false; + } + + // Copy the Info.plist. + if (!base::CopyFile(plist_path, + destination_contents_path.Append("Info.plist"))) { + LOG(ERROR) << "Failed to copy plist: " << plist_path; + return false; + } + + // Write the PkgInfo file. + constexpr char kPkgInfoData[] = "APPL????"; + constexpr size_t kPkgInfoDataSize = base::size(kPkgInfoData) - 1; + if (base::WriteFile(destination_contents_path.Append("PkgInfo"), kPkgInfoData, + kPkgInfoDataSize) != kPkgInfoDataSize) { + LOG(ERROR) << "Failed to write PkgInfo file: " << destination_contents_path; return false; }
diff --git a/chrome/browser/win/titlebar_config.cc b/chrome/browser/win/titlebar_config.cc index 4b2bff5..decdabf4 100644 --- a/chrome/browser/win/titlebar_config.cc +++ b/chrome/browser/win/titlebar_config.cc
@@ -9,17 +9,17 @@ #include "chrome/common/chrome_switches.h" #include "ui/native_theme/native_theme_win.h" -// Enables custom-drawing the titlebar and tabstrip background so that we can -// paint it various gray colors instead of the default #FFFFFF. -const base::Feature kWindows10CustomTitlebar{"Windows10CustomTitlebar", - base::FEATURE_ENABLED_BY_DEFAULT}; - bool ShouldCustomDrawSystemTitlebar() { + // Cache flag lookup. + static const bool custom_titlebar_disabled = + base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableWindows10CustomTitlebar); + // TODO(bsep): We would like the custom-draw the titlebar in high-contrast // mode so that we can correctly draw the caption buttons on the left in RTL // mode. But they require a different style and color selection that isn't // currently implemented. - return !ui::NativeTheme::GetInstanceForNativeUi()->UsesHighContrastColors() && - base::FeatureList::IsEnabled(kWindows10CustomTitlebar) && + return !custom_titlebar_disabled && + !ui::NativeTheme::GetInstanceForNativeUi()->UsesHighContrastColors() && base::win::GetVersion() >= base::win::Version::WIN10; }
diff --git a/chrome/chrome_elf/chrome_elf_main.cc b/chrome/chrome_elf/chrome_elf_main.cc index c6cd0c8..6f0f867 100644 --- a/chrome/chrome_elf/chrome_elf_main.cc +++ b/chrome/chrome_elf/chrome_elf_main.cc
@@ -8,7 +8,6 @@ #include <windows.h> #include "chrome/chrome_elf/blacklist/blacklist.h" -#include "chrome/chrome_elf/chrome_elf_security.h" #include "chrome/chrome_elf/crash/crash_helper.h" #include "chrome/chrome_elf/third_party_dlls/main.h" #include "chrome/install_static/install_details.h" @@ -71,9 +70,6 @@ if (install_static::IsNonBrowserProcess()) return TRUE; - // Disable legacy hooking. - elf_security::EarlyBrowserSecurity(); - __try { // Initialize blacklist before initializing third_party_dlls. // Note: "blacklist" is deprecated in favor of "third_party_dlls", but
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 74f7163..e83c2d34 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc
@@ -797,6 +797,10 @@ #endif // defined(OS_MACOSX) #if defined(OS_WIN) +// Disables custom-drawing the window titlebar on Windows 10. +const char kDisableWindows10CustomTitlebar[] = + "disable-windows10-custom-titlebar"; + // Fallback to XPS. By default connector uses CDD. const char kEnableCloudPrintXps[] = "enable-cloud-print-xps";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index de75a32..4f2eba8 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h
@@ -242,6 +242,7 @@ #endif // defined(OS_MACOSX) #if defined(OS_WIN) +extern const char kDisableWindows10CustomTitlebar[]; extern const char kEnableCloudPrintXps[]; extern const char kEnableProfileShortcutManager[]; extern const char kHideIcons[];
diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json index cb351822..b57db4b 100644 --- a/chrome/common/extensions/api/_api_features.json +++ b/chrome/common/extensions/api/_api_features.json
@@ -241,7 +241,8 @@ "chrome://mobilesetup/*", "chrome://oobe/*", "chrome://password-change/*", - "chrome://assistant-optin/*" + "chrome://assistant-optin/*", + "chrome://add-supervision/*" ] }], "cloudPrintPrivate": {
diff --git a/chrome/common/extensions/chrome_extensions_client.cc b/chrome/common/extensions/chrome_extensions_client.cc index a338dc2..521352e 100644 --- a/chrome/common/extensions/chrome_extensions_client.cc +++ b/chrome/common/extensions/chrome_extensions_client.cc
@@ -52,34 +52,6 @@ const char kThumbsWhiteListedExtension[] = "khopmbdjffemhegeeobelklnbglcdgfh"; -// Mirrors version_info::Channel for histograms. -enum ChromeChannelForHistogram { - CHANNEL_UNKNOWN, - CHANNEL_CANARY, - CHANNEL_DEV, - CHANNEL_BETA, - CHANNEL_STABLE, - NUM_CHANNELS_FOR_HISTOGRAM -}; - -ChromeChannelForHistogram GetChromeChannelForHistogram( - version_info::Channel channel) { - switch (channel) { - case version_info::Channel::UNKNOWN: - return CHANNEL_UNKNOWN; - case version_info::Channel::CANARY: - return CHANNEL_CANARY; - case version_info::Channel::DEV: - return CHANNEL_DEV; - case version_info::Channel::BETA: - return CHANNEL_BETA; - case version_info::Channel::STABLE: - return CHANNEL_STABLE; - } - NOTREACHED() << static_cast<int>(channel); - return CHANNEL_UNKNOWN; -} - } // namespace ChromeExtensionsClient::ChromeExtensionsClient() { @@ -204,12 +176,6 @@ return true; } -void ChromeExtensionsClient::RecordDidSuppressFatalError() { - UMA_HISTOGRAM_ENUMERATION("Extensions.DidSuppressJavaScriptException", - GetChromeChannelForHistogram(GetCurrentChannel()), - NUM_CHANNELS_FOR_HISTOGRAM); -} - const GURL& ChromeExtensionsClient::GetWebstoreBaseURL() const { return webstore_base_url_; }
diff --git a/chrome/common/extensions/chrome_extensions_client.h b/chrome/common/extensions/chrome_extensions_client.h index 5272ed00..5eb6613 100644 --- a/chrome/common/extensions/chrome_extensions_client.h +++ b/chrome/common/extensions/chrome_extensions_client.h
@@ -39,7 +39,6 @@ const APIPermissionSet& api_permissions) const override; bool IsScriptableURL(const GURL& url, std::string* error) const override; bool ShouldSuppressFatalErrors() const override; - void RecordDidSuppressFatalError() override; const GURL& GetWebstoreBaseURL() const override; const GURL& GetWebstoreUpdateURL() const override; bool IsBlacklistUpdateURL(const GURL& url) const override;
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc index 43395bf..590dd134 100644 --- a/chrome/common/webui_url_constants.cc +++ b/chrome/common/webui_url_constants.cc
@@ -189,6 +189,8 @@ const char kChromeUIAccountManagerWelcomeURL[] = "chrome://account-manager-welcome"; const char kChromeUIActivationMessageHost[] = "activationmessage"; +const char kChromeUIAddSupervisionHost[] = "add-supervision"; +const char kChromeUIAddSupervisionURL[] = "chrome://add-supervision/"; const char kChromeUIArcGraphicsTracingHost[] = "arc-graphics-tracing"; const char kChromeUIArcGraphicsTracingURL[] = "chrome://arc-graphics-tracing/"; const char kChromeUIAssistantOptInHost[] = "assistant-optin"; @@ -251,6 +253,7 @@ static const char* const kHosts[] = { kChromeUIAccountManagerWelcomeHost, kChromeUIActivationMessageHost, + kChromeUIAddSupervisionHost, kChromeUIAssistantOptInHost, kChromeUIBluetoothPairingHost, kChromeUICellularSetupHost,
diff --git a/chrome/common/webui_url_constants.h b/chrome/common/webui_url_constants.h index 0615e93..f04e885 100644 --- a/chrome/common/webui_url_constants.h +++ b/chrome/common/webui_url_constants.h
@@ -189,6 +189,8 @@ extern const char kChromeUIAccountManagerWelcomeHost[]; extern const char kChromeUIAccountManagerWelcomeURL[]; extern const char kChromeUIActivationMessageHost[]; +extern const char kChromeUIAddSupervisionHost[]; +extern const char kChromeUIAddSupervisionURL[]; extern const char kChromeUIArcGraphicsTracingHost[]; extern const char kChromeUIArcGraphicsTracingURL[]; extern const char kChromeUIAssistantOptInHost[];
diff --git a/chrome/installer/mac/BUILD.gn b/chrome/installer/mac/BUILD.gn index 760cb9e..3bdda5d 100644 --- a/chrome/installer/mac/BUILD.gn +++ b/chrome/installer/mac/BUILD.gn
@@ -23,22 +23,14 @@ script = "//build/gn_run_binary.py" shell_script = "//chrome/installer/mac/make_signers.sh" - deps = [ - ":copy_variables", - ] - inputs = [ script, shell_script, - "sign_app.sh.in", - "sign_versioned_dir.sh.in", "app_resource_rules.plist.in", "//chrome/VERSION", ] outputs = [ - "$_packaging_dir/sign_app.sh", - "$_packaging_dir/sign_versioned_dir.sh", "$_packaging_dir/app_resource_rules.plist", ] @@ -50,19 +42,6 @@ ] } -copy("copy_variables") { - visibility = [ - ":make_signers", - ":copies", - ] - sources = [ - "variables.sh", - ] - outputs = [ - "$_packaging_dir/{{source_file_part}}", - ] -} - process_version_rc_template("sign_config") { visibility = [ ":copy_signing" ] @@ -111,7 +90,6 @@ deps = [ ":copy_signing", - ":copy_variables", "//chrome:entitlements", "//chrome/installer/mac/third_party/bsdiff:goobsdiff", "//chrome/installer/mac/third_party/bsdiff:goobspatch", @@ -132,7 +110,6 @@ "dmgdiffer.sh", "pkg-dmg", "sign_chrome.py", - "sign_installer_tools.sh", ] if (is_chrome_branded) { @@ -150,8 +127,6 @@ "internal/chrome_dmg_background.png", "internal/chrome_dmg_dsstore", "internal/chrome_dmg_icon.icns", - "internal/generate_dmgs", - "internal/signing_common.sh", ] }
diff --git a/chrome/installer/mac/make_signers.sh b/chrome/installer/mac/make_signers.sh index 57d76282..f6272fb7 100755 --- a/chrome/installer/mac/make_signers.sh +++ b/chrome/installer/mac/make_signers.sh
@@ -38,8 +38,6 @@ script_dir="$(dirname "${0}")" in_files=( - "${script_dir}/sign_app.sh.in" - "${script_dir}/sign_versioned_dir.sh.in" "${script_dir}/app_resource_rules.plist.in" )
diff --git a/chrome/installer/mac/sign_app.sh.in b/chrome/installer/mac/sign_app.sh.in deleted file mode 100644 index 16edd99..0000000 --- a/chrome/installer/mac/sign_app.sh.in +++ /dev/null
@@ -1,142 +0,0 @@ -#!/bin/bash -p - -# Copyright (c) 2012 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# Using codesign, sign the application. After signing, the signatures on the -# inner bundle components are verified, and the application's own signature is -# verified. Inner bundle components are expected to be signed before this -# script is called. See sign_versioned_dir.sh.in. - -set -eux - -# Environment sanitization. Set a known-safe PATH. Clear environment variables -# that might impact the interpreter's operation. The |bash -p| invocation -# on the #! line takes the bite out of BASH_ENV, ENV, and SHELLOPTS (among -# other features), but clearing them here ensures that they won't impact any -# shell scripts used as utility programs. SHELLOPTS is read-only and can't be -# unset, only unexported. -export PATH="/usr/bin:/bin:/usr/sbin:/sbin" -unset BASH_ENV CDPATH ENV GLOBIGNORE IFS POSIXLY_CORRECT -export -n SHELLOPTS - -ME="$(basename "${0}")" -readonly ME - -# Note that |is_development| is tested for string length, not value. -is_development= - -if [[ ${#} -eq 4 || ${#} -eq 6 ]]; then - app_path="${1}" - codesign_keychain="${2}" - codesign_id="${3}" - if [[ "${4}" == "--development" || "${6}" == "--development" ]]; then - is_development=1 - fi -elif [[ ${#} -ne 5 ]]; then - echo "usage: ${ME} app_path codesign_keychain codesign_id \ -provisioning_profile entitlements_plist" >& 2 - exit 1 -else - app_path="${1}" - codesign_keychain="${2}" - codesign_id="${3}" - provisioning_profile="${4}" - entitlements_plist="${5}" -fi - -script_dir="$(dirname "${0}")" -source "${script_dir}/variables.sh" - -# Use custom resource rules for the browser application. -browser_app_rules="${script_dir}/app_resource_rules.plist" - -contents_dir="${app_path}/Contents" -versioned_dir="${contents_dir}/Versions/@VERSION@" - -browser_app="${app_path}" -framework="${versioned_dir}/@MAC_PRODUCT_NAME@ Framework.framework" -notification_service="${framework}/XPCServices/AlertNotificationService.xpc" -crashpad_handler="${framework}/Helpers/chrome_crashpad_handler" -helper_app="${versioned_dir}/@MAC_PRODUCT_NAME@ Helper.app" -app_mode_loader_app="${framework}/Resources/app_mode_loader.app" -app_mode_loader="${app_mode_loader_app}/Contents/MacOS/app_mode_loader" - -libraries_dir="${framework}/Libraries" -libraries=( - "${libraries_dir}/libEGL.dylib" - "${libraries_dir}/libGLESv2.dylib" - "${libraries_dir}/libswiftshader_libEGL.dylib" - "${libraries_dir}/libswiftshader_libGLESv2.dylib" - "${libraries_dir}/WidevineCdm/_platform_specific/mac_x64/libwidevinecdm.dylib" -) - -# Embed the supplied provisioning profile. -if [[ -z "${is_development}" ]]; then - cp "${provisioning_profile}" "${contents_dir}/embedded.provisionprofile" -fi - -requirement="\ -designated => \ -(identifier \"com.google.Chrome\" or \ -identifier \"com.google.Chrome.beta\" or \ -identifier \"com.google.Chrome.dev\" or \ -identifier \"com.google.Chrome.canary\") \ -${requirement_suffix} \ -" - -codesign_cmd=( - codesign --sign "${codesign_id}" --keychain "${codesign_keychain}" - "${browser_app}" - --options "${enforcement_flags_app}" - --resource-rules "${browser_app_rules}" -) -if [[ -z "${is_development}" ]]; then - codesign_cmd+=(--entitlements="${entitlements_plist}") - codesign_cmd+=( -r="${requirement}" ) -fi -"${codesign_cmd[@]}" - -# Show the signature. -codesign --display --verbose=5 -r- "${browser_app}" - -# Verify everything. Check the framework and helper apps to make sure that the -# signatures are present and weren't altered by the signing process. Use -# --ignore-resources on the app mode loader because its signature only covers -# the main executable, not its containing .app bundle. Use --no-strict to -# verify items that use custom resource rules: -# - The outermost brrowser .app -# - The inner .framework, which has a nested component that uses them. -codesign --verify --verbose=6 --deep --no-strict "${browser_app}" -codesign --verify --verbose=6 --deep "${crashpad_handler}" -codesign --verify --verbose=6 --ignore-resources "${app_mode_loader}" -codesign --verify --verbose=6 --deep "${notification_service}" -# Check the framework twice: once deep with no-strict, and once shallow with -# strict verification. -codesign --verify --verbose=6 --deep --no-strict "${framework}" -codesign --verify --verbose=6 --strict "${framework}" -codesign --verify --verbose=6 --deep "${helper_app}" - -for library in "${libraries[@]}"; do - if [ -f "${library}" ]; then - codesign --verify --verbose=6 --deep "${library}" - fi -done - -# Verify with spctl, which uses the same rules that Gatekeeper does for -# validation. This is unreliable on 10.11 where syspolicyd caches assessments -# and becomes confused when a bundle's CFExecutableName changes -# (https://openradar.appspot.com/23614087), so verify a copy at a unique path. -if [[ -z "${is_development}" ]]; then - temp_dir="$(mktemp -d -t "$(basename "${0}")")" - - cleanup() { - set +e - rm -rf "${temp_dir}" - } - trap cleanup EXIT - temp_browser_app="${temp_dir}/$(basename "${browser_app}")" - rsync -a "${browser_app}/" "${temp_browser_app}" - spctl --assess -vv "${temp_browser_app}" -fi
diff --git a/chrome/installer/mac/sign_installer_tools.sh b/chrome/installer/mac/sign_installer_tools.sh deleted file mode 100755 index 3fa50e1..0000000 --- a/chrome/installer/mac/sign_installer_tools.sh +++ /dev/null
@@ -1,75 +0,0 @@ -#!/bin/bash -p - -# Copyright 2015 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# Using codesign, sign the installer tools. After signing, the signatures are -# verified. - -set -eu - -# Environment sanitization. Set a known-safe PATH. Clear environment variables -# that might impact the interpreter's operation. The |bash -p| invocation -# on the #! line takes the bite out of BASH_ENV, ENV, and SHELLOPTS (among -# other features), but clearing them here ensures that they won't impact any -# shell scripts used as utility programs. SHELLOPTS is read-only and can't be -# unset, only unexported. -export PATH="/usr/bin:/bin:/usr/sbin:/sbin" -unset BASH_ENV CDPATH ENV GLOBIGNORE IFS POSIXLY_CORRECT -export -n SHELLOPTS - -ME="$(basename "${0}")" -readonly ME - -if [[ ${#} -ne 3 && ${#} -ne 4 ]]; then - echo "usage: ${ME} packaging_dir codesign_keychain codesign_id \ -[--development]" >& 2 - exit 1 -fi - -packaging_dir="${1}" -codesign_keychain="${2}" -codesign_id="${3}" -is_development= - -if [[ ${#} == 4 && ${4} == "--development" ]]; then - is_development=1 -fi - -script_dir="$(dirname "${0}")" -source "${script_dir}/variables.sh" - -executables=(goobspatch xzdec) -libraries=(liblzma_decompress.dylib) -declare -a everything - -for executable in "${executables[@]}"; do - sign_path="${packaging_dir}/${executable}" - everything+=("${sign_path}") - - codesign_cmd=( - codesign --sign "${codesign_id}" --keychain "${codesign_keychain}" - "${sign_path}" --options "${enforcement_flags_installer_tools}" - ) - - if [[ -z "${is_development}" ]]; then - requirement="designated => identifier \"${executable}\" \ -${requirement_suffix}" - codesign_cmd+=( -r="${requirement}" ) - fi - - "${codesign_cmd[@]}" -done - -for library in "${libraries[@]}"; do - sign_path="${packaging_dir}/${library}" - everything+=("${sign_path}") - - codesign --sign "${codesign_id}" --keychain "${codesign_keychain}" \ - "${sign_path}" -done - -for sign_path in "${everything[@]}"; do - codesign --verify --deep -vvvvvv "${sign_path}" -done
diff --git a/chrome/installer/mac/sign_versioned_dir.sh.in b/chrome/installer/mac/sign_versioned_dir.sh.in deleted file mode 100644 index 95b93ba..0000000 --- a/chrome/installer/mac/sign_versioned_dir.sh.in +++ /dev/null
@@ -1,160 +0,0 @@ -#!/bin/bash -p - -# Copyright (c) 2012 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# Using codesign, sign the contents of the versioned directory. Namely, this -# includes the framework and helper app. After signing, the signatures are -# verified. - -set -eu - -# Environment sanitization. Set a known-safe PATH. Clear environment variables -# that might impact the interpreter's operation. The |bash -p| invocation -# on the #! line takes the bite out of BASH_ENV, ENV, and SHELLOPTS (among -# other features), but clearing them here ensures that they won't impact any -# shell scripts used as utility programs. SHELLOPTS is read-only and can't be -# unset, only unexported. -export PATH="/usr/bin:/bin:/usr/sbin:/sbin" -unset BASH_ENV CDPATH ENV GLOBIGNORE IFS POSIXLY_CORRECT -export -n SHELLOPTS - -ME="$(basename "${0}")" -readonly ME - -script_dir="$(dirname "${0}")" -source "${script_dir}/variables.sh" - -codesign_display_and_verify() { - args=("${@}") - path=${args[0]} - - # --verbose can go up to 6 for --display, but that just shows the hash of each - # ordinary page in the executable, which is more noise than anything else. - codesign --display --verbose=5 -r- "${path}" - codesign --verify --verbose=6 "${args[@]:1}" "${path}" -} - -if [[ ${#} -ne 3 && ${#} -ne 4 ]]; then - echo "usage: ${ME} app_path codesign_keychain codesign_id \ -[--development]" >& 2 - exit 1 -fi - -app_path="${1}" -codesign_keychain="${2}" -codesign_id="${3}" -is_development= - -if [[ ${#} == 4 && ${4} == "--development" ]]; then - is_development=1 -fi - -codesign_with_options() { - path=${1} - options=${2} - requirement_identifier=${3} - - codesign_cmd=( - codesign --sign "${codesign_id}" --keychain "${codesign_keychain}" - "${path}" - ) - - if [[ "${requirement_identifier}" = "app_mode_loader" ]]; then - codesign_cmd+=( --identifier "${requirement_identifier}" ) - fi - - if [[ -n "${options}" ]]; then - codesign_cmd+=( --options "${options}" ) - fi - - if [[ -z "${is_development}" ]]; then - requirement="designated => identifier \"${requirement_identifier}\" \ -${requirement_suffix}" - codesign_cmd+=( -r="${requirement}" ) - fi - "${codesign_cmd[@]}" -} - -versioned_dir="${app_path}/Contents/Versions/@VERSION@" - -# To sign an .app bundle that contains nested code, the nested components -# themselves must be signed. Each of these components is signed below. Note -# that unless a framework has multiple versions (which is discouraged), signing -# the entire framework is equivalent to signing the Current version. -# https://developer.apple.com/library/content/technotes/tn2206/_index.html#//apple_ref/doc/uid/DTS40007919-CH1-TNTAG13 - -framework="${versioned_dir}/@MAC_PRODUCT_NAME@ Framework.framework" -notification_service="${framework}/XPCServices/AlertNotificationService.xpc" -crashpad_handler="${framework}/Helpers/chrome_crashpad_handler" -helper_app="${versioned_dir}/@MAC_PRODUCT_NAME@ Helper.app" -app_mode_loader_app="${framework}/Resources/app_mode_loader.app" -app_mode_loader="${app_mode_loader_app}/Contents/MacOS/app_mode_loader" - -libraries_dir="${framework}/Libraries" -libraries=( - "${libraries_dir}/libEGL.dylib" - "${libraries_dir}/libGLESv2.dylib" - "${libraries_dir}/libswiftshader_libEGL.dylib" - "${libraries_dir}/libswiftshader_libGLESv2.dylib" - "${libraries_dir}/WidevineCdm/_platform_specific/mac_x64/libwidevinecdm.dylib" -) - -codesign_with_options "${crashpad_handler}" \ - "${enforcement_flags_helpers}" \ - "chrome_crashpad_handler" - -# The app mode loader bundle is modified dynamically at runtime. Just sign the -# executable, which shouldn't change. In order to do this, the executable needs -# to be copied out of the bundle, signed, and then copied back in. The resulting -# bundle's signature won't validate normally, but if the executable file is -# verified in isolation or with --ignore-resources, it will. -app_mode_loader_tmp="$(mktemp -t app_mode_loader)" -cp "${app_mode_loader}" "${app_mode_loader_tmp}" - -codesign_with_options "${app_mode_loader_tmp}" \ - "${enforcement_flags_helpers}" \ - "app_mode_loader" - -cp "${app_mode_loader_tmp}" "${app_mode_loader}" -rm -f "${app_mode_loader_tmp}" - -xpc_plist="${notification_service}/Contents/Info" -xpc_bundle_id="$(__CFPREFERENCES_AVOID_DAEMON=1 defaults read \ - "${xpc_plist}" "CFBundleIdentifier")" - -codesign_with_options "${notification_service}" \ - "${enforcement_flags_helpers}" \ - "${xpc_bundle_id}" - -# Sign the other Libraries. Some of these could be missing, if they are -# excluded from the build via GN args, so do test for their presence first. -for library in "${libraries[@]}"; do - if [ -f "${library}" ]; then - # No ${enforcement_flags_helpers} since they only apply to executables. - codesign_with_options "${library}" "" "$(basename "$library" .dylib)" - fi -done - -# The framework is a dylib, so ${enforcement_flags_helpers} are meaningless. -codesign_with_options "${framework}" "" "com.google.Chrome.framework" - -codesign_with_options "${helper_app}" \ - "${enforcement_flags_app}" \ - "com.google.Chrome.helper" - -codesign_display_and_verify "${crashpad_handler}" --deep -codesign_display_and_verify "${app_mode_loader}" --ignore-resources -codesign_display_and_verify "${notification_service}" --deep -# The framework contains KeystoneRegistration.framework, which uses -# custom resource rules, so use --no-strict to verify. -codesign_display_and_verify "${framework}" --deep --no-strict -codesign_display_and_verify "${framework}" --strict -codesign_display_and_verify "${helper_app}" --deep - -for library in "${libraries[@]}"; do - if [ -f "${library}" ]; then - codesign_display_and_verify "${library}" --deep - fi -done
diff --git a/chrome/installer/mac/signing/signing.py b/chrome/installer/mac/signing/signing.py index 6c8b4bf..91b7ed84 100644 --- a/chrome/installer/mac/signing/signing.py +++ b/chrome/installer/mac/signing/signing.py
@@ -75,8 +75,7 @@ verify_options=VerifyOptions.DEEP), 'app-mode-app': CodeSignedProduct( - '{.framework_dir}/Resources/app_mode_loader.app/Contents/MacOS/app_mode_loader' - .format(config), + '{.framework_dir}/Helpers/app_mode_loader'.format(config), 'app_mode_loader', options=config.codesign_options_helpers, verify_options=VerifyOptions.IGNORE_RESOURCES), @@ -224,25 +223,10 @@ # signing the entire framework is equivalent to signing the Current version. # https://developer.apple.com/library/content/technotes/tn2206/_index.html#//apple_ref/doc/uid/DTS40007919-CH1-TNTAG13 for name, part in parts.items(): - if name in ('app', 'framework', 'app-mode-app'): + if name in ('app', 'framework'): continue sign_part(paths, config, part) - # The app mode loader bundle is modified dynamically at runtime. Just sign - # the executable, which shouldn't change. In order to do this, the - # executable needs to be moved out of the bundle, signed, and then moved - # back in. The resulting bundle's signature won't validate normally, but if - # the executable file is verified in isolation or with --ignore-resources, - # it will. - app_mode_app = copy.copy(parts['app-mode-app']) - orig_app_mode_path = os.path.join(paths.work, app_mode_app.path) - temp_app_mode_path = os.path.join(paths.work, - os.path.basename(app_mode_app.path)) - commands.move_file(orig_app_mode_path, temp_app_mode_path) - app_mode_app.path = temp_app_mode_path - sign_part(paths, config, app_mode_app) - commands.move_file(temp_app_mode_path, orig_app_mode_path) - # Sign the framework bundle. sign_part(paths, config, parts['framework'])
diff --git a/chrome/installer/mac/signing/signing_test.py b/chrome/installer/mac/signing/signing_test.py index c2938e8..786a9bf 100644 --- a/chrome/installer/mac/signing/signing_test.py +++ b/chrome/installer/mac/signing/signing_test.py
@@ -223,30 +223,8 @@ signing.sign_chrome(self.paths, config) - # Test that the two file moves are for app_mode_loader. - self.assertEqual(kwargs['move_file'].mock_calls, [ - mock.call.move_file( - '$W/App Product.app/Contents/Versions/99.0.9999.99/Product Framework.framework/Resources/app_mode_loader.app/Contents/MacOS/app_mode_loader', - '$W/app_mode_loader'), - mock.call.move_file( - '$W/app_mode_loader', - '$W/App Product.app/Contents/Versions/99.0.9999.99/Product Framework.framework/Resources/app_mode_loader.app/Contents/MacOS/app_mode_loader' - ), - ]) - - # Find the signing step between the two moves. - moved_app_loader_index = manager.mock_calls.index( - mock.call.move_file(*kwargs['move_file'].mock_calls[0][1])) - sign_app_mode = manager.mock_calls[moved_app_loader_index + 1] - self.assertEqual('$W/app_mode_loader', sign_app_mode[1][2].path) - - # Make sure app_mode_loader is only signed that once. - other_sign_app_modes = [ - call for call in kwargs['sign_part'].mock_calls - if call[1][2].identifier == 'app_mode_loader' - ] - self.assertEqual(1, len(other_sign_app_modes)) - self.assertEqual(sign_app_mode[1], other_sign_app_modes[0][1]) + # No files should be moved. + self.assertEqual(0, kwargs['move_file'].call_count) # Test that the provisioning profile is copied. self.assertEqual(kwargs['copy_files'].mock_calls, [ @@ -255,11 +233,17 @@ '$W/App Product.app/Contents/embedded.provisionprofile') ]) + # Ensure that all the parts are signed. + signed_paths = [ + call[1][2].path for call in kwargs['sign_part'].mock_calls + ] + self.assertEqual( + set([p.path for p in signing.get_parts(config).values()]), + set(signed_paths)) + # Make sure that the framework and the app are the last two parts that # are signed. - last_two_sign_parts = kwargs['sign_part'].mock_calls[-2:] - last_two_part_paths = [call[1][2].path for call in last_two_sign_parts] - self.assertEqual(last_two_part_paths, [ + self.assertEqual(signed_paths[-2:], [ 'App Product.app/Contents/Versions/99.0.9999.99/Product Framework.framework', 'App Product.app' ])
diff --git a/chrome/installer/mac/variables.sh b/chrome/installer/mac/variables.sh deleted file mode 100644 index cb07976..0000000 --- a/chrome/installer/mac/variables.sh +++ /dev/null
@@ -1,23 +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. - -# This signs the main app and helper executable, and enables "rootless" -# protections. The main app does not use library validation because it has to -# load Flash player, plugins, etc. -enforcement_flags_app="restrict" - -# All the helpers (crashpad, app_mode_loader, etc.), run under library -# validation as they should not run any code not signed by Google. -enforcement_flags_helpers="${enforcement_flags_app},library" - -# The installer tools are signed with the kill bit as well, as they run on -# signing machines and should never be modified. -enforcement_flags_installer_tools="${enforcement_flags_helpers},kill" - -# The designated requirement suffix used when signing Chrome's binaries. It -# contains the hash of the certificate used to sign Chrome. When transitioning -# signing certs, this may include the hash of both the old and new certificate. -requirement_suffix="\ -and certificate leaf = H\"c9a99324ca3fcb23dbcc36bd5fd4f9753305130a\" \ -"
diff --git a/chrome/renderer/searchbox/searchbox_extension.cc b/chrome/renderer/searchbox/searchbox_extension.cc index 3dfcd442..714a7cf 100644 --- a/chrome/renderer/searchbox/searchbox_extension.cc +++ b/chrome/renderer/searchbox/searchbox_extension.cc
@@ -199,11 +199,15 @@ return maybe_int.ToLocalChecked()->Value(); } +// TODO(gayane): Consider removing RGBAColor struct and replacing it with +// SkColor. // Converts RGBAColor to SkColor. SkColor RGBAColorToSkColor(const RGBAColor& color) { return SkColorSetARGB(color.a, color.r, color.g, color.b); } +// TODO(gayane): Consider moving any non-trivial logic up to |InstantService| +// and do only mapping here. v8::Local<v8::Object> GenerateThemeBackgroundInfo( v8::Isolate* isolate, const ThemeBackgroundInfo& theme_info) { @@ -308,7 +312,7 @@ // If a custom background has been set provide the relevant information to the // page. if (!theme_info.custom_background_url.is_empty()) { - ntp_text = RGBAColor{255, 255, 255, 255}; + ntp_text = RGBAColor{248, 249, 250, 255}; // GG050 builder.Set("alternateLogo", true); builder.Set("customBackgroundConfigured", true); builder.Set("imageUrl", theme_info.custom_background_url.spec()); @@ -327,8 +331,11 @@ // Value is always valid. builder.Set("textColorRgba", internal::RGBAColorToArray(isolate, ntp_text)); + // Generate fields for themeing NTP elements. builder.Set("isNtpBackgroundDark", internal::IsNtpBackgroundDark(RGBAColorToSkColor(ntp_text))); + builder.Set("useTitleContainer", + crx_file::id_util::IdIsValid(theme_info.theme_id)); return builder.Build(); }
diff --git a/chrome/services/isolated_xr_device/OWNERS b/chrome/services/isolated_xr_device/OWNERS index 2466914..776883c 100644 --- a/chrome/services/isolated_xr_device/OWNERS +++ b/chrome/services/isolated_xr_device/OWNERS
@@ -1,3 +1,4 @@ +alcooper@chromium.org billorr@chromium.org ddorwin@chromium.org klausw@chromium.org
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index f289b28..e048bda 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1988,6 +1988,7 @@ "../browser/chromeos/policy/restore_on_startup_browsertest_chromeos.cc", "../browser/chromeos/policy/signin_profile_apps_policy_browsertest.cc", "../browser/chromeos/policy/site_isolation_flag_handling_browsertest.cc", + "../browser/chromeos/policy/status_collector/child_status_collector_browsertest.cc", "../browser/chromeos/policy/status_collector/device_status_collector_browsertest.cc", "../browser/chromeos/policy/unaffiliated_arc_allowed_browsertest.cc", "../browser/chromeos/policy/user_affiliation_browsertest.cc", @@ -2844,6 +2845,7 @@ "../browser/performance_manager/performance_manager_test_harness.cc", "../browser/performance_manager/performance_manager_test_harness.h", "../browser/performance_manager/performance_manager_unittest.cc", + "../browser/performance_manager/persistence/site_data/exponential_moving_average_unittest.cc", "../browser/performance_manager/web_contents_proxy_unittest.cc", "../browser/performance_manager/webui_graph_dump_impl_unittest.cc", "../browser/performance_monitor/metric_evaluator_helper_win_unittest.cc", @@ -3393,7 +3395,6 @@ "../browser/resource_coordinator/background_tab_navigation_throttle_unittest.cc", "../browser/resource_coordinator/decision_details_unittest.cc", "../browser/resource_coordinator/discard_metrics_lifecycle_unit_observer_unittest.cc", - "../browser/resource_coordinator/exponential_moving_average_unittest.cc", "../browser/resource_coordinator/intervention_policy_database_unittest.cc", "../browser/resource_coordinator/leveldb_site_characteristics_database_unittest.cc", "../browser/resource_coordinator/lifecycle_unit_base_unittest.cc", @@ -5103,6 +5104,8 @@ "base/interactive_ui_tests_main.cc", "base/save_desktop_snapshot_win.cc", "base/save_desktop_snapshot_win.h", + "base/window_contents_as_string_win.cc", + "base/window_contents_as_string_win.h", "ppapi/ppapi_interactive_browsertest.cc", ] @@ -5897,6 +5900,8 @@ "base/interactive_test_utils_mac.mm", "base/interactive_test_utils_win.cc", "base/interactive_ui_tests_main.cc", + "base/window_contents_as_string_win.cc", + "base/window_contents_as_string_win.h", ] if (use_aura) {
diff --git a/chrome/test/base/interactive_test_utils_win.cc b/chrome/test/base/interactive_test_utils_win.cc index 078c26e..69fdb90 100644 --- a/chrome/test/base/interactive_test_utils_win.cc +++ b/chrome/test/base/interactive_test_utils_win.cc
@@ -14,6 +14,7 @@ #include "chrome/test/base/interactive_test_utils_aura.h" #include "chrome/test/base/process_lineage_win.h" #include "chrome/test/base/save_desktop_snapshot_win.h" +#include "chrome/test/base/window_contents_as_string_win.h" #include "ui/aura/window_tree_host.h" #include "ui/base/test/ui_controls.h" #include "ui/base/win/foreground_helper.h" @@ -56,6 +57,7 @@ GetWindowText(foreground_window, window_title, base::size(window_title)); base::string16 lineage_str; + base::string16 window_contents; if (foreground_window) { DWORD process_id = 0; GetWindowThreadProcessId(foreground_window, &process_id); @@ -64,9 +66,13 @@ lineage_str = STRING16_LITERAL(", process lineage: "); lineage_str.append(lineage.ToString()); } + + window_contents = WindowContentsAsString(foreground_window); } LOG(ERROR) << "ShowAndFocusNativeWindow failed. foreground window: " - << foreground_window << ", title: " << window_title << lineage_str; + << foreground_window << ", title: " << window_title << lineage_str + << ", contents:" << std::endl + << window_contents; const base::FilePath output_dir = base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
diff --git a/chrome/test/base/window_contents_as_string_win.cc b/chrome/test/base/window_contents_as_string_win.cc new file mode 100644 index 0000000..d78caaea --- /dev/null +++ b/chrome/test/base/window_contents_as_string_win.cc
@@ -0,0 +1,123 @@ +// 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/test/base/window_contents_as_string_win.h" + +// Needed for <uiautomation.h> +#include <objbase.h> + +#include <uiautomation.h> +#include <wrl/client.h> + +#include <utility> + +#include "base/logging.h" +#include "base/win/com_init_util.h" +#include "base/win/scoped_bstr.h" +#include "base/win/scoped_variant.h" + +namespace { + +// IDs corresponding to the properties read by CachedElementContentsAsString. +constexpr long kCachedProperties[] = { + UIA_LocalizedControlTypePropertyId, + UIA_NamePropertyId, + UIA_IsInvokePatternAvailablePropertyId, +}; + +// Returns a string representation of the cached properties of |element|. +base::string16 CachedElementContentsAsString(IUIAutomationElement* element) { + base::string16 contents; + + base::win::ScopedVariant variant; + HRESULT result = element->GetCachedPropertyValue( + UIA_IsInvokePatternAvailablePropertyId, variant.Receive()); + if (SUCCEEDED(result) && variant.type() == VT_BOOL && + V_BOOL(variant.ptr()) == VARIANT_TRUE) { + contents.append(STRING16_LITERAL("[invokable] ")); + } + + base::win::ScopedBstr value; + result = element->get_CachedLocalizedControlType(value.Receive()); + if (SUCCEEDED(result)) + contents.append(STRING16_LITERAL("type: ")).append(value); + + value.Reset(); + result = element->get_CachedName(value.Receive()); + if (SUCCEEDED(result)) { + if (!contents.empty()) + contents.append(STRING16_LITERAL(", ")); + contents.append(STRING16_LITERAL("name: ")).append(value); + } + + return contents; +} + +void TreeAsString(IUIAutomationTreeWalker* walker, + IUIAutomationCacheRequest* cache_request, + IUIAutomationElement* element, + const base::string16& padding, + base::string16* contents) { + contents->append(padding) + .append(CachedElementContentsAsString(element)) + .append(STRING16_LITERAL("\n")); + + Microsoft::WRL::ComPtr<IUIAutomationElement> child_element; + HRESULT result = walker->GetFirstChildElementBuildCache( + element, cache_request, &child_element); + if (FAILED(result)) + return; + const base::string16 next_padding = padding + STRING16_LITERAL(" "); + while (child_element.Get()) { + TreeAsString(walker, cache_request, child_element.Get(), next_padding, + contents); + Microsoft::WRL::ComPtr<IUIAutomationElement> next_element; + result = walker->GetNextSiblingElementBuildCache( + child_element.Get(), cache_request, &next_element); + if (FAILED(result)) + return; + child_element = std::move(next_element); + } +} + +} // namespace + +base::string16 WindowContentsAsString(HWND window_handle) { + DCHECK(window_handle); + base::win::AssertComInitialized(); + + Microsoft::WRL::ComPtr<IUIAutomation> automation; + + HRESULT result = + ::CoCreateInstance(CLSID_CUIAutomation, nullptr, CLSCTX_INPROC_SERVER, + IID_PPV_ARGS(&automation)); + if (FAILED(result)) + return base::string16(); + + Microsoft::WRL::ComPtr<IUIAutomationCacheRequest> cache_request; + result = automation->CreateCacheRequest(&cache_request); + if (FAILED(result)) + return base::string16(); + for (auto property_id : kCachedProperties) + cache_request->AddProperty(property_id); + + Microsoft::WRL::ComPtr<IUIAutomationElement> window_element; + result = automation->ElementFromHandleBuildCache( + window_handle, cache_request.Get(), &window_element); + if (FAILED(result)) + return base::string16(); + + Microsoft::WRL::ComPtr<IUIAutomationTreeWalker> walker; + result = automation->get_RawViewWalker(&walker); + if (FAILED(result)) + return base::string16(); + + base::string16 contents; + TreeAsString(walker.Get(), cache_request.Get(), window_element.Get(), + base::string16(), &contents); + // Strip the trailing newline. + if (!contents.empty()) + contents.pop_back(); + return contents; +}
diff --git a/chrome/test/base/window_contents_as_string_win.h b/chrome/test/base/window_contents_as_string_win.h new file mode 100644 index 0000000..bf377e3 --- /dev/null +++ b/chrome/test/base/window_contents_as_string_win.h
@@ -0,0 +1,29 @@ +// 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_TEST_BASE_WINDOW_CONTENTS_AS_STRING_WIN_H_ +#define CHROME_TEST_BASE_WINDOW_CONTENTS_AS_STRING_WIN_H_ + +#include "base/strings/string16.h" +#include "base/win/windows_types.h" + +// Returns a string representation of the contents of |window| on the basis of +// the elements it exposes via UI automation, or an empty string in case of +// error. In particular, the control type and title of the window's element and +// each UI element within it is emitted, indented an amount corresponding to its +// depth in the UI hierarchy. Elements that are invokable (e.g., buttons) are +// labeled as such. For example: +// type: window, name: Windows can't open this type of file (.adm) +// type: pane, name: Flyout window +// type: pane, name: +// type: pane, name: Immersive Openwith Flyout +// type: text, name: Windows can't open this type of file (.adm) +// type: pane, name: +// type: list, name: +// type: list, name: +// [invokable] type: link, name: More apps +// [invokable] type: button, name: OK +base::string16 WindowContentsAsString(HWND window_handle); + +#endif // CHROME_TEST_BASE_WINDOW_CONTENTS_AS_STRING_WIN_H_
diff --git a/chrome/test/data/media/picture-in-picture/iframe-test.html b/chrome/test/data/media/picture-in-picture/iframe-test.html index e4f4565a..aa0cde7 100644 --- a/chrome/test/data/media/picture-in-picture/iframe-test.html +++ b/chrome/test/data/media/picture-in-picture/iframe-test.html
@@ -4,6 +4,7 @@ <title>Picture-in-Picture iframe Test</title> </head> <body> + <video controls preload=auto src='../bigbuck.webm'></video> </body> <script> let src = 'iframe-content.html'; @@ -24,5 +25,12 @@ document.title = 'loadedmetadata'; } }); + + const video = document.querySelector('video'); + function enterPictureInPicture() { + video.requestPictureInPicture().then(() => { + domAutomationController.send(true); + }); + } </script> </html>
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index a464426..8dee445 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -2228,6 +2228,10 @@ "note": "This policy has no pref as it is only directly read by the policy system." }, + "PolicyDictionaryMultipleSourceMergeList": { + "note": "This policy has no pref as it is only directly read by the policy system." + }, + "EnterpriseWebStoreURL": { "note": "This policy is retired, see http://crbug.com/178938." },
diff --git a/chromecast/base/cast_features.cc b/chromecast/base/cast_features.cc index 419abea..9baa7a2 100644 --- a/chromecast/base/cast_features.cc +++ b/chromecast/base/cast_features.cc
@@ -251,7 +251,7 @@ feature_name, base::FeatureList::OVERRIDE_DISABLE_FEATURE)) { // Build a map of the FieldTrial parameters and associate it to the // FieldTrial. - base::FieldTrialParamAssociator::FieldTrialParams params; + base::FieldTrialParams params; for (Iterator p(*params_dict); !p.IsAtEnd(); p.Advance()) { std::string val; if (p.value().GetAsString(&val)) {
diff --git a/chromecast/common/cast_extensions_client.cc b/chromecast/common/cast_extensions_client.cc index 537283db..6fe8893a 100644 --- a/chromecast/common/cast_extensions_client.cc +++ b/chromecast/common/cast_extensions_client.cc
@@ -129,8 +129,6 @@ return true; } -void CastExtensionsClient::RecordDidSuppressFatalError() {} - const GURL& CastExtensionsClient::GetWebstoreBaseURL() const { return webstore_base_url_; }
diff --git a/chromecast/common/cast_extensions_client.h b/chromecast/common/cast_extensions_client.h index 1f614d7d..b6827867 100644 --- a/chromecast/common/cast_extensions_client.h +++ b/chromecast/common/cast_extensions_client.h
@@ -34,7 +34,6 @@ const APIPermissionSet& api_permissions) const override; bool IsScriptableURL(const GURL& url, std::string* error) const override; bool ShouldSuppressFatalErrors() const override; - void RecordDidSuppressFatalError() override; const GURL& GetWebstoreBaseURL() const override; const GURL& GetWebstoreUpdateURL() const override; bool IsBlacklistUpdateURL(const GURL& url) const override;
diff --git a/chromeos/constants/chromeos_switches.cc b/chromeos/constants/chromeos_switches.cc index f0b1ebd..f2c32b83 100644 --- a/chromeos/constants/chromeos_switches.cc +++ b/chromeos/constants/chromeos_switches.cc
@@ -39,6 +39,10 @@ const base::Feature kAccountManager{"ChromeOSAccountManager", base::FEATURE_DISABLED_BY_DEFAULT}; +// Controls whether to enable Chrome OS Add Child Account Supervision flow. +const base::Feature kAddSupervision{"ChromeOSAddSupervision", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Controls whether to enable Google Assistant feature. const base::Feature kAssistantFeature{"ChromeOSAssistant", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -570,6 +574,10 @@ return base::FeatureList::IsEnabled(kAccountManager); } +bool IsAddSupervisionEnabled() { + return base::FeatureList::IsEnabled(kAddSupervision); +} + bool IsAssistantFlagsEnabled() { return base::FeatureList::IsEnabled(kAssistantFeature); }
diff --git a/chromeos/constants/chromeos_switches.h b/chromeos/constants/chromeos_switches.h index 475acdd..d28d89d 100644 --- a/chromeos/constants/chromeos_switches.h +++ b/chromeos/constants/chromeos_switches.h
@@ -200,6 +200,9 @@ // Controls whether to enable Chrome OS Account Manager. COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kAccountManager; +// Controls whether to enable Chrome OS Add Child Account Supervision flow. +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kAddSupervision; + // Controls whether to enable Google Assistant feature. COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kAssistantFeature; @@ -242,6 +245,9 @@ // Returns true if Chrome OS Account Manager is enabled. COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsAccountManagerEnabled(); +// Returns true if Chrome OS Add Child Supervision flow is enabled. +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsAddSupervisionEnabled(); + // Returns true if Google Assistant flags are enabled. COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsAssistantFlagsEnabled();
diff --git a/components/autofill/content/browser/DEPS b/components/autofill/content/browser/DEPS index 847530b9..078458d 100644 --- a/components/autofill/content/browser/DEPS +++ b/components/autofill/content/browser/DEPS
@@ -12,4 +12,8 @@ '.*_[a-z]*test\.cc': [ "+content/public/test", ], + '.*internal_authenticator_impl\.(cc|h)': [ + "+content/browser/webauth/authenticator_common.h", + "+third_party/blink/public/mojom/webauthn/internal_authenticator.mojom.h", + ] }
diff --git a/components/autofill/content/browser/webauthn/BUILD.gn b/components/autofill/content/browser/webauthn/BUILD.gn new file mode 100644 index 0000000..a6068f9 --- /dev/null +++ b/components/autofill/content/browser/webauthn/BUILD.gn
@@ -0,0 +1,19 @@ +# 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("//build/config/jumbo.gni") + +jumbo_static_library("webauthn") { + if (is_component_build) { + check_includes = false + } + sources = [ + "internal_authenticator_impl.cc", + "internal_authenticator_impl.h", + ] + deps = [ + "//content/browser:for_internal_webauthn", + "//content/public/browser", + ] +}
diff --git a/components/autofill/content/browser/webauthn/OWNERS b/components/autofill/content/browser/webauthn/OWNERS new file mode 100644 index 0000000..a6f6a36 --- /dev/null +++ b/components/autofill/content/browser/webauthn/OWNERS
@@ -0,0 +1 @@ +file://components/autofill/core/browser/payments/OWNERS
diff --git a/components/autofill/content/browser/webauthn/internal_authenticator_impl.cc b/components/autofill/content/browser/webauthn/internal_authenticator_impl.cc new file mode 100644 index 0000000..f6a9145 --- /dev/null +++ b/components/autofill/content/browser/webauthn/internal_authenticator_impl.cc
@@ -0,0 +1,102 @@ +// 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 "components/autofill/content/browser/webauthn/internal_authenticator_impl.h" + +#include <string> +#include <utility> + +#include "base/timer/timer.h" +#include "content/browser/webauth/authenticator_common.h" +#include "content/public/browser/navigation_handle.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/web_contents.h" +#include "url/origin.h" + +namespace content { + +InternalAuthenticatorImpl::InternalAuthenticatorImpl( + RenderFrameHost* render_frame_host, + url::Origin effective_origin) + : InternalAuthenticatorImpl(render_frame_host, + std::move(effective_origin), + std::make_unique<AuthenticatorCommon>( + render_frame_host, + nullptr /* connector */, + std::make_unique<base::OneShotTimer>())) {} + +InternalAuthenticatorImpl::InternalAuthenticatorImpl( + RenderFrameHost* render_frame_host, + url::Origin effective_origin, + std::unique_ptr<AuthenticatorCommon> authenticator_common) + : WebContentsObserver(WebContents::FromRenderFrameHost(render_frame_host)), + render_frame_host_(render_frame_host), + effective_origin_(std::move(effective_origin)), + authenticator_common_(std::move(authenticator_common)), + binding_(this), + weak_factory_(this) { + DCHECK(render_frame_host_); + DCHECK(authenticator_common_); + DCHECK(!effective_origin.opaque()); +} + +InternalAuthenticatorImpl::~InternalAuthenticatorImpl() { + // This call exists to assert that |render_frame_host_| outlives this object. + // If this is violated, ASAN should notice. + render_frame_host_->GetRoutingID(); +} + +void InternalAuthenticatorImpl::Bind( + blink::mojom::InternalAuthenticatorRequest request) { + // If |render_frame_host_| is being unloaded then binding requests are + // rejected. + if (!render_frame_host_->IsCurrent()) { + return; + } + + DCHECK(!binding_.is_bound()); + binding_.Bind(std::move(request)); +} + +// mojom::InternalAuthenticator +void InternalAuthenticatorImpl::MakeCredential( + blink::mojom::PublicKeyCredentialCreationOptionsPtr options, + MakeCredentialCallback callback) { + authenticator_common_->MakeCredential(effective_origin_, std::move(options), + std::move(callback)); +} + +// mojom::InternalAuthenticator +void InternalAuthenticatorImpl::GetAssertion( + blink::mojom::PublicKeyCredentialRequestOptionsPtr options, + GetAssertionCallback callback) { + authenticator_common_->GetAssertion(effective_origin_, std::move(options), + std::move(callback)); +} + +// mojom::InternalAuthenticator +void InternalAuthenticatorImpl::IsUserVerifyingPlatformAuthenticatorAvailable( + IsUserVerifyingPlatformAuthenticatorAvailableCallback callback) { + authenticator_common_->IsUserVerifyingPlatformAuthenticatorAvailable( + std::move(callback)); +} + +void InternalAuthenticatorImpl::DidFinishNavigation( + NavigationHandle* navigation_handle) { + // If the RenderFrameHost itself is navigated then this function will cause + // request state to be cleaned up. It's also possible for a navigation in the + // same frame to use a fresh RenderFrameHost. In this case, + // |render_frame_host_->IsCurrent()| will start returning false, causing all + // focus checks to fail if any Mojo requests are made in that state. + if (!navigation_handle->HasCommitted() || + navigation_handle->IsSameDocument() || + navigation_handle->GetRenderFrameHost() != render_frame_host_) { + return; + } + + binding_.Close(); + authenticator_common_->Cleanup(); +} + +} // namespace content
diff --git a/components/autofill/content/browser/webauthn/internal_authenticator_impl.h b/components/autofill/content/browser/webauthn/internal_authenticator_impl.h new file mode 100644 index 0000000..b1d00c26 --- /dev/null +++ b/components/autofill/content/browser/webauthn/internal_authenticator_impl.h
@@ -0,0 +1,87 @@ +// 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 COMPONENTS_AUTOFILL_CONTENT_BROWSER_WEBAUTHN_INTERNAL_AUTHENTICATOR_IMPL_H_ +#define COMPONENTS_AUTOFILL_CONTENT_BROWSER_WEBAUTHN_INTERNAL_AUTHENTICATOR_IMPL_H_ + +#include <stdint.h> + +#include <memory> +#include <string> + +#include "base/macros.h" +#include "content/browser/webauth/authenticator_common.h" +#include "content/public/browser/web_contents_observer.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "third_party/blink/public/mojom/webauthn/internal_authenticator.mojom.h" + +namespace url { +class Origin; +} + +namespace content { + +class RenderFrameHost; + +// Implementation of the public InternalAuthenticator interface. +// This class is meant only for trusted and internal components of Chrome to +// use. +class InternalAuthenticatorImpl : public blink::mojom::InternalAuthenticator, + public WebContentsObserver { + public: + InternalAuthenticatorImpl(RenderFrameHost* render_frame_host, + url::Origin effective_origin); + + ~InternalAuthenticatorImpl() override; + + // Creates a binding between this implementation and |request|. + // + // Note that one InternalAuthenticatorImpl instance can be bound to + // exactly one interface connection at a time, and disconnected when the frame + // navigates to a new active document. + void Bind(blink::mojom::InternalAuthenticatorRequest request); + + private: + friend class InternalAuthenticatorImplTest; + + // By being able to set AuthenticatorCommon, this constructor permits setting + // the connector and timer for testing. Using this constructor will also empty + // out the protocol set, since no device discovery will take place during + // tests. + InternalAuthenticatorImpl( + RenderFrameHost* render_frame_host, + url::Origin effective_origin, + std::unique_ptr<AuthenticatorCommon> authenticator_common); + + AuthenticatorCommon* get_authenticator_common_for_testing() { + return authenticator_common_.get(); + } + + // mojom::InternalAuthenticator + void MakeCredential( + blink::mojom::PublicKeyCredentialCreationOptionsPtr options, + MakeCredentialCallback callback) override; + void GetAssertion(blink::mojom::PublicKeyCredentialRequestOptionsPtr options, + GetAssertionCallback callback) override; + void IsUserVerifyingPlatformAuthenticatorAvailable( + IsUserVerifyingPlatformAuthenticatorAvailableCallback callback) override; + + // WebContentsObserver + void DidFinishNavigation(NavigationHandle* navigation_handle) override; + + RenderFrameHost* const render_frame_host_; + const url::Origin effective_origin_; + std::unique_ptr<AuthenticatorCommon> authenticator_common_; + + // Owns pipes to this Authenticator from |render_frame_host_|. + mojo::Binding<blink::mojom::InternalAuthenticator> binding_; + + base::WeakPtrFactory<InternalAuthenticatorImpl> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(InternalAuthenticatorImpl); +}; + +} // namespace content + +#endif // COMPONENTS_AUTOFILL_CONTENT_BROWSER_WEBAUTHN_INTERNAL_AUTHENTICATOR_IMPL_H_
diff --git a/components/autofill/core/browser/address_contact_form_label_formatter.cc b/components/autofill/core/browser/address_contact_form_label_formatter.cc index 7cee59e..ac53182 100644 --- a/components/autofill/core/browser/address_contact_form_label_formatter.cc +++ b/components/autofill/core/browser/address_contact_form_label_formatter.cc
@@ -9,16 +9,19 @@ namespace autofill { AddressContactFormLabelFormatter::AddressContactFormLabelFormatter( + const std::vector<AutofillProfile*>& profiles, const std::string& app_locale, ServerFieldType focused_field_type, uint32_t groups, - const std::vector<ServerFieldType>& field_types, - bool show_phone, - bool show_email) - : LabelFormatter(app_locale, focused_field_type, groups, field_types), + const std::vector<ServerFieldType>& field_types) + : LabelFormatter(profiles, + app_locale, + focused_field_type, + groups, + field_types), form_has_street_address_(HasStreetAddress(field_types_for_labels())), - show_phone_(show_phone), - show_email_(show_email) {} + email_disambiguates_(!HaveSameEmailAddresses(profiles, app_locale)), + phone_disambiguates_(!HaveSamePhoneNumbers(profiles, app_locale)) {} AddressContactFormLabelFormatter::~AddressContactFormLabelFormatter() {} @@ -48,11 +51,11 @@ &label_parts); } - if (focused_group != PHONE_HOME && show_phone_) { + if (focused_group != PHONE_HOME && phone_disambiguates_) { AddLabelPartIfNotEmpty(GetLabelPhone(profile, app_locale()), &label_parts); } - if (focused_group != EMAIL && show_email_) { + if (focused_group != EMAIL && email_disambiguates_) { AddLabelPartIfNotEmpty(GetLabelEmail(profile, app_locale()), &label_parts); }
diff --git a/components/autofill/core/browser/address_contact_form_label_formatter.h b/components/autofill/core/browser/address_contact_form_label_formatter.h index 0890b3b7..e5b9271 100644 --- a/components/autofill/core/browser/address_contact_form_label_formatter.h +++ b/components/autofill/core/browser/address_contact_form_label_formatter.h
@@ -20,12 +20,11 @@ class AddressContactFormLabelFormatter : public LabelFormatter { public: AddressContactFormLabelFormatter( + const std::vector<AutofillProfile*>& profiles, const std::string& app_locale, ServerFieldType focused_field_type, uint32_t groups, - const std::vector<ServerFieldType>& field_types, - bool show_phone, - bool show_email); + const std::vector<ServerFieldType>& field_types); ~AddressContactFormLabelFormatter() override; @@ -40,11 +39,9 @@ // street addresses should not appear in labels. bool form_has_street_address_; - // True if phone numbers should be included in labels. - bool show_phone_; - - // True if email addresses should be included in labels. - bool show_email_; + // True if the field disambiguates |profiles_|. + bool email_disambiguates_; + bool phone_disambiguates_; }; } // namespace autofill
diff --git a/components/autofill/core/browser/address_contact_form_label_formatter_unittest.cc b/components/autofill/core/browser/address_contact_form_label_formatter_unittest.cc index cc308ff..acec59d 100644 --- a/components/autofill/core/browser/address_contact_form_label_formatter_unittest.cc +++ b/components/autofill/core/browser/address_contact_form_label_formatter_unittest.cc
@@ -40,8 +40,8 @@ TEST(AddressContactFormLabelFormatterTest, GetLabelsWithMissingProfiles) { const std::vector<AutofillProfile*> profiles{}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "en-US", NAME_BILLING_FULL, GetFieldTypes(), profiles); - EXPECT_TRUE(formatter->GetLabels(profiles).empty()); + profiles, "en-US", NAME_BILLING_FULL, GetFieldTypes()); + EXPECT_TRUE(formatter->GetLabels().empty()); } TEST(AddressContactFormLabelFormatterTest, @@ -82,10 +82,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3, &profile4, &profile5, &profile6}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "en-US", NAME_BILLING_FULL, GetFieldTypes(), profiles); + profiles, "en-US", NAME_BILLING_FULL, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre( ConstructLabelLine({base::ASCIIToUTF16("19 North Sq"), base::ASCIIToUTF16("(617) 523-2338"), @@ -138,10 +138,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3, &profile4, &profile5, &profile6}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "en-US", ADDRESS_BILLING_LINE1, GetFieldTypes(), profiles); + profiles, "en-US", ADDRESS_BILLING_LINE1, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre( ConstructLabelLine({base::ASCIIToUTF16("Sarah Revere"), base::ASCIIToUTF16("(617) 523-2338"), @@ -194,10 +194,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3, &profile4, &profile5, &profile6}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "en-US", ADDRESS_BILLING_CITY, GetFieldTypes(), profiles); + profiles, "en-US", ADDRESS_BILLING_CITY, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre( ConstructLabelLine({base::ASCIIToUTF16("19 North Sq"), base::ASCIIToUTF16("(617) 523-2338"), @@ -250,10 +250,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3, &profile4, &profile5, &profile6}; const std::unique_ptr<LabelFormatter> formatter = - LabelFormatter::Create("en-US", EMAIL_ADDRESS, GetFieldTypes(), profiles); + LabelFormatter::Create(profiles, "en-US", EMAIL_ADDRESS, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("Sarah Revere"), base::ASCIIToUTF16("19 North Sq"), base::ASCIIToUTF16("(617) 523-2338")}), @@ -306,10 +306,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3, &profile4, &profile5, &profile6}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "en-US", PHONE_BILLING_WHOLE_NUMBER, GetFieldTypes(), profiles); + profiles, "en-US", PHONE_BILLING_WHOLE_NUMBER, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre( ConstructLabelLine({base::ASCIIToUTF16("Sarah Revere"), base::ASCIIToUTF16("19 North Sq"), @@ -343,10 +343,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "pt-BR", NAME_BILLING_FULL, GetFieldTypes(), profiles); + profiles, "pt-BR", NAME_BILLING_FULL, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre( ConstructLabelLine( {base::UTF8ToUTF16("Av. Pedro Álvares Cabral, 1301"), @@ -375,10 +375,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "pt-BR", ADDRESS_BILLING_LINE1, GetFieldTypes(), profiles); + profiles, "pt-BR", ADDRESS_BILLING_LINE1, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre( ConstructLabelLine({base::ASCIIToUTF16("Tarsila do Amaral"), base::ASCIIToUTF16("(11) 2648-0254"), @@ -406,10 +406,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "pt-BR", ADDRESS_BILLING_ZIP, GetFieldTypes(), profiles); + profiles, "pt-BR", ADDRESS_BILLING_ZIP, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre( ConstructLabelLine( {base::UTF8ToUTF16("Av. Pedro Álvares Cabral, 1301"), @@ -438,10 +438,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2}; const std::unique_ptr<LabelFormatter> formatter = - LabelFormatter::Create("pt-BR", EMAIL_ADDRESS, GetFieldTypes(), profiles); + LabelFormatter::Create(profiles, "pt-BR", EMAIL_ADDRESS, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre( ConstructLabelLine( {base::ASCIIToUTF16("Tarsila do Amaral"), @@ -470,10 +470,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "pt-BR", PHONE_BILLING_WHOLE_NUMBER, GetFieldTypes(), profiles); + profiles, "pt-BR", PHONE_BILLING_WHOLE_NUMBER, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre( ConstructLabelLine( {base::ASCIIToUTF16("Tarsila do Amaral"), @@ -494,14 +494,13 @@ const std::vector<AutofillProfile*> profiles{&profile}; const std::unique_ptr<LabelFormatter> formatter = - LabelFormatter::Create("en-US", EMAIL_ADDRESS, + LabelFormatter::Create(profiles, "en-US", EMAIL_ADDRESS, {NAME_BILLING_FULL, EMAIL_ADDRESS, - ADDRESS_BILLING_ZIP, PHONE_BILLING_WHOLE_NUMBER}, - profiles); + ADDRESS_BILLING_ZIP, PHONE_BILLING_WHOLE_NUMBER}); // Checks that only address fields in the form are shown in the label. EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre(ConstructLabelLine( {base::ASCIIToUTF16("Sarah Revere"), base::ASCIIToUTF16("02113")}))); }
diff --git a/components/autofill/core/browser/address_email_form_label_formatter.cc b/components/autofill/core/browser/address_email_form_label_formatter.cc index 05ad6804..d55b365 100644 --- a/components/autofill/core/browser/address_email_form_label_formatter.cc +++ b/components/autofill/core/browser/address_email_form_label_formatter.cc
@@ -9,11 +9,16 @@ namespace autofill { AddressEmailFormLabelFormatter::AddressEmailFormLabelFormatter( + const std::vector<AutofillProfile*>& profiles, const std::string& app_locale, ServerFieldType focused_field_type, uint32_t groups, const std::vector<ServerFieldType>& field_types) - : LabelFormatter(app_locale, focused_field_type, groups, field_types), + : LabelFormatter(profiles, + app_locale, + focused_field_type, + groups, + field_types), form_has_street_address_(HasStreetAddress(field_types_for_labels())) {} AddressEmailFormLabelFormatter::~AddressEmailFormLabelFormatter() {}
diff --git a/components/autofill/core/browser/address_email_form_label_formatter.h b/components/autofill/core/browser/address_email_form_label_formatter.h index ce39061..0d34d94 100644 --- a/components/autofill/core/browser/address_email_form_label_formatter.h +++ b/components/autofill/core/browser/address_email_form_label_formatter.h
@@ -20,6 +20,7 @@ class AddressEmailFormLabelFormatter : public LabelFormatter { public: AddressEmailFormLabelFormatter( + const std::vector<AutofillProfile*>& profiles, const std::string& app_locale, ServerFieldType focused_field_type, uint32_t groups,
diff --git a/components/autofill/core/browser/address_email_form_label_formatter_unittest.cc b/components/autofill/core/browser/address_email_form_label_formatter_unittest.cc index 5028083..5477d25 100644 --- a/components/autofill/core/browser/address_email_form_label_formatter_unittest.cc +++ b/components/autofill/core/browser/address_email_form_label_formatter_unittest.cc
@@ -38,8 +38,8 @@ TEST(AddressEmailFormLabelFormatterTest, GetLabelsWithMissingProfiles) { const std::vector<AutofillProfile*> profiles{}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "en-US", NAME_BILLING_FULL, GetFieldTypes(), profiles); - EXPECT_TRUE(formatter->GetLabels(profiles).empty()); + profiles, "en-US", NAME_BILLING_FULL, GetFieldTypes()); + EXPECT_TRUE(formatter->GetLabels().empty()); } TEST(AddressEmailFormLabelFormatterTest, GetLabelsForUSProfilesAndFocusedName) { @@ -68,10 +68,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3, &profile4}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "en-US", NAME_BILLING_FULL, GetFieldTypes(), profiles); + profiles, "en-US", NAME_BILLING_FULL, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("333 Washington St"), base::ASCIIToUTF16("jfk@gmail.com")}), base::ASCIIToUTF16("151 Irving Ave"), @@ -105,10 +105,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3, &profile4}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "en-US", ADDRESS_BILLING_LINE1, GetFieldTypes(), profiles); + profiles, "en-US", ADDRESS_BILLING_LINE1, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("John F Kennedy"), base::ASCIIToUTF16("jfk@gmail.com")}), base::ASCIIToUTF16("Jackie Kennedy"), @@ -142,10 +142,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3, &profile4}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "en-US", ADDRESS_BILLING_ZIP, GetFieldTypes(), profiles); + profiles, "en-US", ADDRESS_BILLING_ZIP, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("333 Washington St"), base::ASCIIToUTF16("jfk@gmail.com")}), base::ASCIIToUTF16("151 Irving Ave"), @@ -178,10 +178,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3, &profile4}; const std::unique_ptr<LabelFormatter> formatter = - LabelFormatter::Create("en-US", EMAIL_ADDRESS, GetFieldTypes(), profiles); + LabelFormatter::Create(profiles, "en-US", EMAIL_ADDRESS, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("John F Kennedy"), base::ASCIIToUTF16("333 Washington St")}), base::ASCIIToUTF16("Jackie Kennedy"), base::string16(), @@ -205,10 +205,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "pt-BR", NAME_BILLING_FULL, GetFieldTypes(), profiles); + profiles, "pt-BR", NAME_BILLING_FULL, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre( ConstructLabelLine( {base::UTF8ToUTF16("Av. Pedro Álvares Cabral, 1301"), @@ -235,10 +235,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "pt-BR", ADDRESS_BILLING_LINE1, GetFieldTypes(), profiles); + profiles, "pt-BR", ADDRESS_BILLING_LINE1, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre( ConstructLabelLine({base::ASCIIToUTF16("Tarsila do Amaral"), base::ASCIIToUTF16("tarsila@aol.com")}), @@ -264,10 +264,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "pt-BR", ADDRESS_BILLING_DEPENDENT_LOCALITY, GetFieldTypes(), profiles); + profiles, "pt-BR", ADDRESS_BILLING_DEPENDENT_LOCALITY, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre( ConstructLabelLine( {base::UTF8ToUTF16("Av. Pedro Álvares Cabral, 1301"), @@ -294,10 +294,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2}; const std::unique_ptr<LabelFormatter> formatter = - LabelFormatter::Create("pt-BR", EMAIL_ADDRESS, GetFieldTypes(), profiles); + LabelFormatter::Create(profiles, "pt-BR", EMAIL_ADDRESS, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre(ConstructLabelLine( {base::ASCIIToUTF16("Tarsila do Amaral"), base::UTF8ToUTF16("Av. Pedro Álvares Cabral, 1301")}), @@ -316,14 +316,13 @@ const std::vector<AutofillProfile*> profiles{&profile}; const std::unique_ptr<LabelFormatter> formatter = - LabelFormatter::Create("en-US", EMAIL_ADDRESS, + LabelFormatter::Create(profiles, "en-US", EMAIL_ADDRESS, {NAME_BILLING_FULL, EMAIL_ADDRESS, - ADDRESS_BILLING_CITY, ADDRESS_BILLING_STATE}, - profiles); + ADDRESS_BILLING_CITY, ADDRESS_BILLING_STATE}); // Checks that only address fields in the form are shown in the label. EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("John F Kennedy"), base::ASCIIToUTF16("Brookline, MA")}))); }
diff --git a/components/autofill/core/browser/address_form_label_formatter.cc b/components/autofill/core/browser/address_form_label_formatter.cc index 40de741a..b1c7628 100644 --- a/components/autofill/core/browser/address_form_label_formatter.cc +++ b/components/autofill/core/browser/address_form_label_formatter.cc
@@ -9,11 +9,16 @@ namespace autofill { AddressFormLabelFormatter::AddressFormLabelFormatter( + const std::vector<AutofillProfile*>& profiles, const std::string& app_locale, ServerFieldType focused_field_type, uint32_t groups, const std::vector<ServerFieldType>& field_types) - : LabelFormatter(app_locale, focused_field_type, groups, field_types), + : LabelFormatter(profiles, + app_locale, + focused_field_type, + groups, + field_types), form_has_street_address_(HasStreetAddress(field_types_for_labels())) {} AddressFormLabelFormatter::~AddressFormLabelFormatter() {}
diff --git a/components/autofill/core/browser/address_form_label_formatter.h b/components/autofill/core/browser/address_form_label_formatter.h index 06aaf6e..89103247 100644 --- a/components/autofill/core/browser/address_form_label_formatter.h +++ b/components/autofill/core/browser/address_form_label_formatter.h
@@ -19,7 +19,8 @@ // with name and address fields and without email or phone fields. class AddressFormLabelFormatter : public LabelFormatter { public: - AddressFormLabelFormatter(const std::string& app_locale, + AddressFormLabelFormatter(const std::vector<AutofillProfile*>& profiles, + const std::string& app_locale, ServerFieldType focused_field_type, uint32_t groups, const std::vector<ServerFieldType>& field_types);
diff --git a/components/autofill/core/browser/address_form_label_formatter_unittest.cc b/components/autofill/core/browser/address_form_label_formatter_unittest.cc index 78fb89d..ee38ede 100644 --- a/components/autofill/core/browser/address_form_label_formatter_unittest.cc +++ b/components/autofill/core/browser/address_form_label_formatter_unittest.cc
@@ -32,8 +32,8 @@ TEST(AddressFormLabelFormatterTest, GetLabelsWithMissingProfiles) { const std::vector<AutofillProfile*> profiles{}; const std::unique_ptr<LabelFormatter> formatter = - LabelFormatter::Create("en-US", NAME_FIRST, GetFieldTypes(), profiles); - EXPECT_TRUE(formatter->GetLabels(profiles).empty()); + LabelFormatter::Create(profiles, "en-US", NAME_FIRST, GetFieldTypes()); + EXPECT_TRUE(formatter->GetLabels().empty()); } TEST(AddressFormLabelFormatterTest, @@ -63,9 +63,9 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3, &profile4}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "en-US", ADDRESS_HOME_LINE1, GetFieldTypes(), profiles); + profiles, "en-US", ADDRESS_HOME_LINE1, GetFieldTypes()); - EXPECT_THAT(formatter->GetLabels(profiles), + EXPECT_THAT(formatter->GetLabels(), ElementsAre(ConstructLabelLine( {base::ASCIIToUTF16("John F Kennedy"), base::ASCIIToUTF16("Brookline, MA 02445")}), @@ -100,10 +100,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3, &profile4}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "en-US", ADDRESS_HOME_CITY, GetFieldTypes(), profiles); + profiles, "en-US", ADDRESS_HOME_CITY, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("John F Kennedy"), base::ASCIIToUTF16("333 Washington St")}), base::ASCIIToUTF16("151 Irving Ave"), @@ -125,10 +125,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2}; const std::unique_ptr<LabelFormatter> formatter = - LabelFormatter::Create("en-US", NAME_FIRST, GetFieldTypes(), profiles); + LabelFormatter::Create(profiles, "en-US", NAME_FIRST, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre(base::ASCIIToUTF16("333 Washington St, Brookline, MA 02445"), base::ASCIIToUTF16("151 Irving Ave, Hyannis, MA 02601"))); } @@ -143,10 +143,10 @@ const std::vector<AutofillProfile*> profiles{&profile}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "pt-BR", ADDRESS_HOME_LINE1, GetFieldTypes(), profiles); + profiles, "pt-BR", ADDRESS_HOME_LINE1, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre(ConstructLabelLine( {base::ASCIIToUTF16("Tarsila do Amaral"), base::UTF8ToUTF16("Vila Mariana, São Paulo-SP, 04094-050")}))); @@ -162,9 +162,9 @@ const std::vector<AutofillProfile*> profiles{&profile}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "pt-BR", ADDRESS_HOME_ZIP, GetFieldTypes(), profiles); + profiles, "pt-BR", ADDRESS_HOME_ZIP, GetFieldTypes()); - EXPECT_THAT(formatter->GetLabels(profiles), + EXPECT_THAT(formatter->GetLabels(), ElementsAre(ConstructLabelLine( {base::ASCIIToUTF16("Tarsila do Amaral"), base::UTF8ToUTF16("Av. Pedro Álvares Cabral, 1301")}))); @@ -179,9 +179,9 @@ const std::vector<AutofillProfile*> profiles{&profile}; const std::unique_ptr<LabelFormatter> formatter = - LabelFormatter::Create("pt-BR", NAME_FIRST, GetFieldTypes(), profiles); + LabelFormatter::Create(profiles, "pt-BR", NAME_FIRST, GetFieldTypes()); - EXPECT_THAT(formatter->GetLabels(profiles), + EXPECT_THAT(formatter->GetLabels(), ElementsAre(base::UTF8ToUTF16( "Av. Pedro Álvares Cabral, 1301, Vila Mariana, São " "Paulo-SP, 04094-050")));
diff --git a/components/autofill/core/browser/address_phone_form_label_formatter.cc b/components/autofill/core/browser/address_phone_form_label_formatter.cc index 7954ab4..5e3b964 100644 --- a/components/autofill/core/browser/address_phone_form_label_formatter.cc +++ b/components/autofill/core/browser/address_phone_form_label_formatter.cc
@@ -9,11 +9,16 @@ namespace autofill { AddressPhoneFormLabelFormatter::AddressPhoneFormLabelFormatter( + const std::vector<AutofillProfile*>& profiles, const std::string& app_locale, ServerFieldType focused_field_type, uint32_t groups, const std::vector<ServerFieldType>& field_types) - : LabelFormatter(app_locale, focused_field_type, groups, field_types), + : LabelFormatter(profiles, + app_locale, + focused_field_type, + groups, + field_types), form_has_street_address_(HasStreetAddress(field_types_for_labels())) {} AddressPhoneFormLabelFormatter::~AddressPhoneFormLabelFormatter() {}
diff --git a/components/autofill/core/browser/address_phone_form_label_formatter.h b/components/autofill/core/browser/address_phone_form_label_formatter.h index 3c56a3d6..d26aa124 100644 --- a/components/autofill/core/browser/address_phone_form_label_formatter.h +++ b/components/autofill/core/browser/address_phone_form_label_formatter.h
@@ -20,6 +20,7 @@ class AddressPhoneFormLabelFormatter : public LabelFormatter { public: AddressPhoneFormLabelFormatter( + const std::vector<AutofillProfile*>& profiles, const std::string& app_locale, ServerFieldType focused_field_type, uint32_t groups,
diff --git a/components/autofill/core/browser/address_phone_form_label_formatter_unittest.cc b/components/autofill/core/browser/address_phone_form_label_formatter_unittest.cc index bb64ba0..24f0aee7 100644 --- a/components/autofill/core/browser/address_phone_form_label_formatter_unittest.cc +++ b/components/autofill/core/browser/address_phone_form_label_formatter_unittest.cc
@@ -32,8 +32,8 @@ TEST(AddressPhoneFormLabelFormatterTest, GetLabelsWithMissingProfiles) { const std::vector<AutofillProfile*> profiles{}; const std::unique_ptr<LabelFormatter> formatter = - LabelFormatter::Create("en-US", NAME_FULL, GetFieldTypes(), profiles); - EXPECT_TRUE(formatter->GetLabels(profiles).empty()); + LabelFormatter::Create(profiles, "en-US", NAME_FULL, GetFieldTypes()); + EXPECT_TRUE(formatter->GetLabels().empty()); } TEST(AddressPhoneFormLabelFormatterTest, GetLabelsForUSProfilesAndFocusedName) { @@ -62,10 +62,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3, &profile4}; const std::unique_ptr<LabelFormatter> formatter = - LabelFormatter::Create("en-US", NAME_FULL, GetFieldTypes(), profiles); + LabelFormatter::Create(profiles, "en-US", NAME_FULL, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("(617) 730-2000"), base::ASCIIToUTF16("333 Washington St")}), base::ASCIIToUTF16("151 Irving Ave"), @@ -99,10 +99,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3, &profile4}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "en-US", ADDRESS_HOME_LINE1, GetFieldTypes(), profiles); + profiles, "en-US", ADDRESS_HOME_LINE1, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("John F Kennedy"), base::ASCIIToUTF16("(617) 730-2000")}), base::ASCIIToUTF16("Jackie Kennedy"), @@ -136,10 +136,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3, &profile4}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "en-US", ADDRESS_HOME_CITY, GetFieldTypes(), profiles); + profiles, "en-US", ADDRESS_HOME_CITY, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("333 Washington St"), base::ASCIIToUTF16("(617) 730-2000")}), base::ASCIIToUTF16("151 Irving Ave"), @@ -173,10 +173,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3, &profile4}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "en-US", PHONE_HOME_WHOLE_NUMBER, GetFieldTypes(), profiles); + profiles, "en-US", PHONE_HOME_WHOLE_NUMBER, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("John F Kennedy"), base::ASCIIToUTF16("333 Washington St")}), base::ASCIIToUTF16("Jackie Kennedy"), @@ -201,10 +201,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2}; const std::unique_ptr<LabelFormatter> formatter = - LabelFormatter::Create("pt-BR", NAME_FULL, GetFieldTypes(), profiles); + LabelFormatter::Create(profiles, "pt-BR", NAME_FULL, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre(ConstructLabelLine( {base::ASCIIToUTF16("(11) 2648-0254"), base::UTF8ToUTF16("Av. Pedro Álvares Cabral, 1301")}), @@ -231,10 +231,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "pt-BR", ADDRESS_HOME_LINE1, GetFieldTypes(), profiles); + profiles, "pt-BR", ADDRESS_HOME_LINE1, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("Tarsila do Amaral"), base::ASCIIToUTF16("(11) 2648-0254")}), ConstructLabelLine({base::ASCIIToUTF16("Artur Avila"), @@ -259,10 +259,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "pt-BR", ADDRESS_HOME_ZIP, GetFieldTypes(), profiles); + profiles, "pt-BR", ADDRESS_HOME_ZIP, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre( ConstructLabelLine( {base::UTF8ToUTF16("Av. Pedro Álvares Cabral, 1301"), @@ -289,10 +289,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "pt-BR", PHONE_HOME_WHOLE_NUMBER, GetFieldTypes(), profiles); + profiles, "pt-BR", PHONE_HOME_WHOLE_NUMBER, GetFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre(ConstructLabelLine( {base::ASCIIToUTF16("Tarsila do Amaral"), base::UTF8ToUTF16("Av. Pedro Álvares Cabral, 1301")}), @@ -311,12 +311,12 @@ const std::vector<AutofillProfile*> profiles{&profile}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "en-US", PHONE_HOME_WHOLE_NUMBER, - {NAME_FULL, PHONE_HOME_WHOLE_NUMBER, ADDRESS_HOME_ZIP}, profiles); + profiles, "en-US", PHONE_HOME_WHOLE_NUMBER, + {NAME_FULL, PHONE_HOME_WHOLE_NUMBER, ADDRESS_HOME_ZIP}); // Checks that only address fields in the form are shown in the label. EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("John F Kennedy"), base::ASCIIToUTF16("02445")}))); }
diff --git a/components/autofill/core/browser/contact_form_label_formatter.cc b/components/autofill/core/browser/contact_form_label_formatter.cc index aee524f2..c1d3c608 100644 --- a/components/autofill/core/browser/contact_form_label_formatter.cc +++ b/components/autofill/core/browser/contact_form_label_formatter.cc
@@ -10,11 +10,16 @@ namespace autofill { ContactFormLabelFormatter::ContactFormLabelFormatter( + const std::vector<AutofillProfile*>& profiles, const std::string& app_locale, ServerFieldType focused_field_type, uint32_t groups, const std::vector<ServerFieldType>& field_types) - : LabelFormatter(app_locale, focused_field_type, groups, field_types) {} + : LabelFormatter(profiles, + app_locale, + focused_field_type, + groups, + field_types) {} ContactFormLabelFormatter::~ContactFormLabelFormatter() {}
diff --git a/components/autofill/core/browser/contact_form_label_formatter.h b/components/autofill/core/browser/contact_form_label_formatter.h index c26852d..23bdc92 100644 --- a/components/autofill/core/browser/contact_form_label_formatter.h +++ b/components/autofill/core/browser/contact_form_label_formatter.h
@@ -19,7 +19,8 @@ // containing name and phone or email fields. class ContactFormLabelFormatter : public LabelFormatter { public: - ContactFormLabelFormatter(const std::string& app_locale, + ContactFormLabelFormatter(const std::vector<AutofillProfile*>& profiles, + const std::string& app_locale, ServerFieldType focused_field_type, uint32_t groups, const std::vector<ServerFieldType>& field_types);
diff --git a/components/autofill/core/browser/contact_form_label_formatter_unittest.cc b/components/autofill/core/browser/contact_form_label_formatter_unittest.cc index ecea6b8..d6cb6f0 100644 --- a/components/autofill/core/browser/contact_form_label_formatter_unittest.cc +++ b/components/autofill/core/browser/contact_form_label_formatter_unittest.cc
@@ -30,8 +30,8 @@ TEST(ContactFormLabelFormatterTest, GetLabelsWithMissingProfiles) { const std::vector<AutofillProfile*> profiles{}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "en-US", NAME_FIRST, GetNamePhoneAndEmailFieldTypes(), profiles); - EXPECT_TRUE(formatter->GetLabels(profiles).empty()); + profiles, "en-US", NAME_FIRST, GetNamePhoneAndEmailFieldTypes()); + EXPECT_TRUE(formatter->GetLabels().empty()); } TEST(ContactFormLabelFormatterTest, GetLabelsForUSProfilesAndFocusedName) { @@ -61,10 +61,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3, &profile4}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "en-US", NAME_LAST, GetNamePhoneAndEmailFieldTypes(), profiles); + profiles, "en-US", NAME_LAST, GetNamePhoneAndEmailFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("(617) 730-2000"), base::ASCIIToUTF16("jfk@gmail.com")}), base::ASCIIToUTF16("jackie@outlook.com"), @@ -97,10 +97,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3, &profile4}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "en-US", EMAIL_ADDRESS, GetNamePhoneAndEmailFieldTypes(), profiles); + profiles, "en-US", EMAIL_ADDRESS, GetNamePhoneAndEmailFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("John F Kennedy"), base::ASCIIToUTF16("(617) 730-2000")}), base::ASCIIToUTF16("Jackie Kennedy"), @@ -135,11 +135,11 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3, &profile4}; const std::unique_ptr<LabelFormatter> formatter = - LabelFormatter::Create("en-US", PHONE_HOME_WHOLE_NUMBER, - GetNamePhoneAndEmailFieldTypes(), profiles); + LabelFormatter::Create(profiles, "en-US", PHONE_HOME_WHOLE_NUMBER, + GetNamePhoneAndEmailFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre( ConstructLabelLine({base::ASCIIToUTF16("John F Kennedy"), base::ASCIIToUTF16("jfk@gmail.com")}), @@ -165,10 +165,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "pt-BR", NAME_LAST, GetNamePhoneAndEmailFieldTypes(), profiles); + profiles, "pt-BR", NAME_LAST, GetNamePhoneAndEmailFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre( ConstructLabelLine({base::ASCIIToUTF16("(11) 2648-0254"), base::ASCIIToUTF16("tarsila@aol.com")}), @@ -193,10 +193,10 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "pt-BR", EMAIL_ADDRESS, GetNamePhoneAndEmailFieldTypes(), profiles); + profiles, "pt-BR", EMAIL_ADDRESS, GetNamePhoneAndEmailFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("Tarsila do Amaral"), base::ASCIIToUTF16("(11) 2648-0254")}), ConstructLabelLine({base::ASCIIToUTF16("Artur Avila"), @@ -220,11 +220,11 @@ const std::vector<AutofillProfile*> profiles{&profile1, &profile2}; const std::unique_ptr<LabelFormatter> formatter = - LabelFormatter::Create("pt-BR", PHONE_HOME_WHOLE_NUMBER, - GetNamePhoneAndEmailFieldTypes(), profiles); + LabelFormatter::Create(profiles, "pt-BR", PHONE_HOME_WHOLE_NUMBER, + GetNamePhoneAndEmailFieldTypes()); EXPECT_THAT( - formatter->GetLabels(profiles), + formatter->GetLabels(), ElementsAre( ConstructLabelLine({base::ASCIIToUTF16("Tarsila do Amaral"), base::ASCIIToUTF16("tarsila@aol.com")}), @@ -240,13 +240,13 @@ "US", "16177302000"); const std::vector<AutofillProfile*> profiles{&profile}; - const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "en-US", NAME_LAST, {NAME_FIRST, NAME_LAST, PHONE_HOME_WHOLE_NUMBER}, - profiles); + const std::unique_ptr<LabelFormatter> formatter = + LabelFormatter::Create(profiles, "en-US", NAME_LAST, + {NAME_FIRST, NAME_LAST, PHONE_HOME_WHOLE_NUMBER}); // Checks that the email address is excluded when the form does not contain an // email field. - EXPECT_THAT(formatter->GetLabels(profiles), + EXPECT_THAT(formatter->GetLabels(), ElementsAre(base::ASCIIToUTF16("(617) 730-2000"))); } @@ -258,13 +258,13 @@ "US", "16177302000"); const std::vector<AutofillProfile*> profiles{&profile}; - const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "en-US", PHONE_HOME_WHOLE_NUMBER, - {NAME_FIRST, NAME_LAST, PHONE_HOME_WHOLE_NUMBER}, profiles); + const std::unique_ptr<LabelFormatter> formatter = + LabelFormatter::Create(profiles, "en-US", PHONE_HOME_WHOLE_NUMBER, + {NAME_FIRST, NAME_LAST, PHONE_HOME_WHOLE_NUMBER}); // Checks that the email address is excluded when the form does not contain an // email field. - EXPECT_THAT(formatter->GetLabels(profiles), + EXPECT_THAT(formatter->GetLabels(), ElementsAre(base::ASCIIToUTF16("John F Kennedy"))); } @@ -277,11 +277,11 @@ const std::vector<AutofillProfile*> profiles{&profile}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "en-US", NAME_LAST, {NAME_FIRST, NAME_LAST, EMAIL_ADDRESS}, profiles); + profiles, "en-US", NAME_LAST, {NAME_FIRST, NAME_LAST, EMAIL_ADDRESS}); // Checks that the phone number is excluded when the form does not contain a // phone field. - EXPECT_THAT(formatter->GetLabels(profiles), + EXPECT_THAT(formatter->GetLabels(), ElementsAre(base::ASCIIToUTF16("jfk@gmail.com"))); } @@ -294,11 +294,11 @@ const std::vector<AutofillProfile*> profiles{&profile}; const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create( - "en-US", EMAIL_ADDRESS, {NAME_FIRST, NAME_LAST, EMAIL_ADDRESS}, profiles); + profiles, "en-US", EMAIL_ADDRESS, {NAME_FIRST, NAME_LAST, EMAIL_ADDRESS}); // Checks that the phone number is excluded when the form does not contain a // phone field. - EXPECT_THAT(formatter->GetLabels(profiles), + EXPECT_THAT(formatter->GetLabels(), ElementsAre(base::ASCIIToUTF16("John F Kennedy"))); }
diff --git a/components/autofill/core/browser/label_formatter.cc b/components/autofill/core/browser/label_formatter.cc index 5fa3b42..273f0a84 100644 --- a/components/autofill/core/browser/label_formatter.cc +++ b/components/autofill/core/browser/label_formatter.cc
@@ -24,11 +24,13 @@ using data_util::bit_field_type_groups::kName; using data_util::bit_field_type_groups::kPhone; -LabelFormatter::LabelFormatter(const std::string& app_locale, +LabelFormatter::LabelFormatter(const std::vector<AutofillProfile*>& profiles, + const std::string& app_locale, ServerFieldType focused_field_type, uint32_t groups, const std::vector<ServerFieldType>& field_types) - : app_locale_(app_locale), + : profiles_(profiles), + app_locale_(app_locale), focused_field_type_(focused_field_type), groups_(groups) { const FieldTypeGroup focused_group = GetFocusedNonBillingGroup(); @@ -60,10 +62,9 @@ LabelFormatter::~LabelFormatter() = default; -std::vector<base::string16> LabelFormatter::GetLabels( - const std::vector<AutofillProfile*>& profiles) const { +std::vector<base::string16> LabelFormatter::GetLabels() const { std::vector<base::string16> labels; - for (const AutofillProfile* profile : profiles) { + for (const AutofillProfile* profile : profiles_) { labels.push_back(GetLabelForProfile(*profile, GetFocusedNonBillingGroup())); } return labels; @@ -76,32 +77,30 @@ // static std::unique_ptr<LabelFormatter> LabelFormatter::Create( + const std::vector<AutofillProfile*>& profiles, const std::string& app_locale, ServerFieldType focused_field_type, - const std::vector<ServerFieldType>& field_types, - const std::vector<AutofillProfile*>& profiles) { + const std::vector<ServerFieldType>& field_types) { const uint32_t groups = data_util::DetermineGroups(field_types); switch (groups) { case kName | kAddress | kEmail | kPhone: return std::make_unique<AddressContactFormLabelFormatter>( - app_locale, focused_field_type, groups, field_types, - !HaveSamePhoneNumbers(profiles, app_locale), - !HaveSameEmailAddresses(profiles, app_locale)); + profiles, app_locale, focused_field_type, groups, field_types); case kName | kAddress | kPhone: return std::make_unique<AddressPhoneFormLabelFormatter>( - app_locale, focused_field_type, groups, field_types); + profiles, app_locale, focused_field_type, groups, field_types); case kName | kAddress | kEmail: return std::make_unique<AddressEmailFormLabelFormatter>( - app_locale, focused_field_type, groups, field_types); + profiles, app_locale, focused_field_type, groups, field_types); case kName | kAddress: return std::make_unique<AddressFormLabelFormatter>( - app_locale, focused_field_type, groups, field_types); + profiles, app_locale, focused_field_type, groups, field_types); case kName | kEmail | kPhone: case kName | kEmail: case kName | kPhone: return std::make_unique<ContactFormLabelFormatter>( - app_locale, focused_field_type, groups, field_types); + profiles, app_locale, focused_field_type, groups, field_types); default: return nullptr; }
diff --git a/components/autofill/core/browser/label_formatter.h b/components/autofill/core/browser/label_formatter.h index 759837e..1f524ae 100644 --- a/components/autofill/core/browser/label_formatter.h +++ b/components/autofill/core/browser/label_formatter.h
@@ -18,7 +18,8 @@ // Handles the creation of Suggestions' disambiguating labels. class LabelFormatter { public: - LabelFormatter(const std::string& app_locale, + LabelFormatter(const std::vector<AutofillProfile*>& profiles, + const std::string& app_locale, ServerFieldType focused_field_type, uint32_t groups, const std::vector<ServerFieldType>& field_types); @@ -29,18 +30,17 @@ uint32_t groups() const { return groups_; } // Returns a collection of labels formed by extracting useful disambiguating - // information from a collection of |profiles_|. - std::vector<base::string16> GetLabels( - const std::vector<AutofillProfile*>& profiles) const; + // information from |profiles_|. + std::vector<base::string16> GetLabels() const; // Creates a form-specific LabelFormatter according to |field_types|. This // formatter has the ability to build labels with disambiguating information // from the given |profiles|. static std::unique_ptr<LabelFormatter> Create( + const std::vector<AutofillProfile*>& profiles, const std::string& app_locale, ServerFieldType focused_field_type, - const std::vector<ServerFieldType>& field_types, - const std::vector<AutofillProfile*>& profiles); + const std::vector<ServerFieldType>& field_types); protected: // Returns a label to show the user. The elements of the label and their @@ -65,6 +65,15 @@ } private: + // The collection of profiles for which to build labels. Storing this + // collection ensures that the profiles for which this formatter is created + // are the profiles for which the labels are constructed. + // + // It is safe to store a reference here because the LabelFormatter is + // destroyed when the suggestions for which the labels are constructed are + // returned. + const std::vector<AutofillProfile*>& profiles_; + // The locale for which to generate labels. This reflects the language and // country for which the application is translated, e.g. en-AU for Australian // English.
diff --git a/components/autofill/core/browser/label_formatter_unittest.cc b/components/autofill/core/browser/label_formatter_unittest.cc index ee933db..e60a5bf 100644 --- a/components/autofill/core/browser/label_formatter_unittest.cc +++ b/components/autofill/core/browser/label_formatter_unittest.cc
@@ -14,9 +14,9 @@ namespace { TEST(LabelFormatterTest, CreateWithMissingFieldTypes) { - EXPECT_EQ(LabelFormatter::Create("en-US", NAME_FIRST, - std::vector<ServerFieldType>(), - std::vector<AutofillProfile*>()), + const std::vector<AutofillProfile*> profiles{}; + EXPECT_EQ(LabelFormatter::Create(profiles, "en-US", NAME_FIRST, + std::vector<ServerFieldType>()), nullptr); }
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc index ef4c213..6c3d6a1b 100644 --- a/components/autofill/core/browser/personal_data_manager.cc +++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -1170,18 +1170,19 @@ std::unique_ptr<LabelFormatter> formatter; #if !defined(OS_ANDROID) && !defined(OS_IOS) - bool use_improved_label_disambiguation = base::FeatureList::IsEnabled( - autofill::features::kAutofillUseImprovedLabelDisambiguation); - formatter = use_improved_label_disambiguation - ? LabelFormatter::Create(app_locale_, type.GetStorableType(), - field_types, unique_matched_profiles) + // The formatter stores a constant reference to |unique_matched_profiles|. + // This is safe since the formatter is destroyed when this function returns. + formatter = base::FeatureList::IsEnabled( + autofill::features::kAutofillUseImprovedLabelDisambiguation) + ? LabelFormatter::Create(unique_matched_profiles, app_locale_, + type.GetStorableType(), field_types) : nullptr; #endif // !defined(OS_ANDROID) && !defined(OS_IOS) // Generate disambiguating labels based on the list of matches. std::vector<base::string16> labels; if (formatter) { - labels = formatter->GetLabels(unique_matched_profiles); + labels = formatter->GetLabels(); } else { AutofillProfile::CreateInferredLabels(unique_matched_profiles, &field_types, type.GetStorableType(), 1,
diff --git a/components/content_capture/renderer/content_capture_sender.cc b/components/content_capture/renderer/content_capture_sender.cc index e3730c7..15f4bdd0 100644 --- a/components/content_capture/renderer/content_capture_sender.cc +++ b/components/content_capture/renderer/content_capture_sender.cc
@@ -69,6 +69,9 @@ GetContentCaptureReceiver()->DidCaptureContent(frame_data, first_data); } +void ContentCaptureSender::DidUpdateContent( + const std::vector<scoped_refptr<blink::WebContentHolder>>& data) {} + void ContentCaptureSender::DidRemoveContent(const std::vector<int64_t>& data) { GetContentCaptureReceiver()->DidRemoveContent(data); }
diff --git a/components/content_capture/renderer/content_capture_sender.h b/components/content_capture/renderer/content_capture_sender.h index 5d653a0..bf82396 100644 --- a/components/content_capture/renderer/content_capture_sender.h +++ b/components/content_capture/renderer/content_capture_sender.h
@@ -42,9 +42,11 @@ void DidCaptureContent( const std::vector<scoped_refptr<blink::WebContentHolder>>& data, bool first_data) override; + void DidUpdateContent( + const std::vector<scoped_refptr<blink::WebContentHolder>>& data) override; void DidRemoveContent(const std::vector<int64_t>& data) override; - // mojom::ContentCaptureSender + // mojom::ContentCaptureSender: void StartCapture() override; void StopCapture() override;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.cc index 583e7a9..979d588 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.cc
@@ -56,7 +56,6 @@ const char kBuildNumberHeaderOption[] = "b"; const char kPatchNumberHeaderOption[] = "p"; const char kClientHeaderOption[] = "c"; -const char kExperimentsOption[] = "exp"; const char kPageIdOption[] = "pid"; // The empty version for the authentication protocol. Currently used by @@ -85,6 +84,7 @@ const std::string& version, DataReductionProxyConfig* config) : client_(util::GetStringForClient(client)), + server_experiments_(params::GetDataSaverServerExperiments()), data_reduction_proxy_config_(config), current_page_id_(base::RandUint64()) { DCHECK(data_reduction_proxy_config_); @@ -98,7 +98,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); key_ = GetDefaultKey(), UpdateCredentials(); - UpdateExperiments(); + RegenerateRequestHeaderValue(); // Called on the UI thread, but should be checked on the IO thread. thread_checker_.DetachFromThread(); } @@ -108,38 +108,6 @@ return header_value_; } -void DataReductionProxyRequestOptions::UpdateExperiments() { - experiments_.clear(); - std::string experiments = - base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( - data_reduction_proxy::switches::kDataReductionProxyExperiment); - - // The command line override takes precedence over field trial "exp" - // directives. - if (!experiments.empty()) { - base::StringTokenizer experiment_tokenizer(experiments, ", "); - experiment_tokenizer.set_quote_chars("\""); - while (experiment_tokenizer.GetNext()) { - if (!experiment_tokenizer.token().empty()) - experiments_.push_back(experiment_tokenizer.token()); - } - } else { - // If no other "exp" directive is forced by flags, add the field trial - // value. - AddServerExperimentFromFieldTrial(); - } - - RegenerateRequestHeaderValue(); -} - -void DataReductionProxyRequestOptions::AddServerExperimentFromFieldTrial() { - if (!params::IsIncludedInServerExperimentsFieldTrial()) - return; - const std::string server_experiment = variations::GetVariationParamValue( - params::GetServerExperimentsFieldTrialName(), kExperimentsOption); - if (!server_experiment.empty()) - experiments_.push_back(server_experiment); -} void DataReductionProxyRequestOptions::AddPageIDRequestHeader( net::HttpRequestHeaders* request_headers, @@ -248,8 +216,11 @@ DCHECK(!patch_.empty()); headers.push_back(FormatOption(kPatchNumberHeaderOption, patch_)); - for (const auto& experiment : experiments_) - headers.push_back(FormatOption(kExperimentsOption, experiment)); + if (!server_experiments_.empty()) { + headers.push_back( + FormatOption(params::GetDataSaverServerExperimentsOptionName(), + server_experiments_)); + } header_value_ = base::JoinString(headers, ", ");
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h index 29c6689..38980230 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h
@@ -32,7 +32,6 @@ extern const char kBuildNumberHeaderOption[]; extern const char kPatchNumberHeaderOption[]; extern const char kClientHeaderOption[]; -extern const char kExperimentsOption[]; #if defined(OS_ANDROID) extern const char kAndroidWebViewProtocolVersion[]; @@ -126,13 +125,6 @@ // session info. crbug.com/709624 void ResetPageId(); - // Updates the value of the experiments to be run and regenerate the header if - // necessary. - void UpdateExperiments(); - - // Adds the server-side experiment from the field trial. - void AddServerExperimentFromFieldTrial(); - // Generates and updates the session ID and credentials. void UpdateCredentials(); @@ -147,11 +139,11 @@ std::string key_; // Name of the client and version of the data reduction proxy protocol to use. - std::string client_; + const std::string client_; std::string secure_session_; std::string build_; std::string patch_; - std::vector<std::string> experiments_; + const std::string server_experiments_; // Must outlive |this|. DataReductionProxyConfig* data_reduction_proxy_config_;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc index f92a1f8..d64bf8f 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc
@@ -90,7 +90,7 @@ const std::string& build, const std::string& patch, const std::string& page_id, - const std::vector<std::string> experiments, + const std::string& server_experiments, std::string* expected_header) { std::vector<std::string> expected_options; if (!secure_session.empty()) { @@ -108,9 +108,10 @@ expected_options.push_back(std::string(kPatchNumberHeaderOption) + "=" + patch); - for (const auto& experiment : experiments) { + if (!server_experiments.empty()) { expected_options.push_back( - std::string(kExperimentsOption) + "=" + experiment); + std::string(params::GetDataSaverServerExperimentsOptionName()) + "=" + + server_experiments); } EXPECT_FALSE(page_id.empty()); @@ -182,12 +183,12 @@ TEST_F(DataReductionProxyRequestOptionsTest, AuthorizationOnIOThread) { std::string expected_header; SetHeaderExpectations(std::string(), kClientStr, kExpectedBuild, - kExpectedPatch, kPageId, std::vector<std::string>(), + kExpectedPatch, kPageId, std::string(), &expected_header); std::string expected_header2; SetHeaderExpectations(std::string(), kClientStr, kExpectedBuild, - kExpectedPatch, kPageId2, std::vector<std::string>(), + kExpectedPatch, kPageId2, std::string(), &expected_header2); CreateRequestOptions(kVersion); @@ -203,7 +204,7 @@ TEST_F(DataReductionProxyRequestOptionsTest, AuthorizationIgnoresEmptyKey) { std::string expected_header; SetHeaderExpectations(std::string(), kClientStr, kExpectedBuild, - kExpectedPatch, kPageId, std::vector<std::string>(), + kExpectedPatch, kPageId, std::string(), &expected_header); CreateRequestOptions(kVersion); VerifyExpectedHeader(expected_header, kPageIdValue); @@ -217,7 +218,7 @@ TEST_F(DataReductionProxyRequestOptionsTest, SecureSession) { std::string expected_header; SetHeaderExpectations(kSecureSession, kClientStr, kExpectedBuild, - kExpectedPatch, kPageId, std::vector<std::string>(), + kExpectedPatch, kPageId, std::string(), &expected_header); CreateRequestOptions(kVersion); @@ -228,7 +229,7 @@ TEST_F(DataReductionProxyRequestOptionsTest, CallsHeaderCallback) { std::string expected_header; SetHeaderExpectations(kSecureSession, kClientStr, kExpectedBuild, - kExpectedPatch, kPageId, std::vector<std::string>(), + kExpectedPatch, kPageId, std::string(), &expected_header); CreateRequestOptionsWithCallback(kVersion); @@ -247,13 +248,10 @@ TEST_F(DataReductionProxyRequestOptionsTest, ParseExperiments) { base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( data_reduction_proxy::switches::kDataReductionProxyExperiment, - "staging,\"foo,bar\""); - std::vector<std::string> expected_experiments; - expected_experiments.push_back("staging"); - expected_experiments.push_back("\"foo,bar\""); + "staging,foo,bar"); std::string expected_header; SetHeaderExpectations(std::string(), kClientStr, kExpectedBuild, - kExpectedPatch, kPageId, expected_experiments, + kExpectedPatch, kPageId, "staging,foo,bar", &expected_header); CreateRequestOptions(kVersion); @@ -282,42 +280,50 @@ // Experiments from command line switch should override. {kFieldTrialGroupFoo, kExperimentBar, false, kExperimentBar}, {kFieldTrialGroupBar, kExperimentFoo, false, kExperimentFoo}, - {kFieldTrialGroupFoo, kExperimentBar, true, kExperimentBar}, - {kFieldTrialGroupBar, kExperimentFoo, true, kExperimentFoo}, + {kFieldTrialGroupFoo, kExperimentBar, false, kExperimentBar}, + {kFieldTrialGroupBar, kExperimentFoo, false, kExperimentFoo}, + {kFieldTrialGroupFoo, kExperimentBar, true, std::string()}, + {kFieldTrialGroupBar, kExperimentFoo, true, std::string()}, }; std::map<std::string, std::string> server_experiment_foo, server_experiment_bar; - server_experiment_foo["exp"] = kExperimentFoo; - server_experiment_bar["exp"] = kExperimentBar; + server_experiment_foo[params::GetDataSaverServerExperimentsOptionName()] = + kExperimentFoo; + server_experiment_bar[params::GetDataSaverServerExperimentsOptionName()] = + kExperimentBar; ASSERT_TRUE(variations::AssociateVariationParams( - params::GetServerExperimentsFieldTrialName(), kFieldTrialGroupFoo, - server_experiment_foo)); + params::GetDataSaverServerExperimentsFieldTrialNameForTesting(), + kFieldTrialGroupFoo, server_experiment_foo)); ASSERT_TRUE(variations::AssociateVariationParams( - params::GetServerExperimentsFieldTrialName(), kFieldTrialGroupBar, - server_experiment_bar)); + params::GetDataSaverServerExperimentsFieldTrialNameForTesting(), + kFieldTrialGroupBar, server_experiment_bar)); for (const auto& test : tests) { - std::vector<std::string> expected_experiments; + std::string expected_experiments; base::CommandLine::ForCurrentProcess()->InitFromArgv(0, nullptr); - base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( - data_reduction_proxy::switches::kDataReductionProxyExperiment, - test.command_line_experiment); if (test.disable_server_experiments_via_flag) { base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( switches::kDataReductionProxyServerExperimentsDisabled, ""); + } else { + base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( + data_reduction_proxy::switches::kDataReductionProxyExperiment, + test.command_line_experiment); + base::CommandLine::ForCurrentProcess()->RemoveSwitch( + switches::kDataReductionProxyServerExperimentsDisabled); } std::string expected_header; base::FieldTrialList field_trial_list(nullptr); base::FieldTrialList::CreateFieldTrial( - params::GetServerExperimentsFieldTrialName(), test.field_trial_group); + params::GetDataSaverServerExperimentsFieldTrialNameForTesting(), + test.field_trial_group); if (!test.expected_experiment.empty()) - expected_experiments.push_back(test.expected_experiment); + expected_experiments = test.expected_experiment; SetHeaderExpectations(std::string(), kClientStr, kExpectedBuild, kExpectedPatch, kPageId, expected_experiments, @@ -335,16 +341,16 @@ // Field trial has the lowest priority. std::map<std::string, std::string> server_experiment; - server_experiment["exp"] = "foo"; + server_experiment[params::GetDataSaverServerExperimentsOptionName()] = "foo"; ASSERT_TRUE(variations::AssociateVariationParams( - params::GetServerExperimentsFieldTrialName(), "enabled", - server_experiment)); + params::GetDataSaverServerExperimentsFieldTrialNameForTesting(), + "enabled", server_experiment)); base::FieldTrialList field_trial_list(nullptr); base::FieldTrialList::CreateFieldTrial( - params::GetServerExperimentsFieldTrialName(), "enabled"); - std::vector<std::string> expected_experiments; - expected_experiments.push_back("foo"); + params::GetDataSaverServerExperimentsFieldTrialNameForTesting(), + "enabled"); + std::string expected_experiments = "foo"; std::string expected_header; SetHeaderExpectations(std::string(), kClientStr, kExpectedBuild, kExpectedPatch, kPageId, expected_experiments, @@ -355,8 +361,7 @@ // Setting the experiment explicitly has the highest priority. base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( data_reduction_proxy::switches::kDataReductionProxyExperiment, "bar"); - expected_experiments.clear(); - expected_experiments.push_back("bar"); + expected_experiments = "bar"; SetHeaderExpectations(std::string(), kClientStr, kExpectedBuild, kExpectedPatch, kPageId, expected_experiments, &expected_header);
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc index 7ab15d5..70b4878 100644 --- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc +++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc
@@ -57,6 +57,8 @@ // LitePage black list version. const char kLitePageBlackListVersion[] = "lite-page-blacklist-version"; +const char kExperimentsOption[] = "exp"; + bool IsIncludedInFieldTrial(const std::string& name) { return base::StartsWith(base::FieldTrialList::FindFullName(name), kEnabled, base::CompareCase::SENSITIVE); @@ -84,6 +86,13 @@ return false; } +// Returns true if this client is part of the field trial that should enable +// server experiments for the data reduction proxy. +bool IsIncludedInServerExperimentsFieldTrial() { + return base::FieldTrialList::FindFullName(kServerExperimentsFieldTrial) + .find(kDisabled) != 0; +} + } // namespace namespace data_reduction_proxy { @@ -124,13 +133,6 @@ return kLoFiFlagFieldTrial; } -bool IsIncludedInServerExperimentsFieldTrial() { - return !base::CommandLine::ForCurrentProcess()->HasSwitch( - data_reduction_proxy::switches:: - kDataReductionProxyServerExperimentsDisabled) && - base::FieldTrialList::FindFullName(kServerExperimentsFieldTrial) - .find(kDisabled) != 0; -} bool FetchWarmupProbeURLEnabled() { return !base::CommandLine::ForCurrentProcess()->HasSwitch( @@ -339,7 +341,37 @@ return true; } -const char* GetServerExperimentsFieldTrialName() { +std::string GetDataSaverServerExperimentsOptionName() { + return kExperimentsOption; +} + +std::string GetDataSaverServerExperiments() { + const std::string cmd_line_experiment = + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + data_reduction_proxy::switches::kDataReductionProxyExperiment); + + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + data_reduction_proxy::switches:: + kDataReductionProxyServerExperimentsDisabled)) { + // Both kDataReductionProxyExperiment and + // kDataReductionProxyServerExperimentsDisabled switches can't be set at the + // same time. + DCHECK(cmd_line_experiment.empty()); + return std::string(); + } + + // Experiment set using command line overrides field trial. + if (!cmd_line_experiment.empty()) + return cmd_line_experiment; + + // Next, check if the experiment is set using the field trial. + if (!IsIncludedInServerExperimentsFieldTrial()) + return std::string(); + return variations::GetVariationParamValue(kServerExperimentsFieldTrial, + kExperimentsOption); +} + +const char* GetDataSaverServerExperimentsFieldTrialNameForTesting() { return kServerExperimentsFieldTrial; }
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h index a85a167..611d61b 100644 --- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h +++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h
@@ -57,10 +57,6 @@ // TODO(ryansturm): crbug.com/759052 Cleanup once fully cutover to new blacklist const char* GetLoFiFlagFieldTrialName(); -// Returns true if this client is part of the field trial that should enable -// server experiments for the data reduction proxy. -bool IsIncludedInServerExperimentsFieldTrial(); - // Returns true if this client has the command line switch to enable forced // pageload metrics pingbacks on every page load. bool IsForcePingbackEnabledViaFlags(); @@ -104,8 +100,18 @@ bool GetOverrideProxiesForHttpFromCommandLine( std::vector<DataReductionProxyServer>* override_proxies_for_http); +// Returns the server experiments option name. This name is used in the request +// headers to the data saver proxy. This name is also used to set the experiment +// name using finch trial. +std::string GetDataSaverServerExperimentsOptionName(); + +// Returns the server experiment. This name is used in the request +// headers to the data saver proxy. Returned value may be empty indicating no +// experiment is enabled. +std::string GetDataSaverServerExperiments(); + // Returns the name of the server side experiment field trial. -const char* GetServerExperimentsFieldTrialName(); +const char* GetDataSaverServerExperimentsFieldTrialNameForTesting(); // Returns the URL to check to decide if the secure proxy origin should be // used.
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc index 7843f22..e096a9b3 100644 --- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc +++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc
@@ -13,6 +13,8 @@ #include "base/command_line.h" #include "base/macros.h" #include "base/metrics/field_trial.h" +#include "base/metrics/field_trial_param_associator.h" +#include "base/metrics/field_trial_params.h" #include "base/optional.h" #include "base/test/scoped_feature_list.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_features.h" @@ -112,36 +114,66 @@ bool expected; } tests[] = { { - "Field trial not set", "", false, true, + "Field trial not set", + "Enabled_42", + false, + true, }, { - "Field trial not set, flag set", "", true, false, - }, - { - "Enabled", "Enabled", false, true, - }, - { - "Enabled via field trial but disabled via flag", "Enabled", true, + "Field trial not set, flag set", + "", + true, false, }, { - "Disabled via field trial", "Disabled", false, false, + "Enabled", + "Enabled", + false, + true, + }, + { + "Enabled via field trial but disabled via flag", + "Enabled", + true, + false, + }, + { + "Disabled via field trial", + "Disabled", + false, + false, }, }; for (const auto& test : tests) { + base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting(); + base::FieldTrialList field_trial_list(nullptr); - if (!test.trial_group_value.empty()) { - ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( - "DataReductionProxyServerExperiments", test.trial_group_value)); + std::map<std::string, std::string> variation_params; + std::string exp_name; + + if (test.trial_group_value != "Disabled") { + exp_name = "foobar"; + variation_params[params::GetDataSaverServerExperimentsOptionName()] = + exp_name; + ASSERT_TRUE(base::AssociateFieldTrialParams( + params::GetDataSaverServerExperimentsFieldTrialNameForTesting(), + test.trial_group_value, variation_params)); + base::FieldTrialList::CreateFieldTrial( + params::GetDataSaverServerExperimentsFieldTrialNameForTesting(), + test.trial_group_value); } base::CommandLine::ForCurrentProcess()->InitFromArgv(0, nullptr); if (test.disable_flag_set) { + exp_name = ""; base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( switches::kDataReductionProxyServerExperimentsDisabled, ""); + } else { + base::CommandLine::ForCurrentProcess()->RemoveSwitch( + switches::kDataReductionProxyServerExperimentsDisabled); } - EXPECT_EQ(test.expected, params::IsIncludedInServerExperimentsFieldTrial()) + EXPECT_EQ(exp_name, params::GetDataSaverServerExperiments()) << test.test_case; } }
diff --git a/components/domain_reliability/util.cc b/components/domain_reliability/util.cc index 0531a83..06eb155 100644 --- a/components/domain_reliability/util.cc +++ b/components/domain_reliability/util.cc
@@ -136,6 +136,7 @@ case net::HttpResponseInfo::CONNECTION_INFO_QUIC_46: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_47: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_99: + case net::HttpResponseInfo::CONNECTION_INFO_QUIC_999: return "QUIC"; case net::HttpResponseInfo::NUM_OF_CONNECTION_INFOS: NOTREACHED();
diff --git a/components/download/public/background_service/test/test_download_service.cc b/components/download/public/background_service/test/test_download_service.cc index 07f6bb9..ed58d88 100644 --- a/components/download/public/background_service/test/test_download_service.cc +++ b/components/download/public/background_service/test/test_download_service.cc
@@ -127,6 +127,10 @@ ProcessDownload(); } +void TestDownloadService::SetHash256(const std::string& hash256) { + hash256_ = hash256; +} + void TestDownloadService::ProcessDownload() { DCHECK(!fail_at_start_); if (!is_ready_ || downloads_.empty()) @@ -142,6 +146,7 @@ } else { CompletionInfo completion_info(base::FilePath(), file_size_, {params.request_params.url}, nullptr); + completion_info.hash256 = hash256_; OnDownloadSucceeded(params.guid, completion_info); } }
diff --git a/components/download/public/background_service/test/test_download_service.h b/components/download/public/background_service/test/test_download_service.h index 112a46b..5999db5 100644 --- a/components/download/public/background_service/test/test_download_service.h +++ b/components/download/public/background_service/test/test_download_service.h
@@ -48,6 +48,8 @@ void SetIsReady(bool is_ready); + void SetHash256(const std::string& hash256); + void set_client(Client* client) { client_ = client; } private: @@ -67,6 +69,7 @@ std::unique_ptr<Logger> logger_; bool is_ready_; + std::string hash256_; std::string failed_download_id_; bool fail_at_start_; uint64_t file_size_;
diff --git a/components/ntp_tiles/constants.h b/components/ntp_tiles/constants.h index 7242fcc4..eb7a95f 100644 --- a/components/ntp_tiles/constants.h +++ b/components/ntp_tiles/constants.h
@@ -5,6 +5,8 @@ #ifndef COMPONENTS_NTP_TILES_CONSTANTS_H_ #define COMPONENTS_NTP_TILES_CONSTANTS_H_ +#include <stddef.h> + #include <utility> namespace ntp_tiles {
diff --git a/components/policy/core/common/policy_map_unittest.cc b/components/policy/core/common/policy_map_unittest.cc index d764914..1dc34a11 100644 --- a/components/policy/core/common/policy_map_unittest.cc +++ b/components/policy/core/common/policy_map_unittest.cc
@@ -513,6 +513,224 @@ EXPECT_TRUE(list_merged_wildcard.Equals(expected_list_merged_wildcard)); } +TEST_F(PolicyMapTest, MergeDictionaryValues) { + base::Value dict_a(base::Value::Type::DICTIONARY); + dict_a.SetBoolKey("keyA", true); + + base::Value dict_b(base::Value::Type::DICTIONARY); + dict_b.SetStringKey("keyB", "ValueB2"); + dict_b.SetStringKey("keyC", "ValueC2"); + dict_b.SetStringKey("keyD", "ValueD2"); + + base::Value dict_c(base::Value::Type::DICTIONARY); + dict_c.SetStringKey("keyA", "ValueA"); + dict_c.SetStringKey("keyB", "ValueB"); + dict_c.SetStringKey("keyC", "ValueC"); + dict_c.SetStringKey("keyD", "ValueD"); + dict_c.SetStringKey("keyZ", "ValueZ"); + + base::Value dict_d(base::Value::Type::DICTIONARY); + dict_d.SetStringKey("keyC", "ValueC3"); + + base::Value dict_e(base::Value::Type::DICTIONARY); + dict_e.SetStringKey("keyD", "ValueD4"); + dict_e.SetIntKey("keyE", 123); + + base::Value dict_f(base::Value::Type::DICTIONARY); + dict_f.SetStringKey("keyX", "ValueX"); + dict_f.SetStringKey("keyE", "ValueE5"); + + // Case 1: kTestPolicyName1 - Merging should only keep keys with the highest + // priority + PolicyMap::Entry case1(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, + POLICY_SOURCE_PRIORITY_CLOUD, + base::Value::ToUniquePtrValue(dict_a.Clone()), + nullptr); + case1.AddConflictingPolicy(PolicyMap::Entry( + POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_PLATFORM, + base::Value::ToUniquePtrValue(dict_b.Clone()), nullptr)); + case1.AddConflictingPolicy( + PolicyMap::Entry(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, + POLICY_SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE, + base::Value::ToUniquePtrValue(dict_c.Clone()), nullptr)); + case1.AddConflictingPolicy( + PolicyMap::Entry(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, + POLICY_SOURCE_ACTIVE_DIRECTORY, + base::Value::ToUniquePtrValue(dict_d.Clone()), nullptr)); + case1.AddConflictingPolicy( + PolicyMap::Entry(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, + POLICY_SOURCE_ACTIVE_DIRECTORY, + base::Value::ToUniquePtrValue(dict_f.Clone()), nullptr)); + + base::Value merged_dict_case1(base::Value::Type::DICTIONARY); + merged_dict_case1.MergeDictionary(&dict_f); + merged_dict_case1.MergeDictionary(&dict_d); + merged_dict_case1.MergeDictionary(&dict_c); + merged_dict_case1.MergeDictionary(&dict_b); + merged_dict_case1.MergeDictionary(&dict_a); + + PolicyMap::Entry case1_merged( + POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_MERGED, + base::Value::ToUniquePtrValue(merged_dict_case1.Clone()), nullptr); + case1_merged.AddConflictingPolicy(case1); + + // Case - kTestPolicyName2 + // Policies should only be merged with other policies with the same target, + // level and scope. + PolicyMap::Entry case2(POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE, + POLICY_SOURCE_PRIORITY_CLOUD, + base::Value::ToUniquePtrValue(dict_e.Clone()), + nullptr); + + case2.AddConflictingPolicy(PolicyMap::Entry( + POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE, POLICY_SOURCE_PLATFORM, + base::Value::ToUniquePtrValue(dict_f.Clone()), nullptr)); + + case2.AddConflictingPolicy(PolicyMap::Entry( + POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER, POLICY_SOURCE_PLATFORM, + base::Value::ToUniquePtrValue(dict_a.Clone()), nullptr)); + + base::Value merged_dict_case2(base::Value::Type::DICTIONARY); + merged_dict_case2.MergeDictionary(&dict_f); + merged_dict_case2.MergeDictionary(&dict_e); + + PolicyMap::Entry case2_merged( + POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE, POLICY_SOURCE_MERGED, + base::Value::ToUniquePtrValue(merged_dict_case2.Clone()), nullptr); + case2_merged.AddConflictingPolicy(case2); + + // Case 3 - kTestPolicyName3 + // Enterprise default policies should not be merged with other sources. + PolicyMap::Entry case3( + POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_PLATFORM, + base::Value::ToUniquePtrValue(dict_a.Clone()), nullptr); + + case3.AddConflictingPolicy(PolicyMap::Entry( + POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_ACTIVE_DIRECTORY, + base::Value::ToUniquePtrValue(dict_b.Clone()), nullptr)); + + case3.AddConflictingPolicy( + PolicyMap::Entry(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, + POLICY_SOURCE_ENTERPRISE_DEFAULT, + base::Value::ToUniquePtrValue(dict_e.Clone()), nullptr)); + + case3.AddConflictingPolicy( + PolicyMap::Entry(POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER, + POLICY_SOURCE_ENTERPRISE_DEFAULT, + base::Value::ToUniquePtrValue(dict_f.Clone()), nullptr)); + + base::Value merged_dict_case3(base::Value::Type::DICTIONARY); + merged_dict_case3.MergeDictionary(&dict_b); + merged_dict_case3.MergeDictionary(&dict_a); + + PolicyMap::Entry case3_merged( + POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_MERGED, + base::Value::ToUniquePtrValue(merged_dict_case3.Clone()), nullptr); + case3_merged.AddConflictingPolicy(case3); + + // Case 4 - kTestPolicyName4 + // Policies with a single source should stay the same. + PolicyMap::Entry case4(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, + POLICY_SOURCE_ACTIVE_DIRECTORY, + base::Value::ToUniquePtrValue(dict_a.Clone()), + nullptr); + + // Case 5 - kTestPolicyName5 + // Policies that are not dictionaries should not be merged. + // If such a policy is explicitly in the list of policies to merge, an error + // is added to the entry and the policy stays intact. + PolicyMap::Entry case5(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, + POLICY_SOURCE_ACTIVE_DIRECTORY, + std::make_unique<base::Value>("bad stuff"), nullptr); + + PolicyMap::Entry expected_case5(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, + POLICY_SOURCE_ACTIVE_DIRECTORY, + std::make_unique<base::Value>("bad stuff"), + nullptr); + expected_case5.AddError( + IDS_POLICY_DICTIONARY_MERGING_WRONG_POLICY_TYPE_SPECIFIED); + + // Case 6 - kTestPolicyName6 + // User cloud policies should not be merged with other sources. + PolicyMap::Entry case6( + POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_PLATFORM, + base::Value::ToUniquePtrValue(dict_a.Clone()), nullptr); + case6.AddConflictingPolicy(PolicyMap::Entry( + POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, + base::Value::ToUniquePtrValue(dict_e.Clone()), nullptr)); + case6.AddConflictingPolicy(PolicyMap::Entry( + POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_PRIORITY_CLOUD, + base::Value::ToUniquePtrValue(dict_f.Clone()), nullptr)); + + // Case 7 - kTestPolicyName7 + // Policies that are not dictionaries should not be merged. + // If such a policy is explicitly in the list of policies to merge, an error + // is added to the entry and the policy stays intact. + PolicyMap::Entry case7(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, + POLICY_SOURCE_ACTIVE_DIRECTORY, + base::Value::ToUniquePtrValue(dict_a.Clone()), + nullptr); + + PolicyMap::Entry expected_case7 = case7.DeepCopy(); + + expected_case7.AddError(IDS_POLICY_DICTIONARY_MERGING_POLICY_NOT_ALLOWED); + + PolicyMap policy_not_merged; + policy_not_merged.Set(kTestPolicyName1, case1.DeepCopy()); + policy_not_merged.Set(kTestPolicyName2, case2.DeepCopy()); + policy_not_merged.Set(kTestPolicyName3, case3.DeepCopy()); + policy_not_merged.Set(kTestPolicyName4, case4.DeepCopy()); + policy_not_merged.Set(kTestPolicyName5, case5.DeepCopy()); + policy_not_merged.Set(kTestPolicyName6, case6.DeepCopy()); + policy_not_merged.Set(kTestPolicyName7, case7.DeepCopy()); + + PolicyMap expected_list_merged; + expected_list_merged.Set(kTestPolicyName1, case1_merged.DeepCopy()); + expected_list_merged.Set(kTestPolicyName2, case2_merged.DeepCopy()); + expected_list_merged.Set(kTestPolicyName3, case3_merged.DeepCopy()); + expected_list_merged.Set(kTestPolicyName4, case4.DeepCopy()); + expected_list_merged.Set(kTestPolicyName5, expected_case5.DeepCopy()); + expected_list_merged.Set(kTestPolicyName6, case6.DeepCopy()); + expected_list_merged.Set(kTestPolicyName7, expected_case7.DeepCopy()); + + PolicyMap list_merged; + list_merged.CopyFrom(policy_not_merged); + + PolicyMap list_merged_wildcard; + list_merged_wildcard.CopyFrom(policy_not_merged); + + // Merging with no restrictions specified + PolicyDictionaryMerger empty_policy_list({}); + list_merged.MergeValues({&empty_policy_list}); + EXPECT_TRUE(list_merged.Equals(policy_not_merged)); + + PolicyDictionaryMerger bad_policy_list({"unknown"}); + // Merging with wrong restrictions specified + list_merged.MergeValues({&bad_policy_list}); + EXPECT_TRUE(list_merged.Equals(policy_not_merged)); + + // Merging lists restrictions specified + PolicyDictionaryMerger good_policy_list( + {kTestPolicyName1, kTestPolicyName2, kTestPolicyName3, kTestPolicyName4, + kTestPolicyName5, kTestPolicyName6, kTestPolicyName7}); + good_policy_list.SetAllowedPoliciesForTesting( + {kTestPolicyName1, kTestPolicyName2, kTestPolicyName3, kTestPolicyName4, + kTestPolicyName5, kTestPolicyName6}); + PolicyDictionaryMerger wildcard_policy_list({"*"}); + wildcard_policy_list.SetAllowedPoliciesForTesting( + {kTestPolicyName1, kTestPolicyName2, kTestPolicyName3, kTestPolicyName4, + kTestPolicyName5, kTestPolicyName6}); + list_merged.MergeValues({&good_policy_list}); + EXPECT_TRUE(list_merged.Equals(expected_list_merged)); + + PolicyMap expected_list_merged_wildcard; + expected_list_merged_wildcard.CopyFrom(expected_list_merged); + expected_list_merged_wildcard.Set(kTestPolicyName5, case5.DeepCopy()); + expected_list_merged_wildcard.Set(kTestPolicyName7, case7.DeepCopy()); + list_merged_wildcard.MergeValues({&wildcard_policy_list}); + EXPECT_TRUE(list_merged_wildcard.Equals(expected_list_merged_wildcard)); +} + TEST_F(PolicyMapTest, MergeValuesGroup) { std::vector<base::Value> abc = GetListStorage<std::string>({"a", "b", "c"}); std::vector<base::Value> ab = GetListStorage<std::string>({"a", "b"});
diff --git a/components/policy/core/common/policy_merger.cc b/components/policy/core/common/policy_merger.cc index bf77b030..4c85c09c 100644 --- a/components/policy/core/common/policy_merger.cc +++ b/components/policy/core/common/policy_merger.cc
@@ -11,6 +11,29 @@ namespace policy { +const char* const kDictionaryPoliciesToMerge[] = { + key::kContentPackManualBehaviorURLs, + key::kExtensionSettings, + key::kDeviceLoginScreenPowerManagement, + key::kKeyPermissions, + key::kPowerManagementIdleSettings, + key::kScreenBrightnessPercent, + key::kScreenLockDelays}; + +bool UseConflictValueInMerging(const PolicyMap::Entry& conflict, + const PolicyMap::Entry& policy) { + // On desktop, the user cloud policy potentially comes from a different + // domain than e.g. GPO policy or machine-level cloud policy, so prevent + // merging user cloud policy with other policy sources. + const bool is_conflict_user_cloud_policy = + conflict.scope == POLICY_SCOPE_USER && + (conflict.source == POLICY_SOURCE_CLOUD || + conflict.source == POLICY_SOURCE_PRIORITY_CLOUD); + return !is_conflict_user_cloud_policy && !conflict.IsBlockedOrIgnored() && + conflict.source != POLICY_SOURCE_ENTERPRISE_DEFAULT && + conflict.level == policy.level && conflict.scope == policy.scope; +} + PolicyMerger::PolicyMerger() = default; PolicyMerger::~PolicyMerger() = default; @@ -19,11 +42,14 @@ : policies_to_merge_(std::move(policies_to_merge)) {} PolicyListMerger::~PolicyListMerger() = default; +PolicyGroupMerger::PolicyGroupMerger() = default; +PolicyGroupMerger::~PolicyGroupMerger() = default; + void PolicyListMerger::Merge(PolicyMap::PolicyMapType* policies) const { DCHECK(policies); - for (auto it = policies->begin(); it != policies->end(); it++) { - if (CanMerge(it->first, it->second)) - (*policies)[it->first] = DoMerge(it->second); + for (auto& it : *policies) { + if (CanMerge(it.first, it.second)) + DoMerge(&it.second); } } @@ -46,9 +72,11 @@ return true; } -PolicyMap::Entry PolicyListMerger::DoMerge( - const PolicyMap::Entry& policy) const { - std::vector<const base::Value*> value; +void PolicyListMerger::DoMerge(PolicyMap::Entry* policy) const { + if (policy->conflicts.empty()) + return; + + std::vector<const base::Value*> merged_values; auto compare_value_ptr = [](const base::Value* a, const base::Value* b) { return *a < *b; }; @@ -56,24 +84,17 @@ compare_value_ptr); bool merged = false; - for (const base::Value& val : policy.value->GetList()) { + for (const base::Value& val : policy->value->GetList()) { if (duplicates.find(&val) != duplicates.end()) continue; duplicates.insert(&val); - value.push_back(&val); + merged_values.push_back(&val); } - for (const auto& it : policy.conflicts) { - // On desktop, the user cloud policy potentially comes from a different - // domain than e.g. GPO policy or machine-level cloud policy, so prevent - // merging user cloud policy with other policy sources. - const bool is_user_cloud_policy = - it.scope == POLICY_SCOPE_USER && - (it.source == POLICY_SOURCE_CLOUD || - it.source == POLICY_SOURCE_PRIORITY_CLOUD); - if (it.IsBlockedOrIgnored() || - it.source == POLICY_SOURCE_ENTERPRISE_DEFAULT || is_user_cloud_policy || - it.level != policy.level || it.scope != policy.scope) { + // Concatenates the values from accepted conflicting sources to the policy + // value while avoiding duplicates. + for (const auto& it : policy->conflicts) { + if (!UseConflictValueInMerging(it, *policy)) { continue; } @@ -81,28 +102,117 @@ if (duplicates.find(&val) != duplicates.end()) continue; duplicates.insert(&val); - value.push_back(&val); + merged_values.push_back(&val); } merged = true; } - auto result = policy.DeepCopy(); - if (merged) { - result.ClearConflicts(); - result.AddConflictingPolicy(policy); - result.source = POLICY_SOURCE_MERGED; - result.value.reset(new base::Value(base::Value::Type::LIST)); - for (const base::Value* it : value) - result.value->GetList().emplace_back(it->Clone()); - } + auto new_conflict = policy->DeepCopy(); - return result; + base::ListValue* new_value = new base::ListValue(); + for (const base::Value* it : merged_values) + new_value->GetList().emplace_back(it->Clone()); + + policy->value.reset(new_value); + policy->ClearConflicts(); + policy->AddConflictingPolicy(new_conflict); + policy->source = POLICY_SOURCE_MERGED; + } } -PolicyGroupMerger::PolicyGroupMerger() = default; -PolicyGroupMerger::~PolicyGroupMerger() = default; +PolicyDictionaryMerger::PolicyDictionaryMerger( + std::set<std::string> policies_to_merge) + : policies_to_merge_(std::move(policies_to_merge)), + allowed_policies_(std::begin(kDictionaryPoliciesToMerge), + std::end(kDictionaryPoliciesToMerge)) {} +PolicyDictionaryMerger::~PolicyDictionaryMerger() = default; + +void PolicyDictionaryMerger::Merge(PolicyMap::PolicyMapType* policies) const { + DCHECK(policies); + for (auto& it : *policies) { + if (CanMerge(it.first, it.second)) + DoMerge(&it.second); + } +} + +void PolicyDictionaryMerger::SetAllowedPoliciesForTesting( + std::set<std::string> allowed_policies) { + allowed_policies_ = std::move(allowed_policies); +} + +bool PolicyDictionaryMerger::CanMerge(const std::string& policy_name, + PolicyMap::Entry& policy) const { + if (policy.source == POLICY_SOURCE_MERGED) + return false; + + const bool allowed_to_merge = + allowed_policies_.find(policy_name) != allowed_policies_.end(); + + if (policies_to_merge_.find("*") != policies_to_merge_.end()) + return allowed_to_merge && policy.value->is_dict(); + + if (policies_to_merge_.find(policy_name) == policies_to_merge_.end()) + return false; + + if (!allowed_to_merge) { + policy.AddError(IDS_POLICY_DICTIONARY_MERGING_POLICY_NOT_ALLOWED); + return false; + } + + if (!policy.value->is_dict()) { + policy.AddError(IDS_POLICY_DICTIONARY_MERGING_WRONG_POLICY_TYPE_SPECIFIED); + return false; + } + + return true; +} + +void PolicyDictionaryMerger::DoMerge(PolicyMap::Entry* policy) const { + if (policy->conflicts.empty()) + return; + + bool merged = false; + std::vector<const PolicyMap::Entry*> policies; + policies.push_back(policy); + for (const auto& it : policy->conflicts) + policies.push_back(&it); + + std::sort(policies.begin(), policies.end(), + [](const PolicyMap::Entry* a, const PolicyMap::Entry* b) { + return b->has_higher_priority_than(*a); + }); + + base::DictionaryValue merged_dictionary; + // Merges all the keys from the policies from different sources. + for (const auto* it : policies) { + if (!UseConflictValueInMerging(*it, *policy)) { + continue; + } + + base::DictionaryValue* dict = nullptr; + + it->value->GetAsDictionary(&dict); + DCHECK(dict); + + for (const auto& pair : *dict) { + const auto& key = pair.first; + const auto& val = pair.second; + merged_dictionary.SetKey(key, val->Clone()); + } + + merged |= it != policy; + } + + if (merged) { + auto new_conflict = policy->DeepCopy(); + policy->ClearConflicts(); + policy->AddConflictingPolicy(new_conflict); + policy->source = POLICY_SOURCE_MERGED; + policy->value = base::Value::ToUniquePtrValue(std::move(merged_dictionary)); + } +} void PolicyGroupMerger::Merge(PolicyMap::PolicyMapType* policies) const { for (size_t i = 0; i < kPolicyAtomicGroupMappingsLength; ++i) {
diff --git a/components/policy/core/common/policy_merger.h b/components/policy/core/common/policy_merger.h index f071a1d90..14a59dc 100644 --- a/components/policy/core/common/policy_merger.h +++ b/components/policy/core/common/policy_merger.h
@@ -7,6 +7,7 @@ #include <stddef.h> #include <memory> +#include <set> #include <string> #include <vector> @@ -16,6 +17,8 @@ namespace policy { +extern const char* const kDictionaryPoliciesToMerge[]; + // Abstract class that provides an interface to apply custom merging logic on a // set of policies. class POLICY_EXPORT PolicyMerger { @@ -30,7 +33,7 @@ // multiple sources concatenated without duplicates. class POLICY_EXPORT PolicyListMerger : public PolicyMerger { public: - explicit PolicyListMerger(const std::set<std::string> policies_to_merge); + explicit PolicyListMerger(std::set<std::string> policies_to_merge); ~PolicyListMerger() override; // Merges the list policies from |policies| that have multiple sources. @@ -42,16 +45,46 @@ // target and scope. bool CanMerge(const std::string& policy_name, PolicyMap::Entry& policy) const; - // Returns a new entry that has merged the value from the different - // conflicting sources from |policy|. The resulting policy has |policy| and - // its conflicts as conflicts. - PolicyMap::Entry DoMerge(const PolicyMap::Entry& policy) const; + // Merges the values of |policy| if they come from multiple sources. Keeps + // track of the original values by leaving them as conflicts. |policy| must + // remain unchanged if there is nothing to merge. + void DoMerge(PolicyMap::Entry* policy) const; const std::set<std::string> policies_to_merge_; DISALLOW_COPY_AND_ASSIGN(PolicyListMerger); }; +// PolicyDictionaryMerger allows the merging of policy dictionaries that have +// multiple sources. Each policy that has to be merged will have its first level +// keys merged into one dictionary, each conflict will be resolved by +// using the key coming from the highest priority source. +class POLICY_EXPORT PolicyDictionaryMerger : public PolicyMerger { + public: + explicit PolicyDictionaryMerger(std::set<std::string> policies_to_merge); + ~PolicyDictionaryMerger() override; + + // Merges the dictionary policies from |policies| that have multiple sources. + void Merge(PolicyMap::PolicyMapType* policies) const override; + void SetAllowedPoliciesForTesting(std::set<std::string> allowed_policies); + + private: + // Returns True if |policy_name| is in the list of policies to merge and if + // |policy| has values from different sources that share the same level, + // target and scope. + bool CanMerge(const std::string& policy_name, PolicyMap::Entry& policy) const; + + // Merges the values of |policy| if they come from multiple sources. Keeps + // track of the original values by leaving them as conflicts. |policy| stays + // intact if there is nothing to merge. + void DoMerge(PolicyMap::Entry* policy) const; + + const std::set<std::string> policies_to_merge_; + std::set<std::string> allowed_policies_; + + DISALLOW_COPY_AND_ASSIGN(PolicyDictionaryMerger); +}; + // PolicyGroupMerger enforces atomic policy groups. It disables the policies // from a group that do not share the highest priority from that group. class POLICY_EXPORT PolicyGroupMerger : public PolicyMerger {
diff --git a/components/policy/core/common/policy_service_impl.cc b/components/policy/core/common/policy_service_impl.cc index 946800b..4b0472e 100644 --- a/components/policy/core/common/policy_service_impl.cc +++ b/components/policy/core/common/policy_service_impl.cc
@@ -71,6 +71,26 @@ } } +// Returns a list of string values of |policy|. Returns an empty array if +// the values are not strings. +std::set<std::string> GetStringListPolicyItems(const PolicyBundle& bundle, + const PolicyNamespace& space, + const std::string& policy) { + const PolicyMap& chrome_policies = bundle.Get(space); + const base::Value* items_ptr = chrome_policies.GetValue(policy); + + std::set<std::string> items; + + if (items_ptr) { + for (const auto& item : items_ptr->GetList()) { + if (item.is_string()) + items.emplace(item.GetString()); + } + } + + return items; +} + } // namespace PolicyServiceImpl::PolicyServiceImpl(Providers providers) @@ -196,17 +216,12 @@ } // Merges all the mergeable policies + std::set<std::string> policy_lists_to_merge = GetStringListPolicyItems( + bundle, chrome_namespace, key::kPolicyListMultipleSourceMergeList); + std::set<std::string> policy_dictionaries_to_merge = GetStringListPolicyItems( + bundle, chrome_namespace, key::kPolicyDictionaryMultipleSourceMergeList); + const auto& chrome_policies = bundle.Get(chrome_namespace); - auto* policy_lists_to_merge_ptr = - chrome_policies.GetValue(key::kPolicyListMultipleSourceMergeList); - - std::set<std::string> policy_lists_to_merge; - - if (policy_lists_to_merge_ptr) { - for (const auto& item : policy_lists_to_merge_ptr->GetList()) - policy_lists_to_merge.emplace(item.GetString()); - } - auto* value = chrome_policies.GetValue(key::kExtensionInstallListsMergeEnabled); if (value && value->GetBool()) { @@ -216,10 +231,14 @@ } PolicyListMerger policy_list_merger(std::move(policy_lists_to_merge)); + PolicyDictionaryMerger policy_dictionary_merger( + std::move(policy_dictionaries_to_merge)); PolicyGroupMerger policy_group_merger; - for (auto it = bundle.begin(); it != bundle.end(); ++it) - it->second->MergeValues({&policy_list_merger, &policy_group_merger}); + for (auto it = bundle.begin(); it != bundle.end(); ++it) { + it->second->MergeValues( + {&policy_list_merger, &policy_dictionary_merger, &policy_group_merger}); + } // Swap first, so that observers that call GetPolicies() see the current // values.
diff --git a/components/policy/core/common/policy_service_impl_unittest.cc b/components/policy/core/common/policy_service_impl_unittest.cc index 4332bbc..13bd863 100644 --- a/components/policy/core/common/policy_service_impl_unittest.cc +++ b/components/policy/core/common/policy_service_impl_unittest.cc
@@ -735,6 +735,64 @@ EXPECT_TRUE(VerifyPolicies(chrome_namespace, expected_chrome)); EXPECT_TRUE(VerifyPolicies(extension_namespace, expected_extension)); } +TEST_F(PolicyServiceTest, DictionaryPoliciesMerging) { + const PolicyNamespace chrome_namespace(POLICY_DOMAIN_CHROME, std::string()); + + std::unique_ptr<base::Value> dict1 = + std::make_unique<base::Value>(base::Value::Type::DICTIONARY); + dict1->SetBoolKey("google.com", false); + dict1->SetBoolKey("gmail.com", true); + std::unique_ptr<base::Value> dict2 = + std::make_unique<base::Value>(base::Value::Type::DICTIONARY); + dict2->SetBoolKey("example.com", true); + dict2->SetBoolKey("gmail.com", false); + std::unique_ptr<base::Value> result = + std::make_unique<base::Value>(base::Value::Type::DICTIONARY); + result->SetBoolKey("google.com", false); + result->SetBoolKey("gmail.com", false); + result->SetBoolKey("example.com", true); + + std::unique_ptr<base::Value> policy = + std::make_unique<base::Value>(base::Value::Type::LIST); + policy->GetList().push_back( + base::Value(policy::key::kContentPackManualBehaviorURLs)); + + auto policy_bundle1 = std::make_unique<PolicyBundle>(); + PolicyMap& policy_map1 = policy_bundle1->Get(chrome_namespace); + policy_map1.Set(key::kPolicyDictionaryMultipleSourceMergeList, + POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, + POLICY_SOURCE_PLATFORM, + base::Value::ToUniquePtrValue(policy->Clone()), nullptr); + PolicyMap::Entry entry_dict_1(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, + POLICY_SOURCE_PLATFORM, std::move(dict1), + nullptr); + policy_map1.Set(key::kContentPackManualBehaviorURLs, entry_dict_1.DeepCopy()); + + auto policy_bundle2 = std::make_unique<PolicyBundle>(); + PolicyMap& policy_map2 = policy_bundle2->Get(chrome_namespace); + PolicyMap::Entry entry_dict_2(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, + POLICY_SOURCE_PRIORITY_CLOUD, std::move(dict2), + nullptr); + policy_map2.Set(key::kContentPackManualBehaviorURLs, entry_dict_2.DeepCopy()); + + PolicyMap expected_chrome; + expected_chrome.Set(key::kPolicyDictionaryMultipleSourceMergeList, + POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, + POLICY_SOURCE_PLATFORM, + base::Value::ToUniquePtrValue(policy->Clone()), nullptr); + + PolicyMap::Entry merged(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, + POLICY_SOURCE_MERGED, std::move(result), nullptr); + merged.AddConflictingPolicy(entry_dict_1.DeepCopy()); + merged.AddConflictingPolicy(entry_dict_2.DeepCopy()); + expected_chrome.Set(key::kContentPackManualBehaviorURLs, std::move(merged)); + + provider0_.UpdatePolicy(std::move(policy_bundle1)); + provider1_.UpdatePolicy(std::move(policy_bundle2)); + RunUntilIdle(); + + EXPECT_TRUE(VerifyPolicies(chrome_namespace, expected_chrome)); +} TEST_F(PolicyServiceTest, ListsPoliciesMerging) { const PolicyNamespace chrome_namespace(POLICY_DOMAIN_CHROME, std::string());
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 17177dfb..3a700c3 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -6159,6 +6159,73 @@ 'label': '''Allow merging list policies from different sources''', }, { + 'name': 'PolicyDictionaryMultipleSourceMergeList', + 'type': 'string-enum-list', + 'schema': { + 'type': 'array', + 'items': { + 'type': 'string', + 'enum': [ 'ContentPackManualBehaviorURLs', 'ExtensionSettings', 'DeviceLoginScreenPowerManagement', 'KeyPermissions', 'PowerManagementIdleSettings', 'ScreenBrightnessPercent', 'ScreenLockDelays' ], + } + }, + 'items': [ + { + 'name': 'ContentPackManualBehaviorURLs', + 'value': 'ContentPackManualBehaviorURLs', + 'caption': '''Managed user manual exception URLs''', + }, + { + 'name': 'DeviceLoginScreenPowerManagement', + 'value': 'DeviceLoginScreenPowerManagement', + 'caption': '''Power management on the login screen''', + }, + { + 'name': 'ExtensionSettings', + 'value': 'ExtensionSettings', + 'caption': '''Extension management settings''', + }, + { + 'name': 'KeyPermissions', + 'value': 'KeyPermissions', + 'caption': '''Key Permissions''', + }, + { + 'name': 'PowerManagementIdleSettings', + 'value': 'PowerManagementIdleSettings', + 'caption': '''Power management settings when the user becomes idle''', + }, + { + 'name': 'ScreenBrightnessPercent', + 'value': 'ScreenBrightnessPercent', + 'caption': '''Screen brightness percent''', + }, + { + 'name': 'ScreenLockDelays', + 'value': 'ScreenLockDelays', + 'caption': '''Screen lock delays''', + }, + ], + 'supported_on': ['chrome.*:76-'], + 'features': { + 'dynamic_refresh': True, + 'per_profile': True, + }, + 'example_value': ['ExtensionSettings'], + 'id': 565, + 'caption': '''Allow merging dictionary policies from different sources''', + 'tags': [], + 'desc': '''Allows the selected policies to be merged when they come from different sources, with the same scopes and level. + + The merging consists in merging the first level keys of the dictionary from each source. In case of conflict between keys, the key coming from the highest priority source will be applied. + + If a policy is in the list, in case there is conflict between two sources, given that they have the same scopes and level, the values will be merged into a new policy dictionary. + + If a policy is in the list, in case there is conflict between two sources but also between different scopes and/or level, the policy with the highest priority will be applied. + + If a policy is not in the list, in case there is any conflict between sources, scopes and/or level, the policy with the highest priority will be applied.''', + 'label': '''Allow merging dictionary policies from different sources''', + }, + { 'name': 'OpenNetworkConfiguration', 'type': 'string', 'schema': { 'type': 'string' }, @@ -16653,5 +16720,5 @@ ], 'placeholders': [], 'deleted_policy_ids': [412, 546], - 'highest_id_currently_used': 564 + 'highest_id_currently_used': 565 }
diff --git a/components/policy_strings.grdp b/components/policy_strings.grdp index 3893c96..32be4891 100644 --- a/components/policy_strings.grdp +++ b/components/policy_strings.grdp
@@ -444,7 +444,13 @@ Hide status </message> <message name="IDS_POLICY_LIST_MERGING_WRONG_POLICY_TYPE_SPECIFIED" desc="Text explaining that a policy specified to be merged as a list is not a list."> - Warning: This policy was not merged as specified in PolicyListMultipleSourceMergeList policy because it is not a list. + Warning: This policy was not merged as a list as specified by policy because it is not a list. + </message> + <message name="IDS_POLICY_DICTIONARY_MERGING_WRONG_POLICY_TYPE_SPECIFIED" desc="Text explaining that a policy specified to be merged as a dictionary is not a dictionary."> + Warning: This policy was not merged as a dictionary as specified by policy because it is not a dictionary. + </message> + <message name="IDS_POLICY_DICTIONARY_MERGING_POLICY_NOT_ALLOWED" desc="Text explaining that a policy specified to be merged as a dictionary is not allowed to be merged."> + Warning: This policy was not merged as specified in PolicyDictionaryMultipleSourceMergeList policy because it is not part of the dictionary policies that can be merged. </message> <message name="IDS_POLICY_CONFLICT_SAME_VALUE" desc="Text explaining that a policy had conflicting sources, but with the same values."> Warning: More than one source is present for the policy, but the values are the same.
diff --git a/components/test/android/browsertests_apk/components_browser_tests_jni_onload.cc b/components/test/android/browsertests_apk/components_browser_tests_jni_onload.cc index 718e81f..f8f5c7a 100644 --- a/components/test/android/browsertests_apk/components_browser_tests_jni_onload.cc +++ b/components/test/android/browsertests_apk/components_browser_tests_jni_onload.cc
@@ -2,11 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <memory> + #include "base/android/jni_android.h" #include "base/android/library_loader/library_loader_hooks.h" #include "base/bind.h" +#include "base/message_loop/message_loop.h" #include "content/public/app/content_jni_onload.h" #include "content/public/app/content_main.h" +#include "content/public/test/nested_message_pump_android.h" #include "content/shell/app/shell_main_delegate.h" #include "testing/android/native_test/native_test_launcher.h" @@ -15,6 +19,17 @@ base::android::InitVM(vm); if (!content::android::OnJNIOnLoadInit()) return -1; + + // This needs to be done before base::TestSuite::Initialize() is called, + // as it also tries to set MessagePumpForUIFactory. + bool success = base::MessageLoop::InitMessagePumpForUIFactory( + []() -> std::unique_ptr<base::MessagePump> { + return std::make_unique<content::NestedMessagePumpAndroid>(); + }); + // If this fails, MessagePumpForUIFactory is already set, and we're unable to + // override. + DCHECK(success); + content::SetContentMainDelegate(new content::ShellMainDelegate()); return JNI_VERSION_1_4; }
diff --git a/components/viz/host/host_frame_sink_manager_unittest.cc b/components/viz/host/host_frame_sink_manager_unittest.cc index 34403f5..ac0229a 100644 --- a/components/viz/host/host_frame_sink_manager_unittest.cc +++ b/components/viz/host/host_frame_sink_manager_unittest.cc
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "base/run_loop.h" +#include "base/test/simple_test_tick_clock.h" #include "components/viz/common/display/renderer_settings.h" #include "components/viz/common/surfaces/frame_sink_id.h" #include "components/viz/common/surfaces/surface_id.h" @@ -23,6 +24,7 @@ #include "components/viz/test/fake_surface_observer.h" #include "components/viz/test/mock_compositor_frame_sink_client.h" #include "components/viz/test/mock_display_client.h" +#include "components/viz/test/surface_id_allocator_set.h" #include "services/viz/privileged/interfaces/compositing/frame_sink_manager.mojom.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -40,13 +42,6 @@ closure.Run(); } -// Makes a SurfaceId with a default nonce. -SurfaceId MakeSurfaceId(const FrameSinkId& frame_sink_id, uint32_t parent_id) { - return SurfaceId( - frame_sink_id, - LocalSurfaceId(parent_id, base::UnguessableToken::Deserialize(0, 1u))); -} - // Holds the four interface objects needed to create a RootCompositorFrameSink. struct RootCompositorFrameSinkData { mojom::RootCompositorFrameSinkParamsPtr BuildParams( @@ -146,12 +141,15 @@ void TearDown() override { host_manager_.reset(); manager_impl_.reset(); + now_src_.reset(); } protected: + std::unique_ptr<base::SimpleTestTickClock> now_src_; ServerSharedBitmapManager shared_bitmap_manager_; std::unique_ptr<HostFrameSinkManager> host_manager_; std::unique_ptr<testing::NiceMock<MockFrameSinkManagerImpl>> manager_impl_; + SurfaceIdAllocatorSet allocators_; private: DISALLOW_COPY_AND_ASSIGN(HostFrameSinkManagerTestBase); @@ -172,9 +170,11 @@ // testing::Test: void SetUp() override { + now_src_ = std::make_unique<base::SimpleTestTickClock>(); manager_impl_ = std::make_unique<testing::NiceMock<MockFrameSinkManagerImpl>>( &shared_bitmap_manager_); + manager_impl_->surface_manager()->SetTickClockForTesting(now_src_.get()); host_manager_ = std::make_unique<HostFrameSinkManager>(); manager_impl_->SetLocalClient(host_manager_.get()); @@ -274,8 +274,8 @@ FakeHostFrameSinkClient host_client_child; FrameSinkId kParentFrameSink(3, 0); FrameSinkId kChildFrameSink1(65563, 0); - const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1); - const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1); + const SurfaceId child_id1 = allocators_.MakeSurfaceId(kChildFrameSink1, 1); + const SurfaceId parent_id1 = allocators_.MakeSurfaceId(kParentFrameSink, 1); host().RegisterFrameSinkId(kParentFrameSink, &host_client_parent, ReportFirstSurfaceActivation::kYes); host().RegisterFrameSinkId(kChildFrameSink1, &host_client_child, @@ -301,7 +301,7 @@ // HostFrameSinkClient. EXPECT_EQ(0u, host_client_parent.last_frame_token_seen()); - parent_surface->ActivatePendingFrameForDeadline(base::nullopt); + parent_surface->ActivatePendingFrameForDeadline(); EXPECT_FALSE(parent_surface->has_deadline()); EXPECT_TRUE(parent_surface->HasActiveFrame()); EXPECT_FALSE(parent_surface->HasPendingFrame());
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn index bd5eb0a..e2bb3f0 100644 --- a/components/viz/service/BUILD.gn +++ b/components/viz/service/BUILD.gn
@@ -137,8 +137,6 @@ "frame_sinks/frame_sink_observer.h", "frame_sinks/gpu_vsync_begin_frame_source.cc", "frame_sinks/gpu_vsync_begin_frame_source.h", - "frame_sinks/primary_begin_frame_source.cc", - "frame_sinks/primary_begin_frame_source.h", "frame_sinks/root_compositor_frame_sink_impl.cc", "frame_sinks/root_compositor_frame_sink_impl.h", "frame_sinks/surface_resource_holder.cc", @@ -169,7 +167,6 @@ "surfaces/surface_allocation_group.cc", "surfaces/surface_allocation_group.h", "surfaces/surface_client.h", - "surfaces/surface_deadline_client.h", "surfaces/surface_dependency_deadline.cc", "surfaces/surface_dependency_deadline.h", "surfaces/surface_hittest.cc", @@ -425,7 +422,6 @@ "gl/gpu_service_impl_unittest.cc", "hit_test/hit_test_aggregator_unittest.cc", "surfaces/referenced_surface_tracker_unittest.cc", - "surfaces/surface_dependency_deadline_unittest.cc", "surfaces/surface_hittest_unittest.cc", "surfaces/surface_unittest.cc", ]
diff --git a/components/viz/service/display/frame_rate_decider_unittest.cc b/components/viz/service/display/frame_rate_decider_unittest.cc index 60071971..7b7406d8 100644 --- a/components/viz/service/display/frame_rate_decider_unittest.cc +++ b/components/viz/service/display/frame_rate_decider_unittest.cc
@@ -64,8 +64,8 @@ SurfaceId surface_id(frame_sink_id, local_surface_id); SurfaceInfo surface_info(surface_id, frame_.device_scale_factor(), frame_.size_in_pixels()); - auto* surface = surface_manager_->CreateSurface( - surface_client(), surface_info, &begin_frame_source_, false, false); + auto* surface = surface_manager_->CreateSurface(surface_client(), + surface_info, false, false); { FrameRateDecider::ScopedAggregate scope(frame_rate_decider_.get()); @@ -80,7 +80,7 @@ ASSERT_TRUE(surface->QueueFrame(MakeDefaultCompositorFrame(), frame_index, base::ScopedClosureRunner(), Surface::PresentedCallback())); - surface->ActivatePendingFrameForDeadline(base::nullopt); + surface->ActivatePendingFrameForDeadline(); ASSERT_EQ(surface->GetActiveFrameIndex(), frame_index); } @@ -92,7 +92,6 @@ CompositorFrame frame_; StubSurfaceClient surface_client_; - StubBeginFrameSource begin_frame_source_; }; TEST_F(FrameRateDeciderTest, ActiveSurfaceTrackingFrameIndexChange) {
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc index d0305b0..ade286e 100644 --- a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc +++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
@@ -74,7 +74,9 @@ // No video capture clients should remain after calling // UnregisterCompositorFrameSinkSupport(). DCHECK(capture_clients_.empty()); - DCHECK(!added_frame_observer_); + + if (begin_frame_source_ && added_frame_observer_) + begin_frame_source_->RemoveObserver(this); } PresentationFeedbackMap @@ -111,6 +113,10 @@ DCHECK(surface); DCHECK(surface->HasActiveFrame()); + pending_surfaces_.erase(surface); + if (pending_surfaces_.empty()) + UpdateNeedsBeginFramesInternal(); + const LocalSurfaceId& local_surface_id = surface->surface_id().local_surface_id(); const LocalSurfaceId& last_activated_local_surface_id = @@ -187,6 +193,8 @@ } void CompositorFrameSinkSupport::OnSurfaceDestroyed(Surface* surface) { + pending_surfaces_.erase(surface); + if (surface->surface_id() == last_activated_surface_id_) last_activated_surface_id_ = SurfaceId(); @@ -490,7 +498,10 @@ TRACE_EVENT_SCOPE_THREAD); return SubmitResult::ACCEPTED; } - current_surface = CreateSurface(surface_info, block_activation_on_parent); + + current_surface = surface_manager_->CreateSurface( + weak_factory_.GetWeakPtr(), surface_info, needs_sync_tokens_, + block_activation_on_parent); if (!current_surface) { TRACE_EVENT_INSTANT0("viz", "Surface belongs to another client", TRACE_EVENT_SCOPE_THREAD); @@ -513,13 +524,23 @@ frame_sink_manager()->SubmitHitTestRegionList( last_created_surface_id_, frame_index, std::move(hit_test_region_list)); - bool result = current_surface->QueueFrame( + Surface::QueueFrameResult result = current_surface->QueueFrame( std::move(frame), frame_index, std::move(frame_rejected_callback), base::BindOnce(&CompositorFrameSinkSupport::DidPresentCompositorFrame, weak_factory_.GetWeakPtr(), frame.metadata.frame_token)); - if (!result) { - TRACE_EVENT_INSTANT0("viz", "QueueFrame failed", TRACE_EVENT_SCOPE_THREAD); - return SubmitResult::SIZE_MISMATCH; + switch (result) { + case Surface::QueueFrameResult::REJECTED: + TRACE_EVENT_INSTANT0("viz", "QueueFrame failed", + TRACE_EVENT_SCOPE_THREAD); + return SubmitResult::SIZE_MISMATCH; + case Surface::QueueFrameResult::ACCEPTED_PENDING: + // Make sure we periodically check if the frame should activate. + pending_surfaces_.insert(current_surface); + UpdateNeedsBeginFramesInternal(); + break; + case Surface::QueueFrameResult::ACCEPTED_ACTIVE: + // Nothing to do here. + break; } if (begin_frame_source_) @@ -607,6 +628,8 @@ HandleCallback(); } + CheckPendingSurfaces(); + if (client_ && ShouldSendBeginFrame(args.frame_time)) { BeginFrameArgs copy_args = args; copy_args.trace_id = ComputeTraceId(); @@ -639,6 +662,7 @@ // requested it, or if the client needs to get some presentation feedbacks. bool needs_begin_frame = client_needs_begin_frame_ || !presentation_feedbacks_.empty() || + !pending_surfaces_.empty() || (compositor_frame_callback_ && !callback_received_begin_frame_); if (needs_begin_frame == added_frame_observer_) @@ -651,15 +675,6 @@ begin_frame_source_->RemoveObserver(this); } -Surface* CompositorFrameSinkSupport::CreateSurface( - const SurfaceInfo& surface_info, - bool block_activation_on_parent) { - return surface_manager_->CreateSurface( - weak_factory_.GetWeakPtr(), surface_info, - frame_sink_manager_->GetPrimaryBeginFrameSource(), needs_sync_tokens_, - block_activation_on_parent); -} - SubmitResult CompositorFrameSinkSupport::MaybeSubmitCompositorFrame( const LocalSurfaceId& local_surface_id, CompositorFrame frame, @@ -816,4 +831,13 @@ last_evicted_local_surface_id_.parent_sequence_number(); } +void CompositorFrameSinkSupport::CheckPendingSurfaces() { + if (pending_surfaces_.empty()) + return; + base::flat_set<Surface*> pending_surfaces(pending_surfaces_); + for (Surface* surface : pending_surfaces) { + surface->ActivateIfDeadlinePassed(); + } +} + } // namespace viz
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.h b/components/viz/service/frame_sinks/compositor_frame_sink_support.h index cdf4166..bfa8259 100644 --- a/components/viz/service/frame_sinks/compositor_frame_sink_support.h +++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.h
@@ -218,8 +218,6 @@ bool IsRoot() const override; void UpdateNeedsBeginFramesInternal(); - Surface* CreateSurface(const SurfaceInfo& surface_info, - bool block_activation_on_parent); // For the sync API calls, if we are blocking a client callback, runs it once // BeginFrame and FrameAck are done. @@ -233,6 +231,10 @@ bool IsEvicted(const LocalSurfaceId& local_surface_id) const; + // Checks if any of the pending surfaces should activate now because their + // deadline has passed. This is called every BeginFrame. + void CheckPendingSurfaces(); + mojom::CompositorFrameSinkClient* const client_; FrameSinkManagerImpl* const frame_sink_manager_; @@ -323,6 +325,9 @@ "|last_drawn_frame_index| relies on kFrameIndexStart > 1"); uint64_t last_drawn_frame_index_ = kFrameIndexStart - 1; + // The set of surfaces owned by this frame sink that have pending frame. + base::flat_set<Surface*> pending_surfaces_; + base::WeakPtrFactory<CompositorFrameSinkSupport> weak_factory_; DISALLOW_COPY_AND_ASSIGN(CompositorFrameSinkSupport);
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc b/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc index 3595893..8ec698e6 100644 --- a/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc +++ b/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc
@@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/stl_util.h" +#include "base/test/simple_test_tick_clock.h" #include "components/viz/common/frame_sinks/copy_output_request.h" #include "components/viz/common/frame_sinks/copy_output_result.h" #include "components/viz/common/quads/compositor_frame.h" @@ -97,6 +98,8 @@ frame_sync_token_(GenTestSyncToken(4)), consumer_sync_token_(GenTestSyncToken(5)) { manager_.SetLocalClient(&frame_sink_manager_client_); + now_src_ = std::make_unique<base::SimpleTestTickClock>(); + manager_.surface_manager()->SetTickClockForTesting(now_src_.get()); manager_.surface_manager()->AddObserver(&surface_observer_); manager_.RegisterFrameSinkId(kArbitraryFrameSinkId, true /* report_activation */); @@ -230,6 +233,7 @@ } protected: + std::unique_ptr<base::SimpleTestTickClock> now_src_; ServerSharedBitmapManager shared_bitmap_manager_; FrameSinkManagerImpl manager_; MockFrameSinkManagerClient frame_sink_manager_client_;
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc index 3a16274b..197b4bd 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc +++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
@@ -13,7 +13,6 @@ #include "components/viz/service/display/shared_bitmap_manager.h" #include "components/viz/service/display_embedder/output_surface_provider.h" #include "components/viz/service/frame_sinks/compositor_frame_sink_support.h" -#include "components/viz/service/frame_sinks/primary_begin_frame_source.h" #include "components/viz/service/frame_sinks/video_capture/capturable_frame_sink.h" #include "components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.h" @@ -425,8 +424,6 @@ registered_sources_[source] = frame_sink_id; RecursivelyAttachBeginFrameSource(frame_sink_id, source); - - primary_source_.OnBeginFrameSourceAdded(source); } void FrameSinkManagerImpl::UnregisterBeginFrameSource( @@ -437,8 +434,6 @@ FrameSinkId frame_sink_id = registered_sources_[source]; registered_sources_.erase(source); - primary_source_.OnBeginFrameSourceRemoved(source); - if (frame_sink_source_map_.count(frame_sink_id) == 0u) return; @@ -451,10 +446,6 @@ RecursivelyAttachBeginFrameSource(source_iter.second, source_iter.first); } -BeginFrameSource* FrameSinkManagerImpl::GetPrimaryBeginFrameSource() { - return &primary_source_; -} - void FrameSinkManagerImpl::RecursivelyAttachBeginFrameSource( const FrameSinkId& frame_sink_id, BeginFrameSource* source) {
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.h b/components/viz/service/frame_sinks/frame_sink_manager_impl.h index 4b0efa2..e339798 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_impl.h +++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.h
@@ -24,7 +24,6 @@ #include "components/viz/common/surfaces/frame_sink_id.h" #include "components/viz/service/frame_sinks/compositor_frame_sink_impl.h" #include "components/viz/service/frame_sinks/frame_sink_observer.h" -#include "components/viz/service/frame_sinks/primary_begin_frame_source.h" #include "components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h" #include "components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_manager.h" #include "components/viz/service/frame_sinks/video_detector.h" @@ -171,10 +170,6 @@ const FrameSinkId& frame_sink_id); void UnregisterBeginFrameSource(BeginFrameSource* source); - // Returns a stable BeginFrameSource that forwards BeginFrames from the first - // available BeginFrameSource. - BeginFrameSource* GetPrimaryBeginFrameSource(); - SurfaceManager* surface_manager() { return &surface_manager_; } const HitTestManager* hit_test_manager() { return &hit_test_manager_; } SharedBitmapManager* shared_bitmap_manager() { @@ -281,9 +276,6 @@ // Provides an output surface for CreateRootCompositorFrameSink(). OutputSurfaceProvider* const output_surface_provider_; - PrimaryBeginFrameSource primary_source_; - - // Must be created after and destroyed before |primary_source_|. SurfaceManager surface_manager_; // Must be created after and destroyed before |surface_manager_|.
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc b/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc index 17e6cd8..f4af32d 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc +++ b/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc
@@ -207,72 +207,6 @@ EXPECT_EQ(nullptr, GetBeginFrameSource(client)); } -// This test verifies that a PrimaryBeginFrameSource will receive BeginFrames -// from the first BeginFrameSource registered. If that BeginFrameSource goes -// away then it will receive BeginFrames from the second BeginFrameSource. -TEST_F(FrameSinkManagerTest, PrimaryBeginFrameSource) { - // This PrimaryBeginFrameSource should track the first BeginFrameSource - // registered with the SurfaceManager. - testing::NiceMock<MockBeginFrameObserver> obs; - BeginFrameSource* begin_frame_source = manager_.GetPrimaryBeginFrameSource(); - begin_frame_source->AddObserver(&obs); - - auto root1 = CreateCompositorFrameSinkSupport(FrameSinkId(1, 1)); - std::unique_ptr<FakeExternalBeginFrameSource> external_source1 = - std::make_unique<FakeExternalBeginFrameSource>(60.f, false); - manager_.RegisterBeginFrameSource(external_source1.get(), - root1->frame_sink_id()); - - auto root2 = CreateCompositorFrameSinkSupport(FrameSinkId(2, 2)); - std::unique_ptr<FakeExternalBeginFrameSource> external_source2 = - std::make_unique<FakeExternalBeginFrameSource>(60.f, false); - manager_.RegisterBeginFrameSource(external_source2.get(), - root2->frame_sink_id()); - - // Ticking |external_source2| does not propagate to |begin_frame_source|. - { - BeginFrameArgs args = CreateBeginFrameArgsForTesting( - BEGINFRAME_FROM_HERE, external_source2->source_id(), 1); - EXPECT_CALL(obs, OnBeginFrame(testing::_)).Times(0); - external_source2->TestOnBeginFrame(args); - testing::Mock::VerifyAndClearExpectations(&obs); - } - - // Ticking |external_source1| does propagate to |begin_frame_source| and - // |obs|. - { - BeginFrameArgs args = CreateBeginFrameArgsForTesting( - BEGINFRAME_FROM_HERE, external_source1->source_id(), 1); - EXPECT_CALL(obs, OnBeginFrame(args)).Times(1); - external_source1->TestOnBeginFrame(args); - testing::Mock::VerifyAndClearExpectations(&obs); - } - - // Getting rid of |external_source1| means those BeginFrames will not - // propagate. Instead, |external_source2|'s BeginFrames will propagate - // to |begin_frame_source|. - { - BeginFrameArgs args = CreateBeginFrameArgsForTesting( - BEGINFRAME_FROM_HERE, external_source1->source_id(), 2); - manager_.UnregisterBeginFrameSource(external_source1.get()); - EXPECT_CALL(obs, OnBeginFrame(testing::_)).Times(0); - external_source1->TestOnBeginFrame(args); - testing::Mock::VerifyAndClearExpectations(&obs); - } - - { - BeginFrameArgs args = CreateBeginFrameArgsForTesting( - BEGINFRAME_FROM_HERE, external_source2->source_id(), 2); - EXPECT_CALL(obs, OnBeginFrame(testing::_)).Times(1); - external_source2->TestOnBeginFrame(args); - testing::Mock::VerifyAndClearExpectations(&obs); - } - - // Tear down - manager_.UnregisterBeginFrameSource(external_source2.get()); - begin_frame_source->RemoveObserver(&obs); -} - TEST_F(FrameSinkManagerTest, MultipleDisplays) { StubBeginFrameSource root1_source; StubBeginFrameSource root2_source;
diff --git a/components/viz/service/frame_sinks/primary_begin_frame_source.cc b/components/viz/service/frame_sinks/primary_begin_frame_source.cc deleted file mode 100644 index 181f296ec..0000000 --- a/components/viz/service/frame_sinks/primary_begin_frame_source.cc +++ /dev/null
@@ -1,98 +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 "components/viz/service/frame_sinks/primary_begin_frame_source.h" - -namespace viz { - -PrimaryBeginFrameSource::PrimaryBeginFrameSource() - : BeginFrameSource(kNotRestartableId), begin_frame_source_(this) {} - -PrimaryBeginFrameSource::~PrimaryBeginFrameSource() = default; - -void PrimaryBeginFrameSource::OnBeginFrameSourceAdded( - BeginFrameSource* begin_frame_source) { - sources_.insert(begin_frame_source); - - if (current_begin_frame_source_) - return; - - current_begin_frame_source_ = begin_frame_source; - if (needs_begin_frames_ && current_begin_frame_source_) - current_begin_frame_source_->AddObserver(this); -} - -void PrimaryBeginFrameSource::OnBeginFrameSourceRemoved( - BeginFrameSource* begin_frame_source) { - sources_.erase(begin_frame_source); - if (current_begin_frame_source_ != begin_frame_source) - return; - - if (needs_begin_frames_) - current_begin_frame_source_->RemoveObserver(this); - - if (!sources_.empty()) - current_begin_frame_source_ = *sources_.begin(); - else - current_begin_frame_source_ = nullptr; - - if (needs_begin_frames_ && current_begin_frame_source_) - current_begin_frame_source_->AddObserver(this); -} - -void PrimaryBeginFrameSource::OnBeginFrame(const BeginFrameArgs& args) { - begin_frame_source_.OnBeginFrame(args); - last_begin_frame_args_ = args; -} - -const BeginFrameArgs& PrimaryBeginFrameSource::LastUsedBeginFrameArgs() const { - return last_begin_frame_args_; -} - -bool PrimaryBeginFrameSource::WantsAnimateOnlyBeginFrames() const { - // Forward animate_only BeginFrames. - return true; -} - -void PrimaryBeginFrameSource::OnBeginFrameSourcePausedChanged(bool paused) {} - -void PrimaryBeginFrameSource::DidFinishFrame(BeginFrameObserver* obs) { - begin_frame_source_.DidFinishFrame(obs); -} - -void PrimaryBeginFrameSource::AddObserver(BeginFrameObserver* obs) { - begin_frame_source_.AddObserver(obs); -} - -void PrimaryBeginFrameSource::RemoveObserver(BeginFrameObserver* obs) { - begin_frame_source_.RemoveObserver(obs); -} - -bool PrimaryBeginFrameSource::IsThrottled() const { - return current_begin_frame_source_ - ? current_begin_frame_source_->IsThrottled() - : true; -} - -void PrimaryBeginFrameSource::OnGpuNoLongerBusy() { - // PrimaryBeginFrameSource does not hold back the begin frames. So it doesn't - // need to do anything here. -} - -void PrimaryBeginFrameSource::OnNeedsBeginFrames(bool needs_begin_frames) { - if (needs_begin_frames_ == needs_begin_frames) - return; - - needs_begin_frames_ = needs_begin_frames; - - if (!current_begin_frame_source_) - return; - - if (needs_begin_frames_) - current_begin_frame_source_->AddObserver(this); - else - current_begin_frame_source_->RemoveObserver(this); -} - -} // namespace viz
diff --git a/components/viz/service/frame_sinks/primary_begin_frame_source.h b/components/viz/service/frame_sinks/primary_begin_frame_source.h deleted file mode 100644 index 3ba4bf98..0000000 --- a/components/viz/service/frame_sinks/primary_begin_frame_source.h +++ /dev/null
@@ -1,60 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_VIZ_SERVICE_FRAME_SINKS_PRIMARY_BEGIN_FRAME_SOURCE_H_ -#define COMPONENTS_VIZ_SERVICE_FRAME_SINKS_PRIMARY_BEGIN_FRAME_SOURCE_H_ - -#include "base/containers/flat_set.h" -#include "components/viz/common/frame_sinks/begin_frame_source.h" -#include "components/viz/service/viz_service_export.h" - -namespace viz { - -// PrimaryBeginFrameSource echos the first BeginFrameSource in the system. -// If the first source goes away then it will echo the new first -// BeginFrameSource. -class VIZ_SERVICE_EXPORT PrimaryBeginFrameSource - : public BeginFrameSource, - public BeginFrameObserver, - public ExternalBeginFrameSourceClient { - public: - PrimaryBeginFrameSource(); - ~PrimaryBeginFrameSource() override; - - void OnBeginFrameSourceAdded(BeginFrameSource* begin_frame_source); - void OnBeginFrameSourceRemoved(BeginFrameSource* begin_frame_source); - - // BeginFrameObserver implementation. - void OnBeginFrame(const BeginFrameArgs& args) override; - const BeginFrameArgs& LastUsedBeginFrameArgs() const override; - void OnBeginFrameSourcePausedChanged(bool paused) override; - bool WantsAnimateOnlyBeginFrames() const override; - - // BeginFrameSource implementation. - void DidFinishFrame(BeginFrameObserver* obs) override; - void AddObserver(BeginFrameObserver* obs) override; - void RemoveObserver(BeginFrameObserver* obs) override; - bool IsThrottled() const override; - void OnGpuNoLongerBusy() override; - - // ExternalBeginFrameSourceClient implementation. - void OnNeedsBeginFrames(bool needs_begin_frames) override; - - private: - ExternalBeginFrameSource begin_frame_source_; - BeginFrameSource* current_begin_frame_source_ = nullptr; - - // The last begin frame args generated by the begin frame source. - BeginFrameArgs last_begin_frame_args_; - - bool needs_begin_frames_ = false; - - base::flat_set<BeginFrameSource*> sources_; - - DISALLOW_COPY_AND_ASSIGN(PrimaryBeginFrameSource); -}; - -} // namespace viz - -#endif // COMPONENTS_VIZ_SERVICE_FRAME_SINKS_PRIMARY_BEGIN_FRAME_SOURCE_H_
diff --git a/components/viz/service/frame_sinks/surface_synchronization_unittest.cc b/components/viz/service/frame_sinks/surface_synchronization_unittest.cc index 382a986..491380f 100644 --- a/components/viz/service/frame_sinks/surface_synchronization_unittest.cc +++ b/components/viz/service/frame_sinks/surface_synchronization_unittest.cc
@@ -212,6 +212,12 @@ // BeginFrames, since the frame sink hierarchy is not set up in this test. frame_sink_manager_.RegisterBeginFrameSource(begin_frame_source_.get(), kDisplayFrameSink); + frame_sink_manager_.RegisterFrameSinkHierarchy(kDisplayFrameSink, + kParentFrameSink); + frame_sink_manager_.RegisterFrameSinkHierarchy(kDisplayFrameSink, + kChildFrameSink1); + frame_sink_manager_.RegisterFrameSinkHierarchy(kDisplayFrameSink, + kChildFrameSink2); } void TearDown() override { @@ -1923,22 +1929,9 @@ // alive by the display. DestroyFrameSink(kParentFrameSink); - Surface* parent_surface = GetSurfaceForId(parent_id); - ASSERT_NE(nullptr, parent_surface); - - EXPECT_TRUE(parent_surface->has_deadline()); - EXPECT_TRUE(parent_surface->HasActiveFrame()); - EXPECT_TRUE(parent_surface->HasPendingFrame()); - - // Advance BeginFrames to trigger a deadline. This activates the - // CompositorFrame submitted above. - for (int i = 0; i < 4; ++i) - SendNextBeginFrame(); - // The parent surface stays alive through the display. - parent_surface = GetSurfaceForId(parent_id); + Surface* parent_surface = GetSurfaceForId(parent_id); EXPECT_NE(nullptr, parent_surface); - EXPECT_TRUE(surface_observer().IsSurfaceDamaged(parent_id)); // Submitting a new CompositorFrame to the display should free the parent. display_support().SubmitCompositorFrame(display_id.local_surface_id(), @@ -1975,7 +1968,7 @@ // Activate the pending frame in |parent_id2|. previous_frame_surface_id() // should still return |parent_id1|. - parent_surface2->ActivatePendingFrameForDeadline(base::nullopt); + parent_surface2->ActivatePendingFrameForDeadline(); EXPECT_TRUE(parent_surface2->HasActiveFrame()); EXPECT_FALSE(parent_surface2->HasPendingFrame()); EXPECT_EQ(parent_id1, parent_surface2->previous_frame_surface_id()); @@ -2008,7 +2001,7 @@ // Activate the pending frame. GetActiveFrameIndex should return the frame // index of the newly activated frame. - parent_surface->ActivatePendingFrameForDeadline(base::nullopt); + parent_surface->ActivatePendingFrameForDeadline(); EXPECT_EQ(initial_frame_index + n_iterations, parent_surface->GetActiveFrameIndex()); }
diff --git a/components/viz/service/surfaces/surface.cc b/components/viz/service/surfaces/surface.cc index f16d0a1..8af4d18 100644 --- a/components/viz/service/surfaces/surface.cc +++ b/components/viz/service/surfaces/surface.cc
@@ -12,6 +12,7 @@ #include "base/metrics/histogram_functions.h" #include "base/stl_util.h" #include "base/time/tick_clock.h" +#include "base/trace_event/trace_event.h" #include "components/viz/common/frame_sinks/copy_output_request.h" #include "components/viz/common/resources/returned_resource.h" #include "components/viz/common/resources/transferable_resource.h" @@ -176,16 +177,25 @@ return; // All blockers have been cleared. The surface can be activated now. - ActivatePendingFrame(base::nullopt); + ActivatePendingFrame(); } void Surface::SetIsFallbackAndMaybeActivate() { is_fallback_ = true; if (HasPendingFrame()) - ActivatePendingFrameForDeadline(base::nullopt); + ActivatePendingFrameForDeadline(); } -bool Surface::QueueFrame( +void Surface::ActivateIfDeadlinePassed() { + DCHECK(HasPendingFrame()); + if (!deadline_->HasDeadlinePassed()) + return; + TRACE_EVENT1("viz", "Surface deadline passed", "FrameSinkId", + surface_id().frame_sink_id().ToString()); + ActivatePendingFrameForDeadline(); +} + +Surface::QueueFrameResult Surface::QueueFrame( CompositorFrame frame, uint64_t frame_index, base::ScopedClosureRunner frame_rejected_callback, @@ -194,9 +204,11 @@ frame.device_scale_factor() != surface_info_.device_scale_factor()) { TRACE_EVENT_INSTANT0("viz", "Surface invariants violation", TRACE_EVENT_SCOPE_THREAD); - return false; + return QueueFrameResult::REJECTED; } + QueueFrameResult result = QueueFrameResult::ACCEPTED_ACTIVE; + is_latency_info_taken_ = false; if (active_frame_data_ || pending_frame_data_) @@ -232,9 +244,12 @@ pending_frame_data_ = FrameData(std::move(frame), frame_index, std::move(presented_callback)); - // If the deadline is in the past, then the CompositorFrame will activate - // immediately. deadline_->Set(ResolveFrameDeadline(pending_frame_data_->frame)); + if (deadline_->HasDeadlinePassed()) { + ActivatePendingFrameForDeadline(); + } else { + result = QueueFrameResult::ACCEPTED_PENDING; + } } // Returns resources for the previous pending frame. @@ -244,7 +259,7 @@ // callback so it is not called. (void)frame_rejected_callback.Release(); - return true; + return result; } void Surface::RequestCopyOfOutput( @@ -278,11 +293,10 @@ if (block_activation || !activation_dependencies_.empty()) return; // All blockers have been cleared. The surface can be activated now. - ActivatePendingFrame(base::nullopt); + ActivatePendingFrame(); } -void Surface::ActivatePendingFrameForDeadline( - base::Optional<base::TimeDelta> duration) { +void Surface::ActivatePendingFrameForDeadline() { if (!pending_frame_data_) return; @@ -295,7 +309,7 @@ // surface. seen_first_surface_dependency_ = true; - ActivatePendingFrame(duration); + ActivatePendingFrame(); } Surface::FrameData::FrameData(CompositorFrame&& frame, @@ -311,16 +325,14 @@ Surface::FrameData::~FrameData() = default; -void Surface::ActivatePendingFrame(base::Optional<base::TimeDelta> duration) { +void Surface::ActivatePendingFrame() { DCHECK(pending_frame_data_); FrameData frame_data = std::move(*pending_frame_data_); pending_frame_data_.reset(); - DCHECK(!duration || !deadline_->has_deadline()); - if (!duration) - duration = deadline_->Cancel(); + base::Optional<base::TimeDelta> duration = deadline_->Cancel(); - ActivateFrame(std::move(frame_data), duration); + ActivateFrame(std::move(frame_data), std::move(duration)); } void Surface::UpdateReferencedAllocationGroups( @@ -632,12 +644,6 @@ damage_rect, expected_display_time); } -void Surface::OnDeadline(base::TimeDelta duration) { - TRACE_EVENT1("viz", "Surface::OnDeadline", "FrameSinkId", - surface_id().frame_sink_id().ToString()); - ActivatePendingFrameForDeadline(duration); -} - void Surface::UnrefFrameResourcesAndRunCallbacks( base::Optional<FrameData> frame_data) { if (!frame_data || !surface_client_) @@ -732,7 +738,7 @@ // Deadline inheritance implies that this surface was blocking the embedder, // so there shouldn't be an active frame. DCHECK(!HasActiveFrame()); - ActivatePendingFrameForDeadline(base::nullopt); + ActivatePendingFrameForDeadline(); } void Surface::ResetBlockActivationOnParent() { @@ -745,7 +751,7 @@ return; // All blockers have been cleared. The surface can be activated now. - ActivatePendingFrame(base::nullopt); + ActivatePendingFrame(); } } // namespace viz
diff --git a/components/viz/service/surfaces/surface.h b/components/viz/service/surfaces/surface.h index 38cb28f..5826149 100644 --- a/components/viz/service/surfaces/surface.h +++ b/components/viz/service/surfaces/surface.h
@@ -74,10 +74,11 @@ // deadline passes, then the CompositorFrame will activate despite missing // dependencies. The activated CompositorFrame can specify fallback behavior in // the event of missing dependencies at display time. -class VIZ_SERVICE_EXPORT Surface final : public SurfaceDeadlineClient { +class VIZ_SERVICE_EXPORT Surface final { public: using PresentedCallback = base::OnceCallback<void(const gfx::PresentationFeedback&)>; + enum QueueFrameResult { REJECTED, ACCEPTED_ACTIVE, ACCEPTED_PENDING }; Surface(const SurfaceInfo& surface_info, SurfaceManager* surface_manager, @@ -126,10 +127,10 @@ // |presented_callback| is called when the |frame| has been turned into light // the first time on display, or if the |frame| is replaced by another prior // to display. - bool QueueFrame(CompositorFrame frame, - uint64_t frame_index, - base::ScopedClosureRunner frame_rejected_callback, - PresentedCallback presented_callback); + QueueFrameResult QueueFrame(CompositorFrame frame, + uint64_t frame_index, + base::ScopedClosureRunner frame_rejected_callback, + PresentedCallback presented_callback); // Notifies the Surface that a blocking SurfaceId now has an active // frame. @@ -137,8 +138,7 @@ // Called if a deadline has been hit and this surface is not yet active but // it's marked as respecting deadlines. - void ActivatePendingFrameForDeadline( - base::Optional<base::TimeDelta> duration); + void ActivatePendingFrameForDeadline(); using CopyRequestsMap = std::multimap<RenderPassId, std::unique_ptr<CopyOutputRequest>>; @@ -208,9 +208,6 @@ SurfaceAllocationGroup* allocation_group() const { return allocation_group_; } - // SurfaceDeadlineClient implementation: - void OnDeadline(base::TimeDelta duration) override; - // Called when this surface will be included in the next display frame. void OnWillBeDrawn(); @@ -245,6 +242,8 @@ // surfaces and be able to submit to the primary surface. void SetIsFallbackAndMaybeActivate(); + void ActivateIfDeadlinePassed(); + private: struct FrameData { FrameData(CompositorFrame&& frame, @@ -279,7 +278,7 @@ // in the submitted compositor frame. void RecomputeActiveReferencedSurfaces(); - void ActivatePendingFrame(base::Optional<base::TimeDelta> duration); + void ActivatePendingFrame(); // Called when all of the surface's dependencies have been resolved. void ActivateFrame(FrameData frame_data,
diff --git a/components/viz/service/surfaces/surface_deadline_client.h b/components/viz/service/surfaces/surface_deadline_client.h deleted file mode 100644 index 3e4366f..0000000 --- a/components/viz/service/surfaces/surface_deadline_client.h +++ /dev/null
@@ -1,18 +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 COMPONENTS_VIZ_SERVICE_SURFACES_SURFACE_DEADLINE_CLIENT_H_ -#define COMPONENTS_VIZ_SERVICE_SURFACES_SURFACE_DEADLINE_CLIENT_H_ - -namespace viz { - -class SurfaceDeadlineClient { - public: - // Called when a deadline passes for a set of dependencies. - virtual void OnDeadline(base::TimeDelta duration) = 0; -}; - -} // namespace viz - -#endif // COMPONENTS_VIZ_SERVICE_SURFACES_SURFACE_DEADLINE_CLIENT_H_
diff --git a/components/viz/service/surfaces/surface_dependency_deadline.cc b/components/viz/service/surfaces/surface_dependency_deadline.cc index b2d05f1..ee71400 100644 --- a/components/viz/service/surfaces/surface_dependency_deadline.cc +++ b/components/viz/service/surfaces/surface_dependency_deadline.cc
@@ -12,14 +12,8 @@ namespace viz { SurfaceDependencyDeadline::SurfaceDependencyDeadline( - SurfaceDeadlineClient* client, - BeginFrameSource* begin_frame_source, const base::TickClock* tick_clock) - : client_(client), - begin_frame_source_(begin_frame_source), - tick_clock_(tick_clock) { - DCHECK(client_); - DCHECK(begin_frame_source_); + : tick_clock_(tick_clock) { DCHECK(tick_clock_); } @@ -28,19 +22,20 @@ DCHECK(!deadline_); } -bool SurfaceDependencyDeadline::Set(const FrameDeadline& frame_deadline) { +void SurfaceDependencyDeadline::Set(const FrameDeadline& frame_deadline) { Cancel(); start_time_ = frame_deadline.frame_start_time(); deadline_ = frame_deadline.ToWallTime(); - begin_frame_source_->AddObserver(this); - return has_deadline(); +} + +bool SurfaceDependencyDeadline::HasDeadlinePassed() const { + return tick_clock_->NowTicks() >= deadline_; } base::Optional<base::TimeDelta> SurfaceDependencyDeadline::Cancel() { if (!deadline_) return base::nullopt; - begin_frame_source_->RemoveObserver(this); deadline_.reset(); base::TimeDelta duration = tick_clock_->NowTicks() - start_time_; @@ -53,36 +48,7 @@ bool SurfaceDependencyDeadline::operator==( const SurfaceDependencyDeadline& other) const { - return begin_frame_source_ == other.begin_frame_source_ && - deadline_ == other.deadline_; + return deadline_ == other.deadline_; } -// BeginFrameObserver implementation. -void SurfaceDependencyDeadline::OnBeginFrame(const BeginFrameArgs& args) { - last_begin_frame_args_ = args; - // OnBeginFrame might get called immediately after cancellation if some other - // deadline triggered this deadline to be canceled. - if (!deadline_) - return; - - if (deadline_ > tick_clock_->NowTicks()) - return; - - base::Optional<base::TimeDelta> duration = Cancel(); - DCHECK(duration); - - client_->OnDeadline(*duration); -} - -const BeginFrameArgs& SurfaceDependencyDeadline::LastUsedBeginFrameArgs() - const { - return last_begin_frame_args_; -} - -bool SurfaceDependencyDeadline::WantsAnimateOnlyBeginFrames() const { - return false; -} - -void SurfaceDependencyDeadline::OnBeginFrameSourcePausedChanged(bool paused) {} - } // namespace viz
diff --git a/components/viz/service/surfaces/surface_dependency_deadline.h b/components/viz/service/surfaces/surface_dependency_deadline.h index 4601b6e1..2a383bb 100644 --- a/components/viz/service/surfaces/surface_dependency_deadline.h +++ b/components/viz/service/surfaces/surface_dependency_deadline.h
@@ -5,9 +5,9 @@ #ifndef COMPONENTS_VIZ_SERVICE_SURFACES_SURFACE_DEPENDENCY_DEADLINE_H_ #define COMPONENTS_VIZ_SERVICE_SURFACES_SURFACE_DEPENDENCY_DEADLINE_H_ -#include "components/viz/common/frame_sinks/begin_frame_source.h" +#include "base/optional.h" +#include "base/time/time.h" -#include "components/viz/service/surfaces/surface_deadline_client.h" #include "components/viz/service/viz_service_export.h" namespace base { @@ -18,18 +18,17 @@ class FrameDeadline; -class VIZ_SERVICE_EXPORT SurfaceDependencyDeadline : public BeginFrameObserver { +class VIZ_SERVICE_EXPORT SurfaceDependencyDeadline { public: - SurfaceDependencyDeadline(SurfaceDeadlineClient* client, - BeginFrameSource* begin_frame_source, - const base::TickClock* tick_clock); - ~SurfaceDependencyDeadline() override; + explicit SurfaceDependencyDeadline(const base::TickClock* tick_clock); + ~SurfaceDependencyDeadline(); // Sets up a deadline in wall time where // deadline = frame_start_time + deadline_in_frames * frame_interval. - // It's possible for the deadline to already be in the past. In that case, - // this method will return false. Otherwise, it will return true. - bool Set(const FrameDeadline& frame_deadline); + void Set(const FrameDeadline& frame_deadline); + + // Returns whether the deadline has passed. + bool HasDeadlinePassed() const; // If a deadline had been set, then cancel the deadline and return the // the duration of the event tracked by this object. If there was no @@ -47,21 +46,11 @@ return !(*this == other); } - // BeginFrameObserver implementation. - void OnBeginFrame(const BeginFrameArgs& args) override; - const BeginFrameArgs& LastUsedBeginFrameArgs() const override; - void OnBeginFrameSourcePausedChanged(bool paused) override; - bool WantsAnimateOnlyBeginFrames() const override; - private: - SurfaceDeadlineClient* const client_; - BeginFrameSource* begin_frame_source_ = nullptr; const base::TickClock* tick_clock_; base::TimeTicks start_time_; base::Optional<base::TimeTicks> deadline_; - BeginFrameArgs last_begin_frame_args_; - DISALLOW_COPY_AND_ASSIGN(SurfaceDependencyDeadline); };
diff --git a/components/viz/service/surfaces/surface_dependency_deadline_unittest.cc b/components/viz/service/surfaces/surface_dependency_deadline_unittest.cc deleted file mode 100644 index 567ee25e..0000000 --- a/components/viz/service/surfaces/surface_dependency_deadline_unittest.cc +++ /dev/null
@@ -1,139 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/viz/service/surfaces/surface_dependency_deadline.h" -#include "base/test/simple_test_tick_clock.h" -#include "components/viz/common/quads/frame_deadline.h" -#include "components/viz/service/surfaces/surface_deadline_client.h" -#include "components/viz/test/begin_frame_args_test.h" -#include "components/viz/test/fake_external_begin_frame_source.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace viz { - -class FakeSurfaceDeadlineClient : public SurfaceDeadlineClient { - public: - FakeSurfaceDeadlineClient() = default; - ~FakeSurfaceDeadlineClient() = default; - - // SurfaceDeadlineClient implementation: - void OnDeadline(base::TimeDelta duration) override {} - - private: - DISALLOW_COPY_AND_ASSIGN(FakeSurfaceDeadlineClient); -}; - -class FakeSlowBeginFrameSource : public FakeExternalBeginFrameSource { - public: - FakeSlowBeginFrameSource(double refresh_rate, - bool tick_automatically, - base::SimpleTestTickClock* tick_clock) - : FakeExternalBeginFrameSource(refresh_rate, tick_automatically), - tick_clock_(tick_clock) {} - - ~FakeSlowBeginFrameSource() override {} - - // FakeExternalBeginFrameSource overrides: - void AddObserver(BeginFrameObserver* obs) override { - // Advancing time here simulates a slow AddObserver operation. - tick_clock_->Advance(BeginFrameArgs::DefaultInterval()); - FakeExternalBeginFrameSource::AddObserver(obs); - } - - private: - base::SimpleTestTickClock* const tick_clock_; - DISALLOW_COPY_AND_ASSIGN(FakeSlowBeginFrameSource); -}; - -class SurfaceDependencyDeadlineTest : public testing::Test { - public: - SurfaceDependencyDeadlineTest() = default; - - ~SurfaceDependencyDeadlineTest() override {} - - FakeSlowBeginFrameSource* begin_frame_source() { - return begin_frame_source_.get(); - } - - FrameDeadline MakeDefaultDeadline() { - return FrameDeadline(now_src_->NowTicks(), 4u, - BeginFrameArgs::DefaultInterval(), false); - } - - SurfaceDependencyDeadline* deadline() { return deadline_.get(); } - - SurfaceDependencyDeadline* deadline2() { return deadline2_.get(); } - - void SendLateBeginFrame(uint32_t frames_late) { - // Creep the time forward so that any BeginFrameArgs is not equal to the - // last one otherwise we violate the BeginFrameSource contract. - now_src_->Advance(frames_late * BeginFrameArgs::DefaultInterval()); - BeginFrameArgs args = begin_frame_source_->CreateBeginFrameArgs( - BEGINFRAME_FROM_HERE, now_src_.get()); - begin_frame_source_->TestOnBeginFrame(args); - } - - // testing::Test: - void SetUp() override { - testing::Test::SetUp(); - - now_src_ = std::make_unique<base::SimpleTestTickClock>(); - begin_frame_source_ = - std::make_unique<FakeSlowBeginFrameSource>(0.f, false, now_src_.get()); - - deadline_ = std::make_unique<SurfaceDependencyDeadline>( - &client_, begin_frame_source_.get(), now_src_.get()); - - deadline2_ = std::make_unique<SurfaceDependencyDeadline>( - &client_, begin_frame_source_.get(), now_src_.get()); - } - - void TearDown() override { - deadline2_->Cancel(); - deadline2_.reset(); - deadline_->Cancel(); - deadline_.reset(); - begin_frame_source_.reset(); - now_src_.reset(); - } - - private: - std::unique_ptr<base::SimpleTestTickClock> now_src_; - std::unique_ptr<FakeSlowBeginFrameSource> begin_frame_source_; - FakeSurfaceDeadlineClient client_; - std::unique_ptr<SurfaceDependencyDeadline> deadline_; - std::unique_ptr<SurfaceDependencyDeadline> deadline2_; - - DISALLOW_COPY_AND_ASSIGN(SurfaceDependencyDeadlineTest); -}; - -// This test verifies that if the FrameDeadline is in the past then -// SurfaceDependencyDeadline::Set will return false. -TEST_F(SurfaceDependencyDeadlineTest, DeadlineInPast) { - FrameDeadline frame_deadline = MakeDefaultDeadline(); - SendLateBeginFrame(4u); - EXPECT_FALSE(deadline()->Set(frame_deadline)); - EXPECT_FALSE(deadline()->has_deadline()); -} - -// This test verifies that if Set returns false, then SurfaceDependencyDeadline -// does not have a pending deadline. -TEST_F(SurfaceDependencyDeadlineTest, SetMatchesHasDeadlineIfFalse) { - FrameDeadline frame_deadline = MakeDefaultDeadline(); - SendLateBeginFrame(3u); - EXPECT_FALSE(deadline()->Set(frame_deadline)); - EXPECT_FALSE(deadline()->has_deadline()); -} - -// This test verifies that if Set returns true, then SurfaceDependencyDeadline -// has a pending deadline. -TEST_F(SurfaceDependencyDeadlineTest, SetMatchesHasDeadlineIfTrue) { - FrameDeadline frame_deadline = MakeDefaultDeadline(); - SendLateBeginFrame(2u); - EXPECT_TRUE(deadline()->Set(frame_deadline)); - EXPECT_TRUE(deadline()->has_deadline()); -} - -} // namespace viz
diff --git a/components/viz/service/surfaces/surface_manager.cc b/components/viz/service/surfaces/surface_manager.cc index 0c522bf..25e381c7 100644 --- a/components/viz/service/surfaces/surface_manager.cc +++ b/components/viz/service/surfaces/surface_manager.cc
@@ -104,7 +104,6 @@ Surface* SurfaceManager::CreateSurface( base::WeakPtr<SurfaceClient> surface_client, const SurfaceInfo& surface_info, - BeginFrameSource* begin_frame_source, bool needs_sync_tokens, bool block_activation_on_parent) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -126,8 +125,8 @@ std::unique_ptr<Surface> surface = std::make_unique<Surface>( surface_info, this, allocation_group, surface_client, needs_sync_tokens, block_activation_on_parent); - surface->SetDependencyDeadline(std::make_unique<SurfaceDependencyDeadline>( - surface.get(), begin_frame_source, tick_clock_)); + surface->SetDependencyDeadline( + std::make_unique<SurfaceDependencyDeadline>(tick_clock_)); surface_map_[surface_info.id()] = std::move(surface); // We can get into a situation where multiple CompositorFrames arrive for a // FrameSink before the client can add any references for the frame. When
diff --git a/components/viz/service/surfaces/surface_manager.h b/components/viz/service/surfaces/surface_manager.h index 1635548..8f7d269 100644 --- a/components/viz/service/surfaces/surface_manager.h +++ b/components/viz/service/surfaces/surface_manager.h
@@ -21,6 +21,7 @@ #include "base/optional.h" #include "base/threading/thread_checker.h" #include "base/timer/timer.h" +#include "base/trace_event/trace_event.h" #include "components/viz/common/surfaces/frame_sink_id.h" #include "components/viz/common/surfaces/surface_id.h" #include "components/viz/service/surfaces/surface_observer.h" @@ -37,7 +38,6 @@ namespace viz { -class BeginFrameSource; class Surface; class SurfaceAllocationGroup; class SurfaceClient; @@ -80,7 +80,6 @@ // A temporary reference will be added to the new Surface. Surface* CreateSurface(base::WeakPtr<SurfaceClient> surface_client, const SurfaceInfo& surface_info, - BeginFrameSource* begin_frame_source, bool needs_sync_tokens, bool block_activation_on_parent);
diff --git a/content/OWNERS b/content/OWNERS index 906c460..249bacb 100644 --- a/content/OWNERS +++ b/content/OWNERS
@@ -2,7 +2,6 @@ avi@chromium.org clamy@chromium.org creis@chromium.org -darin@chromium.org dgozman@chromium.org jam@chromium.org jochen@chromium.org
diff --git a/content/app/android/content_main.cc b/content/app/android/content_main.cc index bb61be3..2a9c900 100644 --- a/content/app/android/content_main.cc +++ b/content/app/android/content_main.cc
@@ -57,4 +57,9 @@ g_content_main_delegate.Get().reset(delegate); } +ContentMainDelegate* GetContentMainDelegateForTesting() { + DCHECK(g_content_main_delegate.Get().get()); + return g_content_main_delegate.Get().get(); +} + } // namespace content
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 73f96e2..7a6830ed 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -23,6 +23,7 @@ # internal content ones) should depend on the public one. visibility = [ ":for_content_tests", # See top of //content/BUILD.gn for why. + ":for_internal_webauthn", "//content/app:*", "//content/public/browser:browser_sources", "//content/test/fuzzer:appcache_fuzzer", @@ -608,6 +609,7 @@ "cache_storage/legacy/legacy_cache_storage.h", "cache_storage/legacy/legacy_cache_storage_cache.cc", "cache_storage/legacy/legacy_cache_storage_cache.h", + "cache_storage/scoped_writable_entry.h", "child_process_launcher.cc", "child_process_launcher.h", "child_process_launcher_helper.cc", @@ -1363,6 +1365,8 @@ "permissions/permission_service_impl.h", "picture_in_picture/picture_in_picture_service_impl.cc", "picture_in_picture/picture_in_picture_service_impl.h", + "picture_in_picture/picture_in_picture_session.cc", + "picture_in_picture/picture_in_picture_session.h", "picture_in_picture/picture_in_picture_window_controller_impl.cc", "picture_in_picture/picture_in_picture_window_controller_impl.h", "portal/portal.cc", @@ -2713,3 +2717,13 @@ ] } } + +# Meant for internal components to facilitate WebAuthn. +group("for_internal_webauthn") { + visibility = [ "//components/autofill/content/browser/webauthn" ] + if (!is_component_build) { + public_deps = [ + ":browser", + ] + } +}
diff --git a/content/browser/accessibility/accessibility_ipc_error_browsertest.cc b/content/browser/accessibility/accessibility_ipc_error_browsertest.cc index 2ff4266..2a8894d 100644 --- a/content/browser/accessibility/accessibility_ipc_error_browsertest.cc +++ b/content/browser/accessibility/accessibility_ipc_error_browsertest.cc
@@ -117,16 +117,16 @@ VLOG(1) << tree->ToString(); EXPECT_EQ(ax::mojom::Role::kRootWebArea, root->data().role); - ASSERT_EQ(2, root->GetUnignoredChildCount()); + ASSERT_EQ(2, root->child_count()); - const ui::AXNode* live_region = root->GetUnignoredChildAtIndex(0); - ASSERT_EQ(1, live_region->GetUnignoredChildCount()); + const ui::AXNode* live_region = root->ChildAtIndex(0); + ASSERT_EQ(1, live_region->child_count()); EXPECT_EQ(ax::mojom::Role::kGenericContainer, live_region->data().role); - const ui::AXNode* para = live_region->GetUnignoredChildAtIndex(0); + const ui::AXNode* para = live_region->ChildAtIndex(0); EXPECT_EQ(ax::mojom::Role::kParagraph, para->data().role); - const ui::AXNode* button = root->GetUnignoredChildAtIndex(1); + const ui::AXNode* button = root->ChildAtIndex(1); EXPECT_EQ(ax::mojom::Role::kButton, button->data().role); }
diff --git a/content/browser/accessibility/accessibility_tree_formatter_blink.cc b/content/browser/accessibility/accessibility_tree_formatter_blink.cc index eb98c7c..26dd7e3 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_blink.cc +++ b/content/browser/accessibility/accessibility_tree_formatter_blink.cc
@@ -181,7 +181,6 @@ AddPropertyFilter(property_filters, "flowtoIds*"); AddPropertyFilter(property_filters, "detailsIds*"); AddPropertyFilter(property_filters, "invalidState=*"); - AddPropertyFilter(property_filters, "ignored*"); AddPropertyFilter(property_filters, "invalidState=false", PropertyFilter::DENY); // Don't show false value AddPropertyFilter(property_filters, "roleDescription=*"); @@ -203,9 +202,8 @@ const BrowserAccessibility& node) const { if (node.HasStringAttribute(ax::mojom::StringAttribute::kChildTreeId)) return node.PlatformChildCount(); - // We don't want to use InternalGetChild as we want to include - // ignored nodes in the tree for tests. - return node.node()->child_count(); + else + return node.InternalChildCount(); } BrowserAccessibility* AccessibilityTreeFormatterBlink::GetChild( @@ -213,11 +211,8 @@ uint32_t i) const { if (node.HasStringAttribute(ax::mojom::StringAttribute::kChildTreeId)) return node.PlatformGetChild(i); - // We don't want to use InternalGetChild as we want to include - // ignored nodes in the tree for tests. - ui::AXNode* child_node = node.node()->ChildAtIndex(i); - DCHECK(child_node); - return node.manager()->GetFromAXNode(child_node); + else + return node.InternalGetChild(i); } void AccessibilityTreeFormatterBlink::AddProperties(
diff --git a/content/browser/accessibility/ax_platform_node_win_browsertest.cc b/content/browser/accessibility/ax_platform_node_win_browsertest.cc index bde75fcd..72878a8 100644 --- a/content/browser/accessibility/ax_platform_node_win_browsertest.cc +++ b/content/browser/accessibility/ax_platform_node_win_browsertest.cc
@@ -172,8 +172,14 @@ LoadInitialAccessibilityTreeFromHtmlFilePath( "/accessibility/aria/aria-label.html"); - UIAGetPropertyValueFlowsFromBrowserTestTemplate( - FindNode(ax::mojom::Role::kCheckBox, "aria label"), {}); + base::win::ScopedVariant flows_from_variant; + ComPtr<IRawElementProviderSimple> node_provider = + QueryInterfaceFromNode<IRawElementProviderSimple>( + FindNode(ax::mojom::Role::kCheckBox, "aria label")); + node_provider->GetPropertyValue(UIA_FlowsFromPropertyId, + flows_from_variant.Receive()); + ASSERT_EQ(VT_ARRAY | VT_UNKNOWN, flows_from_variant.type()); + ASSERT_EQ(nullptr, V_ARRAY(flows_from_variant.ptr())); } IN_PROC_BROWSER_TEST_F(AXPlatformNodeWinBrowserTest,
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc index 3fe6a2b..ba4c6e54 100644 --- a/content/browser/accessibility/browser_accessibility.cc +++ b/content/browser/accessibility/browser_accessibility.cc
@@ -101,7 +101,7 @@ if (!instance_active()) return nullptr; - ui::AXNode* parent = node_->GetUnignoredParent(); + ui::AXNode* parent = node_->parent(); if (parent) return manager_->GetFromAXNode(parent); @@ -307,26 +307,25 @@ uint32_t BrowserAccessibility::InternalChildCount() const { if (!node_ || !manager_) return 0; - return node_->GetUnignoredChildCount(); + return static_cast<uint32_t>(node_->child_count()); } BrowserAccessibility* BrowserAccessibility::InternalGetChild( uint32_t child_index) const { - if (!node_ || !manager_) + if (!node_ || !manager_ || child_index >= InternalChildCount()) return nullptr; - auto* child_node = node_->GetUnignoredChildAtIndex(child_index); - if (child_node) - return manager_->GetFromAXNode(child_node); - return nullptr; + auto* child_node = node_->ChildAtIndex(child_index); + DCHECK(child_node); + return manager_->GetFromAXNode(child_node); } BrowserAccessibility* BrowserAccessibility::InternalGetParent() const { if (!node_ || !manager_) return nullptr; - auto* child_node = node_->GetUnignoredParent(); - if (child_node) - return manager_->GetFromAXNode(child_node); + ui::AXNode* parent = node_->parent(); + if (parent) + return manager_->GetFromAXNode(parent); return nullptr; } @@ -1390,7 +1389,7 @@ } int BrowserAccessibility::GetIndexInParent() const { - return node_ ? node_->GetUnignoredIndexInParent() : -1; + return node_ ? node_->index_in_parent() : -1; } gfx::AcceleratedWidget
diff --git a/content/browser/accessibility/browser_accessibility.h b/content/browser/accessibility/browser_accessibility.h index fbbb490a..574447b 100644 --- a/content/browser/accessibility/browser_accessibility.h +++ b/content/browser/accessibility/browser_accessibility.h
@@ -244,9 +244,9 @@ bool instance_active() const { return node_ && manager_; } ui::AXNode* node() const { return node_; } - // These access the internal unignored accessibility tree, which doesn't - // necessarily reflect the accessibility tree that should be exposed on each - // platform. Use PlatformChildCount and PlatformGetChild to implement platform + // These access the internal accessibility tree, which doesn't necessarily + // reflect the accessibility tree that should be exposed on each platform. + // Use PlatformChildCount and PlatformGetChild to implement platform // accessibility APIs. uint32_t InternalChildCount() const; BrowserAccessibility* InternalGetChild(uint32_t child_index) const;
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc index 9fa9a025..8c257b6 100644 --- a/content/browser/accessibility/browser_accessibility_manager.cc +++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -1200,6 +1200,7 @@ BrowserAccessibility* wrapper = factory_->Create(); id_wrapper_map_[node->id()] = wrapper; wrapper->Init(this, node); + wrapper->OnDataChanged(); } void BrowserAccessibilityManager::OnNodeReparented(ui::AXTree* tree, @@ -1211,6 +1212,7 @@ id_wrapper_map_[node->id()] = wrapper; } wrapper->Init(this, node); + wrapper->OnDataChanged(); } void BrowserAccessibilityManager::OnNodeChanged(ui::AXTree* tree, @@ -1244,25 +1246,6 @@ // we're properly connected. if (ax_tree_id_changed || root_changed) connected_to_parent_tree_node_ = false; - - // Calls OnDataChanged on newly created or reparented nodes. - for (const auto change : changes) { - ui::AXNode* node = change.node; - BrowserAccessibility* wrapper = GetFromAXNode(node); - if (wrapper) { - switch (change.type) { - case NODE_CREATED: - case NODE_REPARENTED: - wrapper->OnDataChanged(); - break; - // Unhandled. - case NODE_CHANGED: - case SUBTREE_CREATED: - case SUBTREE_REPARENTED: - break; - } - } - } } ui::AXNode* BrowserAccessibilityManager::GetNodeFromTree(
diff --git a/content/browser/accessibility/browser_accessibility_unittest.cc b/content/browser/accessibility/browser_accessibility_unittest.cc index f01e138..873b961a 100644 --- a/content/browser/accessibility/browser_accessibility_unittest.cc +++ b/content/browser/accessibility/browser_accessibility_unittest.cc
@@ -100,11 +100,11 @@ TEST_F(BrowserAccessibilityTest, TestGetDescendants) { // Set up ax tree with the following structure: // - // root_____________________ - // | | | - // para1____ text3 para2____ (hidden) - // | | | | - // text1 text2 text4 text5 (visible) + // root____________ + // | | + // para1___ text3 + // | | + // text1 text2 ui::AXNodeData text1; text1.id = 111; text1.role = ax::mojom::Role::kStaticText; @@ -120,41 +120,21 @@ text3.role = ax::mojom::Role::kStaticText; text3.SetName("Three four five."); - ui::AXNodeData text4; - text4.id = 114; - text4.role = ax::mojom::Role::kStaticText; - text4.SetName("four five six."); - text4.AddState(ax::mojom::State::kIgnored); - - ui::AXNodeData text5; - text5.id = 115; - text5.role = ax::mojom::Role::kStaticText; - text5.SetName("five six seven."); - ui::AXNodeData para1; para1.id = 11; para1.role = ax::mojom::Role::kParagraph; para1.child_ids.push_back(text1.id); para1.child_ids.push_back(text2.id); - ui::AXNodeData para2; - para2.id = 12; - para2.role = ax::mojom::Role::kParagraph; - para2.child_ids.push_back(text4.id); - para2.child_ids.push_back(text5.id); - para2.AddState(ax::mojom::State::kIgnored); - ui::AXNodeData root; root.id = 1; root.role = ax::mojom::Role::kRootWebArea; root.child_ids.push_back(para1.id); root.child_ids.push_back(text3.id); - root.child_ids.push_back(para2.id); std::unique_ptr<BrowserAccessibilityManager> manager( BrowserAccessibilityManager::Create( - MakeAXTreeUpdate(root, para1, text1, text2, text3, para2, text4, - text5), + MakeAXTreeUpdate(root, para1, text1, text2, text3), test_browser_accessibility_delegate_.get(), new BrowserAccessibilityFactory())); @@ -163,9 +143,6 @@ BrowserAccessibility* text1_obj = manager->GetFromID(111); BrowserAccessibility* text2_obj = manager->GetFromID(112); BrowserAccessibility* text3_obj = manager->GetFromID(113); - BrowserAccessibility* para2_obj = manager->GetFromID(12); - BrowserAccessibility* text4_obj = manager->GetFromID(114); - BrowserAccessibility* text5_obj = root_obj->PlatformGetChild(2); // Leaf nodes should have no children. std::vector<gfx::NativeViewAccessible> descendants = @@ -179,16 +156,6 @@ descendants = text3_obj->GetDescendants(); EXPECT_NATIVE_VIEW_ACCESSIBLE_VECTOR_EQ(descendants, expected_descendants); - descendants = text4_obj->GetDescendants(); - EXPECT_NATIVE_VIEW_ACCESSIBLE_VECTOR_EQ(descendants, expected_descendants); - - descendants = text5_obj->GetDescendants(); - EXPECT_NATIVE_VIEW_ACCESSIBLE_VECTOR_EQ(descendants, expected_descendants); - - descendants = para2_obj->GetDescendants(); - expected_descendants = {text5_obj->GetNativeViewAccessible()}; - EXPECT_NATIVE_VIEW_ACCESSIBLE_VECTOR_EQ(descendants, expected_descendants); - // Verify that para1 has two children (text1 and tex2). descendants = para_obj->GetDescendants(); expected_descendants = {text1_obj->GetNativeViewAccessible(), @@ -197,13 +164,11 @@ // Calling GetChildNodeIds on the root should encompass the entire // right and left subtrees (para1, text1, text2, and text3). - // para2 and its subtree should be ignored, except for text5 descendants = root_obj->GetDescendants(); expected_descendants = {para_obj->GetNativeViewAccessible(), text1_obj->GetNativeViewAccessible(), text2_obj->GetNativeViewAccessible(), - text3_obj->GetNativeViewAccessible(), - text5_obj->GetNativeViewAccessible()}; + text3_obj->GetNativeViewAccessible()}; EXPECT_NATIVE_VIEW_ACCESSIBLE_VECTOR_EQ(descendants, expected_descendants); manager.reset();
diff --git a/content/browser/accessibility/cross_platform_accessibility_browsertest.cc b/content/browser/accessibility/cross_platform_accessibility_browsertest.cc index bcabb28..a34d8ab9 100644 --- a/content/browser/accessibility/cross_platform_accessibility_browsertest.cc +++ b/content/browser/accessibility/cross_platform_accessibility_browsertest.cc
@@ -188,8 +188,8 @@ EXPECT_EQ(ax::mojom::Role::kRootWebArea, root->data().role); // Check properties of the BODY element. - ASSERT_EQ(1, root->GetUnignoredChildCount()); - const ui::AXNode* body = root->GetUnignoredChildAtIndex(0); + ASSERT_EQ(1, root->child_count()); + const ui::AXNode* body = root->ChildAtIndex(0); EXPECT_EQ(ax::mojom::Role::kGenericContainer, body->data().role); EXPECT_STREQ("body", GetAttr(body, ax::mojom::StringAttribute::kHtmlTag).c_str()); @@ -197,9 +197,9 @@ GetAttr(body, ax::mojom::StringAttribute::kDisplay).c_str()); // Check properties of the two children of the BODY element. - ASSERT_EQ(2, body->GetUnignoredChildCount()); + ASSERT_EQ(2, body->child_count()); - const ui::AXNode* button = body->GetUnignoredChildAtIndex(0); + const ui::AXNode* button = body->ChildAtIndex(0); EXPECT_EQ(ax::mojom::Role::kButton, button->data().role); EXPECT_STREQ("input", GetAttr(button, ax::mojom::StringAttribute::kHtmlTag).c_str()); @@ -213,7 +213,7 @@ EXPECT_STREQ("value", button->data().html_attributes[1].first.c_str()); EXPECT_STREQ("push", button->data().html_attributes[1].second.c_str()); - const ui::AXNode* checkbox = body->GetUnignoredChildAtIndex(1); + const ui::AXNode* checkbox = body->ChildAtIndex(1); EXPECT_EQ(ax::mojom::Role::kCheckBox, checkbox->data().role); EXPECT_STREQ("input", GetAttr(checkbox, ax::mojom::StringAttribute::kHtmlTag).c_str()); @@ -238,10 +238,10 @@ const ui::AXTree& tree = GetAXTree(); const ui::AXNode* root = tree.root(); - ASSERT_EQ(1, root->GetUnignoredChildCount()); - const ui::AXNode* body = root->GetUnignoredChildAtIndex(0); - ASSERT_EQ(1, body->GetUnignoredChildCount()); - const ui::AXNode* text = body->GetUnignoredChildAtIndex(0); + ASSERT_EQ(1, root->child_count()); + const ui::AXNode* body = root->ChildAtIndex(0); + ASSERT_EQ(1, body->child_count()); + const ui::AXNode* text = body->ChildAtIndex(0); EXPECT_EQ(ax::mojom::Role::kTextField, text->data().role); EXPECT_STREQ("input", GetAttr(text, ax::mojom::StringAttribute::kHtmlTag).c_str()); @@ -269,10 +269,10 @@ const ui::AXTree& tree = GetAXTree(); const ui::AXNode* root = tree.root(); - ASSERT_EQ(1, root->GetUnignoredChildCount()); - const ui::AXNode* body = root->GetUnignoredChildAtIndex(0); - ASSERT_EQ(1, body->GetUnignoredChildCount()); - const ui::AXNode* text = body->GetUnignoredChildAtIndex(0); + ASSERT_EQ(1, root->child_count()); + const ui::AXNode* body = root->ChildAtIndex(0); + ASSERT_EQ(1, body->child_count()); + const ui::AXNode* text = body->ChildAtIndex(0); EXPECT_EQ(ax::mojom::Role::kTextField, text->data().role); EXPECT_STREQ("input", GetAttr(text, ax::mojom::StringAttribute::kHtmlTag).c_str()); @@ -323,33 +323,33 @@ const ui::AXTree& tree = GetAXTree(); const ui::AXNode* root = tree.root(); - ASSERT_EQ(1, root->GetUnignoredChildCount()); - const ui::AXNode* body = root->GetUnignoredChildAtIndex(0); - ASSERT_EQ(3, body->GetUnignoredChildCount()); + ASSERT_EQ(1, root->child_count()); + const ui::AXNode* body = root->ChildAtIndex(0); + ASSERT_EQ(3, body->child_count()); - const ui::AXNode* button1 = body->GetUnignoredChildAtIndex(0); + const ui::AXNode* button1 = body->ChildAtIndex(0); EXPECT_EQ(ax::mojom::Role::kButton, button1->data().role); EXPECT_STREQ("Button 1", GetAttr(button1, ax::mojom::StringAttribute::kName).c_str()); - const ui::AXNode* iframe = body->GetUnignoredChildAtIndex(1); + const ui::AXNode* iframe = body->ChildAtIndex(1); EXPECT_STREQ("iframe", GetAttr(iframe, ax::mojom::StringAttribute::kHtmlTag).c_str()); - ASSERT_EQ(1, iframe->GetUnignoredChildCount()); + ASSERT_EQ(1, iframe->child_count()); - const ui::AXNode* sub_document = iframe->GetUnignoredChildAtIndex(0); + const ui::AXNode* sub_document = iframe->ChildAtIndex(0); EXPECT_EQ(ax::mojom::Role::kWebArea, sub_document->data().role); - ASSERT_EQ(1, sub_document->GetUnignoredChildCount()); + ASSERT_EQ(1, sub_document->child_count()); - const ui::AXNode* sub_body = sub_document->GetUnignoredChildAtIndex(0); - ASSERT_EQ(1, sub_body->GetUnignoredChildCount()); + const ui::AXNode* sub_body = sub_document->ChildAtIndex(0); + ASSERT_EQ(1, sub_body->child_count()); - const ui::AXNode* button2 = sub_body->GetUnignoredChildAtIndex(0); + const ui::AXNode* button2 = sub_body->ChildAtIndex(0); EXPECT_EQ(ax::mojom::Role::kButton, button2->data().role); EXPECT_STREQ("Button 2", GetAttr(button2, ax::mojom::StringAttribute::kName).c_str()); - const ui::AXNode* button3 = body->GetUnignoredChildAtIndex(2); + const ui::AXNode* button3 = body->ChildAtIndex(2); EXPECT_EQ(ax::mojom::Role::kButton, button3->data().role); EXPECT_STREQ("Button 3", GetAttr(button3, ax::mojom::StringAttribute::kName).c_str()); @@ -396,24 +396,18 @@ const ui::AXTree& tree = GetAXTree(); const ui::AXNode* root = tree.root(); - const ui::AXNode* table = root->GetUnignoredChildAtIndex(0); + const ui::AXNode* table = root->ChildAtIndex(0); EXPECT_EQ(ax::mojom::Role::kTable, table->data().role); - ASSERT_GE(table->GetUnignoredChildCount(), 2); - EXPECT_EQ(ax::mojom::Role::kRow, - table->GetUnignoredChildAtIndex(0)->data().role); - EXPECT_EQ(ax::mojom::Role::kRow, - table->GetUnignoredChildAtIndex(1)->data().role); + ASSERT_GE(table->child_count(), 2); + EXPECT_EQ(ax::mojom::Role::kRow, table->ChildAtIndex(0)->data().role); + EXPECT_EQ(ax::mojom::Role::kRow, table->ChildAtIndex(1)->data().role); EXPECT_EQ(3, GetIntAttr(table, ax::mojom::IntAttribute::kTableColumnCount)); EXPECT_EQ(2, GetIntAttr(table, ax::mojom::IntAttribute::kTableRowCount)); - const ui::AXNode* cell1 = - table->GetUnignoredChildAtIndex(0)->GetUnignoredChildAtIndex(0); - const ui::AXNode* cell2 = - table->GetUnignoredChildAtIndex(0)->GetUnignoredChildAtIndex(1); - const ui::AXNode* cell3 = - table->GetUnignoredChildAtIndex(1)->GetUnignoredChildAtIndex(0); - const ui::AXNode* cell4 = - table->GetUnignoredChildAtIndex(1)->GetUnignoredChildAtIndex(1); + const ui::AXNode* cell1 = table->ChildAtIndex(0)->ChildAtIndex(0); + const ui::AXNode* cell2 = table->ChildAtIndex(0)->ChildAtIndex(1); + const ui::AXNode* cell3 = table->ChildAtIndex(1)->ChildAtIndex(0); + const ui::AXNode* cell4 = table->ChildAtIndex(1)->ChildAtIndex(1); EXPECT_EQ(0, GetIntAttr(cell1, ax::mojom::IntAttribute::kTableCellColumnIndex)); @@ -446,8 +440,8 @@ NavigateToURL(shell(), url); const ui::AXTree& tree = GetAXTree(); const ui::AXNode* root = tree.root(); - ASSERT_EQ(1, root->GetUnignoredChildCount()); - const ui::AXNode* textbox = root->GetUnignoredChildAtIndex(0); + ASSERT_EQ(1, root->child_count()); + const ui::AXNode* textbox = root->ChildAtIndex(0); EXPECT_TRUE(textbox->data().HasAction(ax::mojom::Action::kSetValue)); } @@ -468,17 +462,17 @@ const ui::AXTree& tree = GetAXTree(); const ui::AXNode* root = tree.root(); - const ui::AXNode* table = root->GetUnignoredChildAtIndex(0); + const ui::AXNode* table = root->ChildAtIndex(0); EXPECT_EQ(ax::mojom::Role::kTable, table->data().role); - EXPECT_EQ(1, table->GetUnignoredChildCount()); - const ui::AXNode* row = table->GetUnignoredChildAtIndex(0); - EXPECT_EQ(5, row->GetUnignoredChildCount()); + EXPECT_EQ(1, table->child_count()); + const ui::AXNode* row = table->ChildAtIndex(0); + EXPECT_EQ(5, row->child_count()); - const ui::AXNode* header1 = row->GetUnignoredChildAtIndex(0); - const ui::AXNode* header2 = row->GetUnignoredChildAtIndex(1); - const ui::AXNode* header3 = row->GetUnignoredChildAtIndex(2); - const ui::AXNode* header4 = row->GetUnignoredChildAtIndex(3); - const ui::AXNode* header5 = row->GetUnignoredChildAtIndex(4); + const ui::AXNode* header1 = row->ChildAtIndex(0); + const ui::AXNode* header2 = row->ChildAtIndex(1); + const ui::AXNode* header3 = row->ChildAtIndex(2); + const ui::AXNode* header4 = row->ChildAtIndex(3); + const ui::AXNode* header5 = row->ChildAtIndex(4); EXPECT_EQ(static_cast<int>(ax::mojom::SortDirection::kAscending), GetIntAttr(header1, ax::mojom::IntAttribute::kSortDirection));
diff --git a/content/browser/accessibility/snapshot_ax_tree_browsertest.cc b/content/browser/accessibility/snapshot_ax_tree_browsertest.cc index f32a8cf..912294f 100644 --- a/content/browser/accessibility/snapshot_ax_tree_browsertest.cc +++ b/content/browser/accessibility/snapshot_ax_tree_browsertest.cc
@@ -52,7 +52,7 @@ node->data().GetStringAttribute(ax::mojom::StringAttribute::kName) + "'"; *dst += "\n"; - for (int i = 0; i < node->GetUnignoredChildCount(); ++i) + for (int i = 0; i < node->child_count(); ++i) DumpRolesAndNamesAsText(node->children()[i], indent + 1, dst); } @@ -87,9 +87,9 @@ ui::AXNode* root = tree.root(); ASSERT_NE(nullptr, root); ASSERT_EQ(ax::mojom::Role::kRootWebArea, root->data().role); - ui::AXNode* group = root->GetUnignoredChildAtIndex(0); + ui::AXNode* group = root->ChildAtIndex(0); ASSERT_EQ(ax::mojom::Role::kGenericContainer, group->data().role); - ui::AXNode* button = group->GetUnignoredChildAtIndex(0); + ui::AXNode* button = group->ChildAtIndex(0); ASSERT_EQ(ax::mojom::Role::kButton, button->data().role); }
diff --git a/content/browser/appcache/appcache_backend_impl.cc b/content/browser/appcache/appcache_backend_impl.cc index c72648f..18232eae 100644 --- a/content/browser/appcache/appcache_backend_impl.cc +++ b/content/browser/appcache/appcache_backend_impl.cc
@@ -27,51 +27,16 @@ } AppCacheBackendImpl::~AppCacheBackendImpl() { - hosts_.clear(); service_->UnregisterBackend(this); } void AppCacheBackendImpl::RegisterHost( blink::mojom::AppCacheHostRequest host_request, blink::mojom::AppCacheFrontendPtr frontend, - int32_t id, - int32_t render_frame_id) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (GetHost(id)) { - mojo::ReportBadMessage("ACDH_REGISTER"); - return; - } - - // The AppCacheHost could have been precreated in which case we want to - // register it with the backend here. - std::unique_ptr<AppCacheHost> host = - AppCacheNavigationHandleCore::GetPrecreatedHost(id); - if (host) { - // Switch the frontend proxy so that the host can make IPC calls from - // here on. - host->set_frontend(std::move(frontend), render_frame_id); - } else { - if (id < 0) { - // Negative ids correspond to precreated hosts. We should be able to - // retrieve one, but currently we have a race between this IPC and - // browser removing the corresponding frame and precreated AppCacheHost. - // Instead of crashing the renderer or returning wrong host, we do not - // bind any host and let renderer do nothing until it is destroyed by - // the request from browser. - return; - } - host = std::make_unique<AppCacheHost>(id, process_id(), render_frame_id, - std::move(frontend), service_); - } - - host->BindRequest(std::move(host_request)); - hosts_.emplace(std::piecewise_construct, std::forward_as_tuple(id), - std::forward_as_tuple(std::move(host))); -} - -void AppCacheBackendImpl::UnregisterHost(int32_t id) { - if (!hosts_.erase(id)) - mojo::ReportBadMessage("ACDH_UNREGISTER"); + int32_t id) { + service_->RegisterHostInternal(std::move(host_request), std::move(frontend), + id, MSG_ROUTING_NONE, process_id_, + mojo::GetBadMessageCallback()); } } // namespace content
diff --git a/content/browser/appcache/appcache_backend_impl.h b/content/browser/appcache/appcache_backend_impl.h index a4ff77d..2a83108 100644 --- a/content/browser/appcache/appcache_backend_impl.h +++ b/content/browser/appcache/appcache_backend_impl.h
@@ -27,25 +27,13 @@ // blink::mojom::AppCacheBackend void RegisterHost(blink::mojom::AppCacheHostRequest host_request, blink::mojom::AppCacheFrontendPtr frontend, - int32_t host_id, - int32_t render_frame_id) override; - void UnregisterHost(int32_t host_id); - - // Returns a pointer to a registered host. The backend retains ownership. - AppCacheHost* GetHost(int host_id) { - auto it = hosts_.find(host_id); - return (it != hosts_.end()) ? (it->second.get()) : nullptr; - } - - using HostMap = std::unordered_map<int, std::unique_ptr<AppCacheHost>>; - const HostMap& hosts() { return hosts_; } + int32_t host_id) override; private: // Raw pointer is safe because instances of this class are owned by // |service_|. AppCacheServiceImpl* service_; int process_id_; - HostMap hosts_; DISALLOW_COPY_AND_ASSIGN(AppCacheBackendImpl); };
diff --git a/content/browser/appcache/appcache_fuzzer.cc b/content/browser/appcache/appcache_fuzzer.cc index 6727d2be..86d9a14 100644 --- a/content/browser/appcache/appcache_fuzzer.cc +++ b/content/browser/appcache/appcache_fuzzer.cc
@@ -160,7 +160,7 @@ blink::mojom::AppCacheFrontendPtr frontend; mojo::MakeRequest(&frontend); host->RegisterHost(mojo::MakeRequest(®istered_hosts[host_id]), - std::move(frontend), host_id, MSG_ROUTING_NONE); + std::move(frontend), host_id); break; } case fuzzing::proto::Command::kUnregisterHost: {
diff --git a/content/browser/appcache/appcache_host.cc b/content/browser/appcache/appcache_host.cc index d6ed8eb6..12557b1c 100644 --- a/content/browser/appcache/appcache_host.cc +++ b/content/browser/appcache/appcache_host.cc
@@ -126,7 +126,7 @@ } void AppCacheHost::Unregister() { - service_->GetBackend(process_id_)->UnregisterHost(host_id_); + service_->EraseHost(process_id_, host_id_); } void AppCacheHost::SelectCache(const GURL& document_url, @@ -333,14 +333,12 @@ } const AppCacheHost* AppCacheHost::GetSpawningHost() const { - AppCacheBackendImpl* backend = service_->GetBackend(process_id_); - return backend ? backend->GetHost(spawning_host_id_) : nullptr; + return service_->GetHost(process_id_, spawning_host_id_); } AppCacheHost* AppCacheHost::GetParentAppCacheHost() const { DCHECK(is_for_dedicated_worker()); - AppCacheBackendImpl* backend = service_->GetBackend(parent_process_id_); - return backend ? backend->GetHost(parent_host_id_) : nullptr; + return service_->GetHost(parent_process_id_, parent_host_id_); } void AppCacheHost::GetResourceList(GetResourceListCallback callback) {
diff --git a/content/browser/appcache/appcache_interceptor.cc b/content/browser/appcache/appcache_interceptor.cc index 3e4c514d..d610cb0 100644 --- a/content/browser/appcache/appcache_interceptor.cc +++ b/content/browser/appcache/appcache_interceptor.cc
@@ -46,13 +46,9 @@ if (!service || (host_id == blink::mojom::kAppCacheNoHostId)) return; - AppCacheBackendImpl* backend = service->GetBackend(process_id); - if (!backend) - return; - // TODO(michaeln): An invalid host id is indicative of bad data // from a child process. How should we handle that here? - AppCacheHost* host = backend->GetHost(host_id); + AppCacheHost* host = service->GetHost(process_id, host_id); if (!host) return;
diff --git a/content/browser/appcache/appcache_request_handler_unittest.cc b/content/browser/appcache/appcache_request_handler_unittest.cc index 0cd4bfaf..4971d8e 100644 --- a/content/browser/appcache/appcache_request_handler_unittest.cc +++ b/content/browser/appcache/appcache_request_handler_unittest.cc
@@ -222,15 +222,14 @@ mock_service_->set_request_context(empty_context_.get()); mock_policy_.reset(new MockAppCachePolicy); mock_service_->set_appcache_policy(mock_policy_.get()); - backend_impl_ = std::make_unique<AppCacheBackendImpl>(mock_service_.get(), - kMockProcessId); const int kHostId = 1; const int kRenderFrameId = 2; - blink::mojom::AppCacheFrontendPtr frontend; + blink::mojom::AppCacheFrontendPtrInfo frontend; mojo::MakeRequest(&frontend); - backend_impl_->RegisterHost(mojo::MakeRequest(&host_ptr_), - std::move(frontend), kHostId, kRenderFrameId); - host_ = backend_impl_->GetHost(kHostId); + mock_service_->RegisterHostForFrame( + mojo::MakeRequest(&host_ptr_), std::move(frontend), kHostId, + kRenderFrameId, kMockProcessId, GetBadMessageCallback()); + host_ = mock_service_->GetHost(kMockProcessId, kHostId); job_factory_.reset(new MockURLRequestJobFactory()); empty_context_->set_job_factory(job_factory_.get()); } @@ -244,7 +243,6 @@ handler_.reset(); request_ = nullptr; url_request_.reset(); - backend_impl_.reset(); mock_service_.reset(); mock_policy_.reset(); job_factory_.reset(); @@ -723,7 +721,7 @@ ResourceType::kSubResource)); EXPECT_TRUE(handler_.get()); - backend_impl_->UnregisterHost(1); + mock_service_->EraseHost(kMockProcessId, 1); host_ = nullptr; EXPECT_FALSE(handler_->MaybeLoadResource(nullptr)); @@ -748,7 +746,7 @@ EXPECT_TRUE(job()); EXPECT_TRUE(job()->IsWaiting()); - backend_impl_->UnregisterHost(1); + mock_service_->EraseHost(kMockProcessId, 1); host_ = nullptr; if (request_handler_type_ == URLREQUEST) { @@ -776,7 +774,6 @@ SetAppCacheJob(handler_->MaybeLoadResource(nullptr)); EXPECT_TRUE(job()); - backend_impl_.reset(); mock_service_.reset(); mock_policy_.reset(); host_ = nullptr; @@ -893,6 +890,13 @@ return cache; } + mojo::ReportBadMessageCallback GetBadMessageCallback() { + return base::BindOnce(&AppCacheRequestHandlerTest::OnBadMessage, + base::Unretained(this)); + } + + void OnBadMessage(const std::string& reason) { NOTREACHED(); } + MockAppCacheStorage* mock_storage() { return reinterpret_cast<MockAppCacheStorage*>(mock_service_->storage()); } @@ -929,7 +933,6 @@ std::unique_ptr<base::WaitableEvent> test_finished_event_; base::stack<base::OnceClosure> task_stack_; std::unique_ptr<MockAppCacheService> mock_service_; - std::unique_ptr<AppCacheBackendImpl> backend_impl_; std::unique_ptr<MockAppCachePolicy> mock_policy_; AppCacheHost* host_; blink::mojom::AppCacheHostPtr host_ptr_;
diff --git a/content/browser/appcache/appcache_service_impl.cc b/content/browser/appcache/appcache_service_impl.cc index 515f641..442ad56 100644 --- a/content/browser/appcache/appcache_service_impl.cc +++ b/content/browser/appcache/appcache_service_impl.cc
@@ -21,6 +21,8 @@ #include "content/browser/appcache/appcache_backend_impl.h" #include "content/browser/appcache/appcache_entry.h" #include "content/browser/appcache/appcache_histograms.h" +#include "content/browser/appcache/appcache_host.h" +#include "content/browser/appcache/appcache_navigation_handle_core.h" #include "content/browser/appcache/appcache_policy.h" #include "content/browser/appcache/appcache_quota_client.h" #include "content/browser/appcache/appcache_response.h" @@ -405,6 +407,7 @@ AppCacheServiceImpl::~AppCacheServiceImpl() { DCHECK(backends_.empty()); + hosts_.clear(); for (auto& observer : observers_) observer.OnServiceDestructionImminent(this); for (auto& helper : pending_helpers_) @@ -515,4 +518,68 @@ backends_.erase(backend_impl->process_id()); } +AppCacheHost* AppCacheServiceImpl::GetHost(int process_id, int host_id) { + auto it = hosts_.find({process_id, host_id}); + return (it != hosts_.end()) ? (it->second.get()) : nullptr; +} + +bool AppCacheServiceImpl::EraseHost(int process_id, int host_id) { + return (hosts_.erase({process_id, host_id}) != 0); +} + +void AppCacheServiceImpl::RegisterHostForFrame( + blink::mojom::AppCacheHostRequest host_request, + blink::mojom::AppCacheFrontendPtrInfo frontend, + int32_t host_id, + int32_t render_frame_id, + int process_id, + mojo::ReportBadMessageCallback bad_message_callback) { + blink::mojom::AppCacheFrontendPtr appcache_frontend_ptr(std::move(frontend)); + RegisterHostInternal( + std::move(host_request), std::move(appcache_frontend_ptr), host_id, + render_frame_id, process_id, std::move(bad_message_callback)); +} + +void AppCacheServiceImpl::RegisterHostInternal( + blink::mojom::AppCacheHostRequest host_request, + blink::mojom::AppCacheFrontendPtr frontend, + int32_t id, + int32_t render_frame_id, + int process_id, + mojo::ReportBadMessageCallback bad_message_callback) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + if (GetHost(process_id, id)) { + std::move(bad_message_callback).Run("ACSI_REGISTER"); + return; + } + + // The AppCacheHost could have been precreated in which case we want to + // register it with the backend here. + std::unique_ptr<AppCacheHost> host = + AppCacheNavigationHandleCore::GetPrecreatedHost(id); + if (host) { + // Switch the frontend proxy so that the host can make IPC calls from + // here on. + host->set_frontend(std::move(frontend), render_frame_id); + } else { + if (id < 0) { + // Negative ids correspond to precreated hosts. We should be able to + // retrieve one, but currently we have a race between this IPC and + // browser removing the corresponding frame and precreated AppCacheHost. + // Instead of crashing the renderer or returning wrong host, we do not + // bind any host and let renderer do nothing until it is destroyed by + // the request from browser. + return; + } + host = std::make_unique<AppCacheHost>(id, process_id, render_frame_id, + std::move(frontend), this); + } + + host->BindRequest(std::move(host_request)); + + std::pair<int, int> key = std::make_pair(process_id, id); + hosts_.emplace(std::piecewise_construct, std::forward_as_tuple(key), + std::forward_as_tuple(std::move(host))); +} + } // namespace content
diff --git a/content/browser/appcache/appcache_service_impl.h b/content/browser/appcache/appcache_service_impl.h index 4b3e4ec4..0f3a8fc 100644 --- a/content/browser/appcache/appcache_service_impl.h +++ b/content/browser/appcache/appcache_service_impl.h
@@ -24,6 +24,7 @@ #include "net/base/completion_once_callback.h" #include "net/base/net_errors.h" #include "storage/browser/quota/quota_manager_proxy.h" +#include "third_party/blink/public/mojom/appcache/appcache.mojom.h" namespace base { class FilePath; @@ -40,6 +41,7 @@ namespace content { FORWARD_DECLARE_TEST(AppCacheServiceImplTest, ScheduleReinitialize); class AppCacheBackendImpl; +class AppCacheHost; class AppCacheQuotaClient; class AppCachePolicy; class AppCacheServiceImplTest; @@ -179,6 +181,17 @@ return url_loader_factory_getter_.get(); } + // Returns a pointer to a registered host. It retains ownership. + AppCacheHost* GetHost(int process_id, int host_id); + bool EraseHost(int process_id, int host_id); + void RegisterHostForFrame( + blink::mojom::AppCacheHostRequest host_request, + blink::mojom::AppCacheFrontendPtrInfo frontend, + int32_t host_id, + int32_t render_frame_id, + int process_id, + mojo::ReportBadMessageCallback bad_message_callback); + protected: friend class content::AppCacheServiceImplTest; friend class content::AppCacheStorageImplTest; @@ -218,6 +231,21 @@ scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter_; private: + // TODO: Once we remove 'blink::mojom::AppCacheBackend', remove this together. + friend class content::AppCacheBackendImpl; + + void RegisterHostInternal( + blink::mojom::AppCacheHostRequest host_request, + blink::mojom::AppCacheFrontendPtr frontend, + int32_t id, + int32_t render_frame_id, + int process_id, + mojo::ReportBadMessageCallback bad_message_callback); + // The (process id, host id) pair that identifies one AppCacheHost. + using AppCacheHostProcessMap = + std::map<std::pair<int, int>, std::unique_ptr<AppCacheHost>>; + AppCacheHostProcessMap hosts_; + base::WeakPtrFactory<AppCacheServiceImpl> weak_factory_; DISALLOW_COPY_AND_ASSIGN(AppCacheServiceImpl);
diff --git a/content/browser/appcache/appcache_storage_impl_unittest.cc b/content/browser/appcache/appcache_storage_impl_unittest.cc index 585f1ba..08c86865 100644 --- a/content/browser/appcache/appcache_storage_impl_unittest.cc +++ b/content/browser/appcache/appcache_storage_impl_unittest.cc
@@ -65,6 +65,7 @@ namespace { +constexpr int kMockProcessId = 1; constexpr int kMockQuota = 5000; // The Reinitialize test needs some http accessible resources to run, @@ -1694,10 +1695,7 @@ } void Continue_Reinitialize(ReinitTestCase test_case) { - const int kMockProcessId = 1; const int kMockRenderFrameId = MSG_ROUTING_NONE; - backend_ = - std::make_unique<AppCacheBackendImpl>(service_.get(), kMockProcessId); if (test_case == CORRUPT_SQL_ON_INSTALL) { // Break the db file @@ -1710,9 +1708,10 @@ test_case == CORRUPT_SQL_ON_INSTALL) { // Try to create a new appcache, the resulting update job will // eventually fail when it gets to disk cache initialization. - backend_->RegisterHost(blink::mojom::AppCacheHostRequest(), - BindFrontend(), 1, kMockRenderFrameId); - AppCacheHost* host1 = backend_->GetHost(1); + service_->RegisterHostForFrame(blink::mojom::AppCacheHostRequest(), + BindFrontend(), 1, kMockRenderFrameId, + kMockProcessId, GetBadMessageCallback()); + AppCacheHost* host1 = service_->GetHost(kMockProcessId, 1); const GURL kEmptyPageUrl(GetMockUrl("empty.html")); host1->SetFirstPartyUrlForTesting(kEmptyPageUrl); host1->SelectCache(kEmptyPageUrl, blink::mojom::kAppCacheNoCacheId, @@ -1722,9 +1721,10 @@ // Try to access the existing cache manifest. // The URLRequestJob will eventually fail when it gets to disk // cache initialization. - backend_->RegisterHost(blink::mojom::AppCacheHostRequest(), - BindFrontend(), 2, kMockRenderFrameId); - AppCacheHost* host2 = backend_->GetHost(2); + service_->RegisterHostForFrame(blink::mojom::AppCacheHostRequest(), + BindFrontend(), 2, kMockRenderFrameId, + kMockProcessId, GetBadMessageCallback()); + AppCacheHost* host2 = service_->GetHost(kMockProcessId, 2); network::ResourceRequest request; request.url = GetMockUrl("manifest"); handler_ = @@ -1757,20 +1757,21 @@ if (test_case == CORRUPT_CACHE_ON_INSTALL || test_case == CORRUPT_SQL_ON_INSTALL) { EXPECT_TRUE(frontend_.error_event_was_raised_); - AppCacheHost* host1 = backend_->GetHost(1); + AppCacheHost* host1 = service_->GetHost(kMockProcessId, 1); EXPECT_FALSE(host1->associated_cache()); EXPECT_FALSE(host1->group_being_updated_.get()); EXPECT_TRUE(host1->disabled_storage_reference_.get()); } else { ASSERT_EQ(CORRUPT_CACHE_ON_LOAD_EXISTING, test_case); - AppCacheHost* host2 = backend_->GetHost(2); + AppCacheHost* host2 = service_->GetHost(kMockProcessId, 2); EXPECT_TRUE(host2->disabled_storage_reference_.get()); } // Cleanup and claim victory. + service_->EraseHost(kMockProcessId, 1); + service_->EraseHost(kMockProcessId, 2); service_->RemoveObserver(observer_.get()); handler_.reset(); - backend_.reset(); observer_.reset(); TestFinished(); } @@ -1787,12 +1788,19 @@ MockStorageDelegate* delegate() { return delegate_.get(); } - blink::mojom::AppCacheFrontendPtr BindFrontend() { - blink::mojom::AppCacheFrontendPtr result; + blink::mojom::AppCacheFrontendPtrInfo BindFrontend() { + blink::mojom::AppCacheFrontendPtrInfo result; frontend_bindings_.AddBinding(&frontend_, mojo::MakeRequest(&result)); return result; } + mojo::ReportBadMessageCallback GetBadMessageCallback() { + return base::BindOnce(&AppCacheStorageImplTest::OnBadMessage, + base::Unretained(this)); + } + + void OnBadMessage(const std::string& reason) { NOTREACHED(); } + void MakeCacheAndGroup(const GURL& manifest_url, int64_t group_id, int64_t cache_id, @@ -2039,4 +2047,4 @@ // That's all folks! -} // namespace content \ No newline at end of file +} // namespace content
diff --git a/content/browser/background_sync/background_sync_manager.cc b/content/browser/background_sync/background_sync_manager.cc index bfc018a..320cd32 100644 --- a/content/browser/background_sync/background_sync_manager.cc +++ b/content/browser/background_sync/background_sync_manager.cc
@@ -1036,6 +1036,40 @@ } } +void BackgroundSyncManager::DispatchPeriodicSyncEvent( + const std::string& tag, + scoped_refptr<ServiceWorkerVersion> active_version, + ServiceWorkerVersion::StatusCallback callback) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK(active_version); + + if (active_version->running_status() != EmbeddedWorkerStatus::RUNNING) { + active_version->RunAfterStartWorker( + ServiceWorkerMetrics::EventType::PERIODIC_SYNC, + base::BindOnce( + &DidStartWorkerForSyncEvent, + base::BindOnce(&BackgroundSyncManager::DispatchPeriodicSyncEvent, + weak_ptr_factory_.GetWeakPtr(), tag, active_version), + std::move(callback))); + return; + } + + auto repeating_callback = + base::AdaptCallbackForRepeating(std::move(callback)); + + int request_id = active_version->StartRequestWithCustomTimeout( + ServiceWorkerMetrics::EventType::PERIODIC_SYNC, repeating_callback, + parameters_->max_sync_event_duration, + ServiceWorkerVersion::CONTINUE_ON_TIMEOUT); + + active_version->endpoint()->DispatchPeriodicSyncEvent( + tag, parameters_->max_sync_event_duration, + base::BindOnce(&OnSyncEventFinished, active_version, request_id, + std::move(repeating_callback))); + + // TODO(crbug.com/961238): Record Periodic Sync events for DevTools. +} + void BackgroundSyncManager::ScheduleDelayedTask(base::OnceClosure callback, base::TimeDelta delay) { base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( @@ -1285,21 +1319,6 @@ service_worker_registration->id()); DCHECK(registration); - // Don't dispatch a sync event if the sync is periodic. - // TODO(crbug.com/925297): Remove this code when we've added the logic to - // dispatch periodic sync events. - if (registration && - registration_info->sync_type == BackgroundSyncType::PERIODIC) { - RemoveActiveRegistration(*registration_info); - StoreRegistrations(registration_info->service_worker_registration_id, - base::DoNothing()); - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, std::move(event_fired_callback)); - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, std::move(event_completed_callback)); - return; - } - // The connectivity was lost before dispatching the sync event, so there is // no point in going through with it. if (!AreOptionConditionsMet()) { @@ -1320,13 +1339,26 @@ url::Origin::Create(service_worker_registration->scope().GetOrigin()), base::BindOnce(&BackgroundSyncMetrics::RecordEventStarted)); - DispatchSyncEvent( - registration->options()->tag, - service_worker_registration->active_version(), last_chance, - base::BindOnce( - &BackgroundSyncManager::EventComplete, weak_ptr_factory_.GetWeakPtr(), - service_worker_registration, std::move(registration_info), - std::move(keepalive), std::move(event_completed_callback))); + auto sync_type = registration_info->sync_type; + if (sync_type == BackgroundSyncType::ONE_SHOT) { + DispatchSyncEvent( + registration->options()->tag, + service_worker_registration->active_version(), last_chance, + base::BindOnce(&BackgroundSyncManager::EventComplete, + weak_ptr_factory_.GetWeakPtr(), + service_worker_registration, + std::move(registration_info), std::move(keepalive), + std::move(event_completed_callback))); + } else { + DispatchPeriodicSyncEvent( + registration->options()->tag, + service_worker_registration->active_version(), + base::BindOnce(&BackgroundSyncManager::EventComplete, + weak_ptr_factory_.GetWeakPtr(), + service_worker_registration, + std::move(registration_info), std::move(keepalive), + std::move(event_completed_callback))); + } base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, std::move(event_fired_callback));
diff --git a/content/browser/background_sync/background_sync_manager.h b/content/browser/background_sync/background_sync_manager.h index 8e1a5f1..9d61c267 100644 --- a/content/browser/background_sync/background_sync_manager.h +++ b/content/browser/background_sync/background_sync_manager.h
@@ -158,6 +158,10 @@ scoped_refptr<ServiceWorkerVersion> active_version, bool last_chance, ServiceWorkerVersion::StatusCallback callback); + virtual void DispatchPeriodicSyncEvent( + const std::string& tag, + scoped_refptr<ServiceWorkerVersion> active_version, + ServiceWorkerVersion::StatusCallback callback); virtual void ScheduleDelayedTask(base::OnceClosure callback, base::TimeDelta delay); virtual void HasMainFrameProviderHost(const url::Origin& origin,
diff --git a/content/browser/background_sync/background_sync_manager_unittest.cc b/content/browser/background_sync/background_sync_manager_unittest.cc index 4f53236..281c405a 100644 --- a/content/browser/background_sync/background_sync_manager_unittest.cc +++ b/content/browser/background_sync/background_sync_manager_unittest.cc
@@ -388,6 +388,13 @@ SetNetwork(network::mojom::ConnectionType::CONNECTION_WIFI); } + void SetupForPeriodicSyncEvent( + const TestBackgroundSyncManager::DispatchSyncCallback& callback) { + test_background_sync_manager_->set_dispatch_periodic_sync_callback( + callback); + SetNetwork(network::mojom::ConnectionType::CONNECTION_WIFI); + } + void DispatchSyncStatusCallback( blink::ServiceWorkerStatusCode status, scoped_refptr<ServiceWorkerVersion> active_version, @@ -396,12 +403,26 @@ std::move(callback).Run(status); } + void DispatchPeriodicSyncStatusCallback( + blink::ServiceWorkerStatusCode status, + scoped_refptr<ServiceWorkerVersion> active_version, + ServiceWorkerVersion::StatusCallback callback) { + periodic_sync_events_called_++; + std::move(callback).Run(status); + } + void InitSyncEventTest() { SetupForSyncEvent(base::BindRepeating( &BackgroundSyncManagerTest::DispatchSyncStatusCallback, base::Unretained(this), blink::ServiceWorkerStatusCode::kOk)); } + void InitPeriodicSyncEventTest() { + SetupForPeriodicSyncEvent(base::BindRepeating( + &BackgroundSyncManagerTest::DispatchPeriodicSyncStatusCallback, + base::Unretained(this), blink::ServiceWorkerStatusCode::kOk)); + } + void InitFailedSyncEventTest() { SetupForSyncEvent(base::BindRepeating( &BackgroundSyncManagerTest::DispatchSyncStatusCallback, @@ -424,12 +445,12 @@ void RegisterAndVerifySyncEventDelayed( blink::mojom::SyncRegistrationOptions sync_options) { - int sync_events_called = sync_events_called_; + int count_sync_events = sync_events_called_; EXPECT_FALSE(sync_fired_callback_); EXPECT_TRUE(Register(sync_options)); - EXPECT_EQ(sync_events_called + 1, sync_events_called_); + EXPECT_EQ(count_sync_events + 1, sync_events_called_); EXPECT_TRUE(GetRegistration(std::move(sync_options))); EXPECT_TRUE(sync_fired_callback_); } @@ -450,6 +471,12 @@ SetupBackgroundSyncManager(); } + void FireReadyEvents() { background_sync_manager_->OnNetworkChanged(); } + + bool AreOptionConditionsMet() { + return background_sync_manager_->AreOptionConditionsMet(); + } + TestBrowserThreadBundle browser_thread_bundle_; std::unique_ptr<EmbeddedWorkerTestHelper> helper_; std::unique_ptr<BackgroundSyncManager> background_sync_manager_; @@ -473,6 +500,7 @@ blink::ServiceWorkerStatusCode callback_sw_status_code_ = blink::ServiceWorkerStatusCode::kOk; int sync_events_called_ = 0; + int periodic_sync_events_called_ = 0; ServiceWorkerVersion::StatusCallback sync_fired_callback_; }; @@ -906,18 +934,21 @@ EXPECT_FALSE(GetRegistration(sync_options_1_)); } -// TODO(crbug.com/925297): Update once we support dispatching periodic sync -// events. -TEST_F(BackgroundSyncManagerTest, PeriodicSyncDoesNotFireOnRegistration) { - InitSyncEventTest(); - sync_options_2_.min_interval = 36000; - - EXPECT_TRUE(Register(sync_options_1_)); - EXPECT_EQ(1, sync_events_called_); - EXPECT_FALSE(GetRegistration(sync_options_1_)); +TEST_F(BackgroundSyncManagerTest, PeriodicSyncFiresWhenExpected) { + InitPeriodicSyncEventTest(); + int thirteen_hours_ms = 13 * 60 * 60 * 1000; + sync_options_2_.min_interval = thirteen_hours_ms; EXPECT_TRUE(Register(sync_options_2_)); - EXPECT_EQ(1, sync_events_called_); // no increase. + EXPECT_EQ(0, periodic_sync_events_called_); + EXPECT_TRUE(GetRegistration(sync_options_2_)); + + // Advance clock. + test_clock_.Advance(base::TimeDelta::FromMilliseconds(thirteen_hours_ms)); + FireReadyEvents(); + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(1, periodic_sync_events_called_); EXPECT_TRUE(GetRegistration(sync_options_2_)); } @@ -1611,6 +1642,24 @@ EXPECT_EQ(2, sync_events_called_); } +TEST_F(BackgroundSyncManagerTest, DispatchPeriodicSyncEvent) { + InitPeriodicSyncEventTest(); + + EXPECT_TRUE(AreOptionConditionsMet()); + + bool was_called = false; + blink::ServiceWorkerStatusCode code = + blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected; + test_background_sync_manager_->DispatchPeriodicSyncEvent( + "test_tag", sw_registration_1_->active_version(), + base::BindOnce(EmulateDispatchSyncEventCallback, &was_called, &code)); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(was_called); + EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, code); + + EXPECT_EQ(1, periodic_sync_events_called_); +} + TEST_F(BackgroundSyncManagerTest, EventsLoggedForRegistration) { // Note that the dispatch is mocked out, so those events are not registered // by these tests.
diff --git a/content/browser/cache_storage/cache_storage_blob_to_disk_cache.cc b/content/browser/cache_storage/cache_storage_blob_to_disk_cache.cc index f2ef2b2c..f8d230d 100644 --- a/content/browser/cache_storage/cache_storage_blob_to_disk_cache.cc +++ b/content/browser/cache_storage/cache_storage_blob_to_disk_cache.cc
@@ -30,7 +30,7 @@ CacheStorageBlobToDiskCache::~CacheStorageBlobToDiskCache() = default; void CacheStorageBlobToDiskCache::StreamBlobToCache( - disk_cache::ScopedEntryPtr entry, + ScopedWritableEntry entry, int disk_cache_body_index, blink::mojom::BlobPtr blob, uint64_t blob_size,
diff --git a/content/browser/cache_storage/cache_storage_blob_to_disk_cache.h b/content/browser/cache_storage/cache_storage_blob_to_disk_cache.h index efcfc5d..89964d86 100644 --- a/content/browser/cache_storage/cache_storage_blob_to_disk_cache.h +++ b/content/browser/cache_storage/cache_storage_blob_to_disk_cache.h
@@ -11,9 +11,9 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "content/browser/cache_storage/scoped_writable_entry.h" #include "content/common/content_export.h" #include "mojo/public/cpp/bindings/binding.h" -#include "net/disk_cache/disk_cache.h" #include "services/network/public/cpp/net_adapters.h" #include "third_party/blink/public/mojom/blob/blob.mojom.h" @@ -24,7 +24,7 @@ : public blink::mojom::BlobReaderClient { public: using EntryAndBoolCallback = - base::OnceCallback<void(disk_cache::ScopedEntryPtr, bool)>; + base::OnceCallback<void(ScopedWritableEntry, bool)>; // The buffer size used for reading from blobs and writing to disk cache. static const int kBufferSize; @@ -35,7 +35,7 @@ // Writes the body of |blob| to |entry| with index // |disk_cache_body_index|. |entry| is passed to the callback once complete. // Only call this once per instantiation of CacheStorageBlobToDiskCache. - void StreamBlobToCache(disk_cache::ScopedEntryPtr entry, + void StreamBlobToCache(ScopedWritableEntry entry, int disk_cache_body_index, blink::mojom::BlobPtr blob, uint64_t blob_size, @@ -57,7 +57,7 @@ void OnDataPipeReadable(MojoResult result); int cache_entry_offset_ = 0; - disk_cache::ScopedEntryPtr entry_; + ScopedWritableEntry entry_; int disk_cache_body_index_ = 0; EntryAndBoolCallback callback_;
diff --git a/content/browser/cache_storage/cache_storage_blob_to_disk_cache_unittest.cc b/content/browser/cache_storage/cache_storage_blob_to_disk_cache_unittest.cc index ddea197..9e90c8da 100644 --- a/content/browser/cache_storage/cache_storage_blob_to_disk_cache_unittest.cc +++ b/content/browser/cache_storage/cache_storage_blob_to_disk_cache_unittest.cc
@@ -16,6 +16,7 @@ #include "base/test/null_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "content/browser/blob_storage/chrome_blob_storage_context.h" +#include "content/browser/cache_storage/scoped_writable_entry.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/storage_partition.h" @@ -181,7 +182,7 @@ return callback_called_ && callback_success_; } - void StreamCallback(disk_cache::ScopedEntryPtr entry_ptr, bool success) { + void StreamCallback(ScopedWritableEntry entry_ptr, bool success) { disk_cache_entry_ = std::move(entry_ptr); callback_success_ = success; callback_called_ = true; @@ -194,7 +195,7 @@ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_; std::unique_ptr<storage::BlobDataHandle> blob_handle_; std::unique_ptr<disk_cache::Backend> cache_backend_; - disk_cache::ScopedEntryPtr disk_cache_entry_; + ScopedWritableEntry disk_cache_entry_; std::unique_ptr<TestCacheStorageBlobToDiskCache> cache_storage_blob_to_disk_cache_; std::string data_;
diff --git a/content/browser/cache_storage/cache_storage_cache_entry_handler.h b/content/browser/cache_storage/cache_storage_cache_entry_handler.h index 358835d..688ec2e 100644 --- a/content/browser/cache_storage/cache_storage_cache_entry_handler.h +++ b/content/browser/cache_storage/cache_storage_cache_entry_handler.h
@@ -12,6 +12,7 @@ #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "content/browser/cache_storage/cache_storage_cache_handle.h" +#include "content/browser/cache_storage/scoped_writable_entry.h" #include "content/common/content_export.h" #include "net/disk_cache/disk_cache.h" #include "storage/browser/blob/blob_data_builder.h" @@ -51,7 +52,7 @@ // Provided while writing to the cache. ErrorCallback callback; - disk_cache::ScopedEntryPtr cache_entry; + ScopedWritableEntry cache_entry; private: DISALLOW_COPY_AND_ASSIGN(PutContext);
diff --git a/content/browser/cache_storage/cache_storage_cache_unittest.cc b/content/browser/cache_storage/cache_storage_cache_unittest.cc index f19da57..4e500b0c 100644 --- a/content/browser/cache_storage/cache_storage_cache_unittest.cc +++ b/content/browser/cache_storage/cache_storage_cache_unittest.cc
@@ -40,6 +40,8 @@ #include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_utils.h" #include "crypto/symmetric_key.h" +#include "mojo/public/cpp/bindings/strong_binding.h" +#include "mojo/public/cpp/system/data_pipe.h" #include "mojo/public/cpp/system/data_pipe_drainer.h" #include "net/base/test_completion_callback.h" #include "net/disk_cache/disk_cache.h" @@ -52,6 +54,7 @@ #include "storage/browser/blob/blob_storage_context.h" #include "storage/browser/blob/blob_url_request_job_factory.h" #include "storage/browser/quota/quota_manager_proxy.h" +#include "storage/browser/test/fake_blob.h" #include "storage/browser/test/mock_quota_manager_proxy.h" #include "storage/browser/test/mock_special_storage_policy.h" #include "storage/common/blob_storage/blob_handle.h" @@ -94,6 +97,22 @@ run_loop->Quit(); } +// A blob that never finishes writing to its pipe. +class SlowBlob : public storage::FakeBlob { + public: + explicit SlowBlob(base::OnceClosure quit_closure) + : FakeBlob("foo"), quit_closure_(std::move(quit_closure)) {} + + void ReadAll(mojo::ScopedDataPipeProducerHandle producer_handle, + blink::mojom::BlobReaderClientPtr client) override { + // Don't respond, forcing the consumer to wait forever. + std::move(quit_closure_).Run(); + } + + private: + base::OnceClosure quit_closure_; +}; + // A disk_cache::Backend wrapper that can delay operations. class DelayableBackend : public disk_cache::Backend { public: @@ -416,15 +435,14 @@ blob_storage_context_ = blob_storage_context->context(); const bool is_incognito = MemoryOnly(); - base::FilePath temp_dir_path; if (!is_incognito) { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - temp_dir_path = temp_dir_.GetPath(); + temp_dir_path_ = temp_dir_.GetPath(); } quota_policy_ = new MockSpecialStoragePolicy; mock_quota_manager_ = new MockQuotaManager( - is_incognito, temp_dir_path, base::ThreadTaskRunnerHandle::Get().get(), + is_incognito, temp_dir_path_, base::ThreadTaskRunnerHandle::Get().get(), quota_policy_.get()); mock_quota_manager_->SetQuota( kOrigin, blink::mojom::StorageType::kTemporary, 1024 * 1024 * 100); @@ -456,13 +474,13 @@ // CacheStorageCacheHandle reference counting. A LegacyCacheStorage // must be present to be notified when a cache becomes unreferenced. mock_cache_storage_ = std::make_unique<MockLegacyCacheStorage>( - temp_dir_path, MemoryOnly(), base::ThreadTaskRunnerHandle::Get().get(), + temp_dir_path_, MemoryOnly(), base::ThreadTaskRunnerHandle::Get().get(), quota_manager_proxy_, blob_storage_context_->AsWeakPtr(), /* cache_storage_manager = */ nullptr, kOrigin, CacheStorageOwner::kCacheAPI); cache_ = std::make_unique<TestCacheStorageCache>( - kOrigin, kCacheName, temp_dir_path, mock_cache_storage_.get(), + kOrigin, kCacheName, temp_dir_path_, mock_cache_storage_.get(), quota_manager_proxy_, blob_storage_context->context()->AsWeakPtr()); cache_->Init(); } @@ -842,6 +860,7 @@ storage::BlobStorageContext* blob_storage_context_; std::unique_ptr<MockLegacyCacheStorage> mock_cache_storage_; + base::FilePath temp_dir_path_; std::unique_ptr<TestCacheStorageCache> cache_; blink::mojom::FetchAPIRequestPtr body_request_; @@ -2211,6 +2230,53 @@ VerifyAllOpsFail(); } +// Shutdown the cache in the middle of its writing the response body. Upon +// restarting, that response shouldn't be available. See crbug.com/617683. +TEST_P(CacheStorageCacheTestP, UnfinishedPutsShouldNotBeReusable) { + // Create a response with a blob that takes forever to write its bytes to the + // mojo pipe. Guaranteeing that the response isn't finished writing by the + // time we close the backend. + base::RunLoop run_loop; + auto blob = blink::mojom::SerializedBlob::New(); + blob->uuid = "mock blob"; + blob->size = 100; + mojo::MakeStrongBinding(std::make_unique<SlowBlob>(run_loop.QuitClosure()), + MakeRequest(&blob->blob)); + blink::mojom::FetchAPIResponsePtr response = CreateNoBodyResponse(); + response->url_list = {kBodyUrl}; + response->blob = std::move(blob); + + blink::mojom::BatchOperationPtr operation = + blink::mojom::BatchOperation::New(); + operation->operation_type = blink::mojom::OperationType::kPut; + operation->request = BackgroundFetchSettledFetch::CloneRequest(body_request_); + operation->response = std::move(response); + std::vector<blink::mojom::BatchOperationPtr> operations; + operations.emplace_back(std::move(operation)); + + // Start the put operation and let it run until the blob is supposed to write + // to its pipe. + cache_->BatchOperation(std::move(operations), /* trace_id = */ 0, + base::DoNothing(), base::DoNothing()); + run_loop.Run(); + + // Shut down the cache. Doing so causes the write to cease, and the entry + // should be erased. + cache_ = nullptr; + base::RunLoop().RunUntilIdle(); + + // Create a new Cache in the same space. + ChromeBlobStorageContext* blob_storage_context = + ChromeBlobStorageContext::GetFor(&browser_context_); + cache_ = std::make_unique<TestCacheStorageCache>( + kOrigin, kCacheName, temp_dir_path_, nullptr /* CacheStorage */, + quota_manager_proxy_, blob_storage_context->context()->AsWeakPtr()); + cache_->Init(); + + // Now attempt to read the same response from the cache. It should fail. + EXPECT_FALSE(Match(body_request_)); +} + TEST_P(CacheStorageCacheTestP, BlobReferenceDelaysClose) { // Create the backend and put something in it. EXPECT_TRUE(Put(body_request_, CreateBlobBodyResponse()));
diff --git a/content/browser/cache_storage/legacy/legacy_cache_storage_cache.cc b/content/browser/cache_storage/legacy/legacy_cache_storage_cache.cc index 0a5299b..db4c2f6 100644 --- a/content/browser/cache_storage/legacy/legacy_cache_storage_cache.cc +++ b/content/browser/cache_storage/legacy/legacy_cache_storage_cache.cc
@@ -39,6 +39,7 @@ #include "content/browser/cache_storage/cache_storage_quota_client.h" #include "content/browser/cache_storage/cache_storage_scheduler.h" #include "content/browser/cache_storage/cache_storage_trace_utils.h" +#include "content/browser/cache_storage/legacy/legacy_cache_storage.h" #include "content/common/background_fetch/background_fetch_types.h" #include "content/common/service_worker/service_worker_utils.h" #include "content/public/browser/browser_thread.h" @@ -1416,7 +1417,11 @@ std::move(callback).Run(CacheStorageError::kErrorNotFound); return; } - disk_cache::ScopedEntryPtr entry(*entry_ptr); + + // Moving the entry into a ScopedWritableEntry which will doom the entry + // before closing unless we tell it that writing has successfully completed + // via WritingCompleted. + ScopedWritableEntry entry(*entry_ptr); ReadMetadata( *entry_ptr, @@ -1432,7 +1437,7 @@ int64_t trace_id, scoped_refptr<net::IOBuffer> buffer, int buf_len, - disk_cache::ScopedEntryPtr entry, + ScopedWritableEntry entry, std::unique_ptr<proto::CacheMetadata> headers) { TRACE_EVENT_WITH_FLOW0( "CacheStorage", "LegacyCacheStorageCache::WriteSideDataDidReadMetaData", @@ -1440,7 +1445,8 @@ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); if (!headers || headers->response().response_time() != expected_response_time.ToInternalValue()) { - std::move(callback).Run(CacheStorageError::kErrorNotFound); + WriteSideDataComplete(std::move(callback), std::move(entry), + CacheStorageError::kErrorNotFound); return; } // Get a temporary copy of the entry pointer before passing it in base::Bind. @@ -1472,7 +1478,7 @@ void LegacyCacheStorageCache::WriteSideDataDidWrite( ErrorCallback callback, - disk_cache::ScopedEntryPtr entry, + ScopedWritableEntry entry, int expected_bytes, std::unique_ptr<::content::proto::CacheResponse> response, int side_data_size_before_write, @@ -1482,9 +1488,8 @@ "LegacyCacheStorageCache::WriteSideDataDidWrite", TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN); if (rv != expected_bytes) { - entry->Doom(); - UpdateCacheSize( - base::BindOnce(std::move(callback), CacheStorageError::kErrorNotFound)); + WriteSideDataComplete(std::move(callback), std::move(entry), + CacheStorageError::kErrorStorage); return; } @@ -1499,8 +1504,31 @@ response.get(), cache_padding_key_.get(), rv); } - UpdateCacheSize( - base::BindOnce(std::move(callback), CacheStorageError::kSuccess)); + WriteSideDataComplete(std::move(callback), std::move(entry), + CacheStorageError::kSuccess); +} + +void LegacyCacheStorageCache::WriteSideDataComplete( + ErrorCallback callback, + ScopedWritableEntry entry, + blink::mojom::CacheStorageError error) { + if (error != CacheStorageError::kSuccess) { + // If we found the entry, then we possibly wrote something and now we're + // dooming the entry, causing a change in size, so update the size before + // returning. + if (error != CacheStorageError::kErrorNotFound) { + UpdateCacheSize(base::BindOnce(std::move(callback), error)); + return; + } + + entry.get_deleter() + .WritingCompleted(); // Since we didn't change the entry. + std::move(callback).Run(error); + return; + } + + entry.get_deleter().WritingCompleted(); // Since we didn't change the entry. + UpdateCacheSize(base::BindOnce(std::move(callback), error)); } void LegacyCacheStorageCache::Put(blink::mojom::BatchOperationPtr operation, @@ -1541,8 +1569,8 @@ CacheStorageTracedValue(put_context->request), "response", CacheStorageTracedValue(put_context->response)); if (backend_state_ != BACKEND_OPEN) { - std::move(put_context->callback) - .Run(MakeErrorStorage(ErrorStorageType::kPutImplBackendClosed)); + PutComplete(std::move(put_context), + MakeErrorStorage(ErrorStorageType::kPutImplBackendClosed)); return; } @@ -1581,15 +1609,15 @@ TRACE_ID_GLOBAL(put_context->trace_id), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); if (backend_state_ != BACKEND_OPEN) { - std::move(put_context->callback) - .Run(MakeErrorStorage( - ErrorStorageType::kPutDidDeleteEntryBackendClosed)); + PutComplete( + std::move(put_context), + MakeErrorStorage(ErrorStorageType::kPutDidDeleteEntryBackendClosed)); return; } if (error != CacheStorageError::kSuccess && error != CacheStorageError::kErrorNotFound) { - std::move(put_context->callback).Run(error); + PutComplete(std::move(put_context), error); return; } @@ -1624,10 +1652,13 @@ TRACE_ID_GLOBAL(put_context->trace_id), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); + // Moving the entry into a ScopedWritableEntry which will doom the entry + // before closing unless we tell it that writing has successfully completed + // via WritingCompleted. put_context->cache_entry.reset(*entry_ptr); if (rv != net::OK) { - std::move(put_context->callback).Run(CacheStorageError::kErrorExists); + PutComplete(std::move(put_context), CacheStorageError::kErrorExists); return; } @@ -1666,8 +1697,9 @@ std::unique_ptr<std::string> serialized(new std::string()); if (!metadata.SerializeToString(serialized.get())) { - std::move(put_context->callback) - .Run(MakeErrorStorage(ErrorStorageType::kMetadataSerializationFailed)); + PutComplete( + std::move(put_context), + MakeErrorStorage(ErrorStorageType::kMetadataSerializationFailed)); return; } @@ -1704,9 +1736,9 @@ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); if (rv != expected_bytes) { - put_context->cache_entry->Doom(); - std::move(put_context->callback) - .Run(MakeErrorStorage(ErrorStorageType::kPutDidWriteHeadersWrongBytes)); + PutComplete( + std::move(put_context), + MakeErrorStorage(ErrorStorageType::kPutDidWriteHeadersWrongBytes)); return; } @@ -1732,8 +1764,7 @@ return; } - UpdateCacheSize(base::BindOnce(std::move(put_context->callback), - CacheStorageError::kSuccess)); + PutComplete(std::move(put_context), CacheStorageError::kSuccess); } void LegacyCacheStorageCache::PutWriteBlobToCache( @@ -1747,17 +1778,28 @@ TRACE_ID_GLOBAL(put_context->trace_id), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); - blink::mojom::BlobPtr blob = disk_cache_body_index == INDEX_RESPONSE_BODY - ? std::move(put_context->blob) - : std::move(put_context->side_data_blob); + blink::mojom::BlobPtr blob; + int64_t blob_size = 0; + + switch (disk_cache_body_index) { + case INDEX_RESPONSE_BODY: { + blob = std::move(put_context->blob); + put_context->blob.reset(); + blob_size = put_context->blob_size; + break; + } + case INDEX_SIDE_DATA: { + blob = std::move(put_context->side_data_blob); + put_context->side_data_blob.reset(); + blob_size = put_context->side_data_blob_size; + break; + } + case INDEX_HEADERS: + NOTREACHED(); + } DCHECK(blob); - int64_t blob_size = disk_cache_body_index == INDEX_RESPONSE_BODY - ? put_context->blob_size - : put_context->side_data_blob_size; - - disk_cache::ScopedEntryPtr entry(std::move(put_context->cache_entry)); - put_context->cache_entry = nullptr; + ScopedWritableEntry entry(put_context->cache_entry.release()); auto blob_to_cache = std::make_unique<CacheStorageBlobToDiskCache>(); CacheStorageBlobToDiskCache* blob_to_cache_raw = blob_to_cache.get(); @@ -1774,7 +1816,7 @@ void LegacyCacheStorageCache::PutDidWriteBlobToCache( std::unique_ptr<PutContext> put_context, BlobToDiskCacheIDMap::KeyType blob_to_cache_key, - disk_cache::ScopedEntryPtr entry, + ScopedWritableEntry entry, bool success) { DCHECK(entry); TRACE_EVENT_WITH_FLOW0("CacheStorage", @@ -1787,9 +1829,9 @@ active_blob_to_disk_cache_writers_.Remove(blob_to_cache_key); if (!success) { - put_context->cache_entry->Doom(); - std::move(put_context->callback) - .Run(MakeErrorStorage(ErrorStorageType::kPutDidWriteBlobToCacheFailed)); + PutComplete( + std::move(put_context), + MakeErrorStorage(ErrorStorageType::kPutDidWriteBlobToCacheFailed)); return; } @@ -1798,8 +1840,24 @@ return; } - UpdateCacheSize(base::BindOnce(std::move(put_context->callback), - CacheStorageError::kSuccess)); + PutComplete(std::move(put_context), CacheStorageError::kSuccess); +} + +void LegacyCacheStorageCache::PutComplete( + std::unique_ptr<PutContext> put_context, + blink::mojom::CacheStorageError error) { + if (error == CacheStorageError::kSuccess) { + // Make sure we've written everything. + DCHECK(put_context->cache_entry); + DCHECK(!put_context->blob); + DCHECK(!put_context->side_data_blob); + + // Tell the WritableScopedEntry not to doom the entry since it was a + // successful operation. + put_context->cache_entry.get_deleter().WritingCompleted(); + } + + UpdateCacheSize(base::BindOnce(std::move(put_context->callback), error)); } void LegacyCacheStorageCache::CalculateCacheSizePadding(
diff --git a/content/browser/cache_storage/legacy/legacy_cache_storage_cache.h b/content/browser/cache_storage/legacy/legacy_cache_storage_cache.h index 2a24559..bce6bad 100644 --- a/content/browser/cache_storage/legacy/legacy_cache_storage_cache.h +++ b/content/browser/cache_storage/legacy/legacy_cache_storage_cache.h
@@ -19,6 +19,7 @@ #include "base/optional.h" #include "content/browser/cache_storage/cache_storage_cache.h" #include "content/browser/cache_storage/cache_storage_handle.h" +#include "content/browser/cache_storage/scoped_writable_entry.h" #include "content/common/service_worker/service_worker_types.h" #include "net/base/completion_once_callback.h" #include "net/base/io_buffer.h" @@ -333,16 +334,19 @@ int64_t trace_id, scoped_refptr<net::IOBuffer> buffer, int buf_len, - disk_cache::ScopedEntryPtr entry, + ScopedWritableEntry entry, std::unique_ptr<proto::CacheMetadata> headers); void WriteSideDataDidWrite( ErrorCallback callback, - disk_cache::ScopedEntryPtr entry, + ScopedWritableEntry entry, int expected_bytes, std::unique_ptr<content::proto::CacheResponse> response, int side_data_size_before_write, int64_t trace_id, int rv); + void WriteSideDataComplete(ErrorCallback callback, + ScopedWritableEntry entry, + blink::mojom::CacheStorageError error); // Puts the request and response object in the cache. The response body (if // present) is stored in the cache, but not the request body. Returns OK on @@ -367,8 +371,10 @@ int disk_cache_body_index); void PutDidWriteBlobToCache(std::unique_ptr<PutContext> put_context, BlobToDiskCacheIDMap::KeyType blob_to_cache_key, - disk_cache::ScopedEntryPtr entry, + ScopedWritableEntry entry, bool success); + void PutComplete(std::unique_ptr<PutContext> put_context, + blink::mojom::CacheStorageError error); // Asynchronously calculates the current cache size, notifies the quota // manager of any change from the last report, and sets cache_size_ to the new
diff --git a/content/browser/cache_storage/scoped_writable_entry.h b/content/browser/cache_storage/scoped_writable_entry.h new file mode 100644 index 0000000..93f5515 --- /dev/null +++ b/content/browser/cache_storage/scoped_writable_entry.h
@@ -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. + +#ifndef CONTENT_BROWSER_CACHE_STORAGE_SCOPED_WRITABLE_ENTRY_H_ +#define CONTENT_BROWSER_CACHE_STORAGE_SCOPED_WRITABLE_ENTRY_H_ + +#include <memory> + +#include "net/disk_cache/disk_cache.h" + +namespace content { + +// A custom deleter that closes the entry. But if WritingCompleted() hasn't been +// called, it will doom the entry before closing it. +class ScopedWritableDeleter { + public: + ScopedWritableDeleter() = default; + ScopedWritableDeleter(ScopedWritableDeleter&& other) = default; + ScopedWritableDeleter& operator=(ScopedWritableDeleter&& other) = default; + + void operator()(disk_cache::Entry* entry) { + if (!completed_) + entry->Doom(); + + // |entry| is owned by the backend, we just need to close it as it's + // ref-counted. + entry->Close(); + } + + void WritingCompleted() { completed_ = true; } + + private: + bool completed_ = false; +}; + +// Use this to manage disk_cache::Entry*'s that should be doomed before closing +// unless told otherwise (via calling WritingCompleted on the deleter). +// +// Example: +// ScopedWritableEntry entry(my_entry); +// .. write some stuff .. +// entry.get_deleter().WritingCompleted(); +typedef std::unique_ptr<disk_cache::Entry, ScopedWritableDeleter> + ScopedWritableEntry; + +} // namespace content + +#endif // CONTENT_BROWSER_CACHE_STORAGE_SCOPED_WRITABLE_ENTRY_H_
diff --git a/content/browser/devtools/protocol/service_worker_handler.h b/content/browser/devtools/protocol/service_worker_handler.h index ec9ab86..13f2533 100644 --- a/content/browser/devtools/protocol/service_worker_handler.h +++ b/content/browser/devtools/protocol/service_worker_handler.h
@@ -56,6 +56,7 @@ const std::string& registration_id, const std::string& tag, bool last_chance) override; + // TODO(crbug.com/961238): Add DispatchPeriodicSyncEvent(). private: void OnWorkerRegistrationUpdated(
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 27187fd..3a1a2125 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -190,6 +190,7 @@ #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/frame/frame_policy.h" #include "third_party/blink/public/common/messaging/transferable_message.h" +#include "third_party/blink/public/mojom/appcache/appcache.mojom.h" #include "third_party/blink/public/mojom/frame/frame_host_test_interface.mojom.h" #include "third_party/blink/public/mojom/loader/pause_subresource_loading_handle.mojom.h" #include "third_party/blink/public/mojom/loader/url_loader_factory_bundle.mojom.h" @@ -5983,6 +5984,22 @@ #endif // !defined(OS_ANDROID) } +void RenderFrameHostImpl::RegisterAppCacheHost( + blink::mojom::AppCacheHostRequest host_request, + blink::mojom::AppCacheFrontendPtr frontend, + int32_t id) { + auto* appcache_service_impl = static_cast<AppCacheServiceImpl*>( + GetProcess()->GetStoragePartition()->GetAppCacheService()); + + base::PostTaskWithTraits( + FROM_HERE, {BrowserThread::IO}, + base::BindOnce(&AppCacheServiceImpl::RegisterHostForFrame, + appcache_service_impl->AsWeakPtr(), + std::move(host_request), frontend.PassInterface(), id, + routing_id_, GetProcess()->GetID(), + mojo::GetBadMessageCallback())); +} + std::unique_ptr<NavigationRequest> RenderFrameHostImpl::CreateNavigationRequestForCommit( const FrameHostMsg_DidCommitProvisionalLoad_Params& params,
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index 61a04da..5eff918 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -1378,6 +1378,9 @@ void GetAuthenticator(blink::mojom::AuthenticatorRequest request) override; void GetVirtualAuthenticatorManager( blink::test::mojom::VirtualAuthenticatorManagerRequest request) override; + void RegisterAppCacheHost(blink::mojom::AppCacheHostRequest host_request, + blink::mojom::AppCacheFrontendPtr frontend, + int32_t id) override; // Allows tests to disable the swapout event timer to simulate bugs that // happen before it fires (to avoid flakiness).
diff --git a/content/browser/picture_in_picture/picture_in_picture_service_impl.cc b/content/browser/picture_in_picture/picture_in_picture_service_impl.cc index fe51da3..2d82643 100644 --- a/content/browser/picture_in_picture/picture_in_picture_service_impl.cc +++ b/content/browser/picture_in_picture/picture_in_picture_service_impl.cc
@@ -6,8 +6,7 @@ #include <utility> -#include "content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h" -#include "content/browser/web_contents/web_contents_impl.h" +#include "content/browser/picture_in_picture/picture_in_picture_session.h" namespace content { @@ -32,66 +31,17 @@ const gfx::Size& natural_size, bool show_play_pause_button, bool show_mute_button, + blink::mojom::PictureInPictureSessionObserverPtr observer, StartSessionCallback callback) { - player_id_ = MediaPlayerId(render_frame_host_, player_id); + blink::mojom::PictureInPictureSessionPtr session_ptr; - auto* pip_controller = GetController(); - if (pip_controller) - pip_controller->set_service(this); + gfx::Size window_size; + active_session_.reset(new PictureInPictureSession( + this, MediaPlayerId(render_frame_host_, player_id), surface_id, + natural_size, show_play_pause_button, show_mute_button, + mojo::MakeRequest(&session_ptr), std::move(observer), &window_size)); - gfx::Size window_size = web_contents_impl()->EnterPictureInPicture( - surface_id.value(), natural_size); - - if (pip_controller) { - pip_controller->SetAlwaysHidePlayPauseButton(show_play_pause_button); - pip_controller->SetAlwaysHideMuteButton(show_mute_button); - } - - std::move(callback).Run(window_size); -} - -void PictureInPictureServiceImpl::EndSession(EndSessionCallback callback) { - DCHECK(player_id_); - - ExitPictureInPictureInternal(); - - std::move(callback).Run(); -} - -void PictureInPictureServiceImpl::UpdateSession( - uint32_t player_id, - const base::Optional<viz::SurfaceId>& surface_id, - const gfx::Size& natural_size, - bool show_play_pause_button, - bool show_mute_button) { - player_id_ = MediaPlayerId(render_frame_host_, player_id); - - // The PictureInPictureWindowController instance may not have been created by - // the embedder. - if (auto* pip_controller = GetController()) { - pip_controller->EmbedSurface(surface_id.value(), natural_size); - pip_controller->SetAlwaysHidePlayPauseButton(show_play_pause_button); - pip_controller->SetAlwaysHideMuteButton(show_mute_button); - pip_controller->set_service(this); - } -} - -void PictureInPictureServiceImpl::SetDelegate( - blink::mojom::PictureInPictureDelegatePtr delegate) { - delegate.set_connection_error_handler( - base::BindOnce(&PictureInPictureServiceImpl::OnDelegateDisconnected, - // delegate is held by |this|. - base::Unretained(this))); - - if (delegate_) - mojo::ReportBadMessage("SetDelegate() should only be called once."); - - delegate_ = std::move(delegate); -} - -void PictureInPictureServiceImpl::NotifyWindowResized(const gfx::Size& size) { - if (delegate_) - delegate_->PictureInPictureWindowSizeChanged(size); + std::move(callback).Run(std::move(session_ptr), window_size); } PictureInPictureServiceImpl::PictureInPictureServiceImpl( @@ -101,35 +51,10 @@ render_frame_host_(render_frame_host) {} PictureInPictureServiceImpl::~PictureInPictureServiceImpl() { - if (player_id_) - ExitPictureInPictureInternal(); - if (GetController()) - GetController()->set_service(nullptr); -} - -PictureInPictureWindowControllerImpl* -PictureInPictureServiceImpl::GetController() { - return PictureInPictureWindowControllerImpl::GetOrCreateForWebContents( - web_contents_impl()); -} - -void PictureInPictureServiceImpl::OnDelegateDisconnected() { - delegate_ = nullptr; -} - -void PictureInPictureServiceImpl::ExitPictureInPictureInternal() { - web_contents_impl()->ExitPictureInPicture(); - - // Reset must happen after notifying the WebContents because it may interact - // with it. - player_id_.reset(); - - if (auto* controller = GetController()) - controller->set_service(nullptr); -} - -WebContentsImpl* PictureInPictureServiceImpl::web_contents_impl() { - return static_cast<WebContentsImpl*>(web_contents()); + // If the service is destroyed because the frame was destroyed, the session + // may still be active and it has to be shutdown before its dtor runs. + if (active_session_) + active_session_->Shutdown(); } } // namespace content
diff --git a/content/browser/picture_in_picture/picture_in_picture_service_impl.h b/content/browser/picture_in_picture/picture_in_picture_service_impl.h index d9cab4a..2d32633 100644 --- a/content/browser/picture_in_picture/picture_in_picture_service_impl.h +++ b/content/browser/picture_in_picture/picture_in_picture_service_impl.h
@@ -8,17 +8,17 @@ #include "base/containers/unique_ptr_adapters.h" #include "content/common/content_export.h" #include "content/public/browser/frame_service_base.h" -#include "content/public/browser/media_player_id.h" #include "third_party/blink/public/mojom/picture_in_picture/picture_in_picture.mojom.h" namespace content { -class PictureInPictureWindowControllerImpl; +class PictureInPictureSession; // Receives Picture-in-Picture messages from a given RenderFrame. There is one -// PictureInPictureServiceImpl per RenderFrameHost. It talks directly to the -// PictureInPictureWindowControllerImpl. Only one service interacts with the -// window at a given time. +// PictureInPictureServiceImpl per RenderFrameHost. The service gets a hold of +// a PictureInPictureSession to which it delegates most of the interactions with +// the rest of the Picture-in-Picture classes such as +// PictureInPictureWindowController. class CONTENT_EXPORT PictureInPictureServiceImpl final : public content::FrameServiceBase<blink::mojom::PictureInPictureService> { public: @@ -34,44 +34,23 @@ const gfx::Size& natural_size, bool show_play_pause_button, bool show_mute_button, + blink::mojom::PictureInPictureSessionObserverPtr, StartSessionCallback) final; - void EndSession(EndSessionCallback) final; - void UpdateSession(uint32_t player_id, - const base::Optional<viz::SurfaceId>& surface_id, - const gfx::Size& natural_size, - bool show_play_pause_button, - bool show_mute_button) final; - void SetDelegate(blink::mojom::PictureInPictureDelegatePtr) final; - void NotifyWindowResized(const gfx::Size&); - - // Returns the player that is currently in Picture-in-Picture in the context - // of the frame associated with the service. Returns nullopt if there are - // none. - const base::Optional<MediaPlayerId>& player_id() const { return player_id_; } - void ResetPlayerId() { player_id_.reset(); } + PictureInPictureSession* active_session_for_testing() const { + return active_session_.get(); + } private: + friend class PictureInPictureSession; + PictureInPictureServiceImpl(RenderFrameHost*, blink::mojom::PictureInPictureServiceRequest); ~PictureInPictureServiceImpl() override; - // Returns the PictureInPictureWindowControllerImpl associated with the - // WebContents. Can be null. - PictureInPictureWindowControllerImpl* GetController(); - - // Callack run when the delegate is disconnected. Only one delegate should be - // set at any given time. - void OnDelegateDisconnected(); - - // Implementation of ExitPictureInPicture without callback handling. - void ExitPictureInPictureInternal(); - - WebContentsImpl* web_contents_impl(); - - blink::mojom::PictureInPictureDelegatePtr delegate_ = nullptr; RenderFrameHost* render_frame_host_ = nullptr; - base::Optional<MediaPlayerId> player_id_; + + std::unique_ptr<PictureInPictureSession> active_session_; DISALLOW_COPY_AND_ASSIGN(PictureInPictureServiceImpl); };
diff --git a/content/browser/picture_in_picture/picture_in_picture_service_impl_unittest.cc b/content/browser/picture_in_picture/picture_in_picture_service_impl_unittest.cc index 0f99ec23..b2603154 100644 --- a/content/browser/picture_in_picture/picture_in_picture_service_impl_unittest.cc +++ b/content/browser/picture_in_picture/picture_in_picture_service_impl_unittest.cc
@@ -19,6 +19,20 @@ namespace content { +class DummyPictureInPictureSessionObserver + : public blink::mojom::PictureInPictureSessionObserver { + public: + DummyPictureInPictureSessionObserver() = default; + ~DummyPictureInPictureSessionObserver() final = default; + + // Implementation of PictureInPictureSessionObserver. + void OnWindowSizeChanged(const gfx::Size&) final {} + void OnStopped() final {} + + private: + DISALLOW_COPY_AND_ASSIGN(DummyPictureInPictureSessionObserver); +}; + class PictureInPictureDelegate : public WebContentsDelegate { public: PictureInPictureDelegate() = default; @@ -113,9 +127,14 @@ TEST_F(PictureInPictureServiceImplTest, EnterPictureInPicture) { const int kPlayerVideoOnlyId = 30; - // If Picture-in-Picture was never triggered, the media player id would not be - // set. - EXPECT_FALSE(service().player_id().has_value()); + DummyPictureInPictureSessionObserver observer; + mojo::Binding<blink::mojom::PictureInPictureSessionObserver> + observer_bindings(&observer); + blink::mojom::PictureInPictureSessionObserverPtr observer_ptr; + observer_bindings.Bind(mojo::MakeRequest(&observer_ptr)); + + // If Picture-in-Picture there shouldn't be an active session. + EXPECT_FALSE(service().active_session_for_testing()); viz::SurfaceId surface_id = viz::SurfaceId(viz::FrameSinkId(1, 1), @@ -127,9 +146,9 @@ service().StartSession(kPlayerVideoOnlyId, surface_id, gfx::Size(42, 42), true /* show_play_pause_button */, - true /* show_mute_button */, base::DoNothing()); - EXPECT_TRUE(service().player_id().has_value()); - EXPECT_EQ(kPlayerVideoOnlyId, service().player_id()->delegate_id); + true /* show_mute_button */, std::move(observer_ptr), + base::DoNothing()); + EXPECT_TRUE(service().active_session_for_testing()); // Picture-in-Picture media player id should not be reset when the media is // destroyed (e.g. video stops playing). This allows the Picture-in-Picture @@ -137,7 +156,7 @@ contents()->GetMainFrame()->OnMessageReceived( MediaPlayerDelegateHostMsg_OnMediaDestroyed( contents()->GetMainFrame()->GetRoutingID(), kPlayerVideoOnlyId)); - EXPECT_TRUE(service().player_id().has_value()); + EXPECT_TRUE(service().active_session_for_testing()); } } // namespace content
diff --git a/content/browser/picture_in_picture/picture_in_picture_session.cc b/content/browser/picture_in_picture/picture_in_picture_session.cc new file mode 100644 index 0000000..641f514e2 --- /dev/null +++ b/content/browser/picture_in_picture/picture_in_picture_session.cc
@@ -0,0 +1,119 @@ +// 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 "content/browser/picture_in_picture/picture_in_picture_session.h" + +#include "content/browser/picture_in_picture/picture_in_picture_service_impl.h" +#include "content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h" +#include "content/browser/web_contents/web_contents_impl.h" +#include "content/common/media/media_player_delegate_messages.h" + +namespace content { + +PictureInPictureSession::PictureInPictureSession( + PictureInPictureServiceImpl* service, + const MediaPlayerId& player_id, + const base::Optional<viz::SurfaceId>& surface_id, + const gfx::Size& natural_size, + bool show_play_pause_button, + bool show_mute_button, + mojo::InterfaceRequest<blink::mojom::PictureInPictureSession> request, + blink::mojom::PictureInPictureSessionObserverPtr observer, + gfx::Size* window_size) + : service_(service), + binding_(this, std::move(request)), + player_id_(player_id), + observer_(std::move(observer)) { + binding_.set_connection_error_handler(base::BindOnce( + &PictureInPictureSession::OnConnectionError, base::Unretained(this))); + + // TODO(mlamouri): figure out why this can be null and have the method return + // a const ref. + auto* controller = GetController(); + if (controller) + controller->SetActiveSession(this); + + *window_size = GetWebContentsImpl()->EnterPictureInPicture(surface_id.value(), + natural_size); + + if (controller) { + controller->SetAlwaysHidePlayPauseButton(show_play_pause_button); + controller->SetAlwaysHideMuteButton(show_mute_button); + } +} + +PictureInPictureSession::~PictureInPictureSession() { + DCHECK(is_stopping_); +} + +void PictureInPictureSession::Stop(StopCallback callback) { + StopInternal(std::move(callback)); +} + +void PictureInPictureSession::Update( + uint32_t player_id, + const base::Optional<viz::SurfaceId>& surface_id, + const gfx::Size& natural_size, + bool show_play_pause_button, + bool show_mute_button) { + player_id_ = MediaPlayerId(service_->render_frame_host_, player_id); + + // The PictureInPictureWindowController instance may not have been created by + // the embedder. + if (auto* pip_controller = GetController()) { + pip_controller->EmbedSurface(surface_id.value(), natural_size); + pip_controller->SetAlwaysHidePlayPauseButton(show_play_pause_button); + pip_controller->SetAlwaysHideMuteButton(show_mute_button); + pip_controller->SetActiveSession(this); + } +} + +void PictureInPictureSession::NotifyWindowResized(const gfx::Size& size) { + observer_->OnWindowSizeChanged(size); +} + +void PictureInPictureSession::Shutdown() { + if (is_stopping_) + return; + + StopInternal(base::DoNothing()); +} + +void PictureInPictureSession::StopInternal(StopCallback callback) { + DCHECK(!is_stopping_); + + is_stopping_ = true; + + GetWebContentsImpl()->ExitPictureInPicture(); + + std::move(callback).Run(); + + // TODO(mlamouri): move to observer_->Stop(); + player_id_->render_frame_host->Send( + new MediaPlayerDelegateMsg_EndPictureInPictureMode( + player_id_->render_frame_host->GetRoutingID(), + player_id_->delegate_id)); + + if (auto* controller = GetController()) + controller->SetActiveSession(nullptr); + + // Reset must happen after everything is done as it will destroy |this|. + service_->active_session_.reset(); +} + +void PictureInPictureSession::OnConnectionError() { + // StopInternal() will self destruct which will close the bindings. + StopInternal(base::DoNothing()); +} + +WebContentsImpl* PictureInPictureSession::GetWebContentsImpl() { + return static_cast<WebContentsImpl*>(service_->web_contents()); +} + +PictureInPictureWindowControllerImpl* PictureInPictureSession::GetController() { + return PictureInPictureWindowControllerImpl::GetOrCreateForWebContents( + GetWebContentsImpl()); +} + +} // namespace content
diff --git a/content/browser/picture_in_picture/picture_in_picture_session.h b/content/browser/picture_in_picture/picture_in_picture_session.h new file mode 100644 index 0000000..7d34db7 --- /dev/null +++ b/content/browser/picture_in_picture/picture_in_picture_session.h
@@ -0,0 +1,92 @@ +// 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 CONTENT_BROWSER_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_SESSION_H_ +#define CONTENT_BROWSER_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_SESSION_H_ + +#include "content/public/browser/media_player_id.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "third_party/blink/public/mojom/picture_in_picture/picture_in_picture.mojom.h" + +namespace content { + +class PictureInPictureServiceImpl; +class PictureInPictureWindowControllerImpl; +class WebContentsImpl; + +// The PicutreInPictureSession communicates with the +// PictureInPictureWindowController and the WebContents. It is created by the +// PictureInPictureService but deletes itself. When created, the session will +// enter Picture-in-Picture and when deleted, it will automatically exit +// Picture-in-Picture unless another session became active. +// The session MUST be stopped before its dtor runs to avoid unexpected +// deletion. +class PictureInPictureSession : public blink::mojom::PictureInPictureSession { + public: + PictureInPictureSession( + PictureInPictureServiceImpl* service, + const MediaPlayerId& player_id, + const base::Optional<viz::SurfaceId>& surface_id, + const gfx::Size& natural_size, + bool show_play_pause_button, + bool show_mute_button, + mojo::InterfaceRequest<blink::mojom::PictureInPictureSession> request, + blink::mojom::PictureInPictureSessionObserverPtr observer, + gfx::Size* window_size); + ~PictureInPictureSession() override; + + // blink::mojom::PictureInPictureSession interface. + void Stop(StopCallback callback) final; + void Update(uint32_t player_id, + const base::Optional<viz::SurfaceId>& surface_id, + const gfx::Size& natural_size, + bool show_play_pause_button, + bool show_mute_button) final; + + void NotifyWindowResized(const gfx::Size& size); + + // Returns the player that is currently in Picture-in-Picture. Returns nullopt + // if there are none. + const base::Optional<MediaPlayerId>& player_id() const { return player_id_; } + + // Shuts down the session. Called by the window controller when the window is + // closed. + void Shutdown(); + + private: + PictureInPictureSession() = delete; + + // Exits Picture-in-Picture, notifies the PictureInPictureWindowController of + // change of active session and deletes self. + void StopInternal(StopCallback callback); + + // Called when the |binding_| hits a connection error. + void OnConnectionError(); + + // Returns the WebContentsImpl associated with this Picture-in-Picture + // session. It relies on the WebContents associated with the |service_|. + WebContentsImpl* GetWebContentsImpl(); + + // Returns the PictureInPictureWindowControllerImpl associated with the + // WebContents. Can be null. + PictureInPictureWindowControllerImpl* GetController(); + + // Owns |this|. + PictureInPictureServiceImpl* service_; + + mojo::Binding<blink::mojom::PictureInPictureSession> binding_; + + base::Optional<MediaPlayerId> player_id_; + + // Whether the session is currently stopping. The final stop of stopping is to + // be destroyed so once its set to true it will never be set back to false and + // the dtor will check that it's stopping. + bool is_stopping_ = false; + + blink::mojom::PictureInPictureSessionObserverPtr observer_ = nullptr; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_SESSION_H_
diff --git a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc index dd91aa0..3a86ab1f 100644 --- a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc +++ b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc
@@ -9,7 +9,7 @@ #include "components/viz/common/surfaces/surface_id.h" #include "content/browser/media/media_web_contents_observer.h" #include "content/browser/media/session/media_session_impl.h" -#include "content/browser/picture_in_picture/picture_in_picture_service_impl.h" +#include "content/browser/picture_in_picture/picture_in_picture_session.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/common/media/media_player_delegate_messages.h" #include "content/public/browser/content_browser_client.h" @@ -50,8 +50,7 @@ return; initiator_->SetHasPictureInPictureVideo(false); - OnLeavingPictureInPicture(true /* should_pause_video */, - true /* should_reset_pip_player */); + OnLeavingPictureInPicture(true /* should_pause_video */); } PictureInPictureWindowControllerImpl::PictureInPictureWindowControllerImpl( @@ -95,24 +94,22 @@ return window_->GetBounds().size(); } -void PictureInPictureWindowControllerImpl::Close(bool should_pause_video, - bool should_reset_pip_player) { +void PictureInPictureWindowControllerImpl::Close(bool should_pause_video) { if (!window_ || !window_->IsVisible()) return; window_->Hide(); - CloseInternal(should_pause_video, should_reset_pip_player); + CloseInternal(should_pause_video); } void PictureInPictureWindowControllerImpl::CloseAndFocusInitiator() { - Close(false /* should_pause_video */, true /* should_reset_pip_player */); + Close(false /* should_pause_video */); initiator_->Activate(); } void PictureInPictureWindowControllerImpl::OnWindowDestroyed() { window_ = nullptr; - CloseInternal(true /* should_pause_video */, - true /* should_reset_pip_player */); + CloseInternal(true /* should_pause_video */); } void PictureInPictureWindowControllerImpl::EmbedSurface( @@ -140,15 +137,16 @@ } void PictureInPictureWindowControllerImpl::UpdateLayerBounds() { - if (media_player_id_.has_value() && service_ && window_ && + if (media_player_id_.has_value() && active_session_ && window_ && window_->IsVisible()) { - service_->NotifyWindowResized(window_->GetBounds().size()); + active_session_->NotifyWindowResized(window_->GetBounds().size()); } } bool PictureInPictureWindowControllerImpl::IsPlayerActive() { if (!media_player_id_.has_value()) - media_player_id_ = service_ ? service_->player_id() : base::nullopt; + media_player_id_ = + active_session_ ? active_session_->player_id() : base::nullopt; // At creation time, the player id may not be set. if (!media_player_id_.has_value()) @@ -229,11 +227,23 @@ } void PictureInPictureWindowControllerImpl::UpdateMediaPlayerId() { - media_player_id_ = service_ ? service_->player_id() : base::nullopt; + media_player_id_ = + active_session_ ? active_session_->player_id() : base::nullopt; UpdatePlaybackState(IsPlayerActive(), !media_player_id_.has_value()); UpdateMutedState(); } +void PictureInPictureWindowControllerImpl::SetActiveSession( + PictureInPictureSession* session) { + if (active_session_ == session) + return; + + if (active_session_) + active_session_->Shutdown(); + + active_session_ = session; +} + void PictureInPictureWindowControllerImpl::SetAlwaysHidePlayPauseButton( bool is_visible) { always_hide_play_pause_button_ = is_visible; @@ -376,8 +386,7 @@ } void PictureInPictureWindowControllerImpl::OnLeavingPictureInPicture( - bool should_pause_video, - bool should_reset_pip_player) { + bool should_pause_video) { if (IsPlayerActive() && should_pause_video) { // Pause the current video so there is only one video playing at a time. media_player_id_->render_frame_host->Send(new MediaPlayerDelegateMsg_Pause( @@ -386,27 +395,19 @@ } if (media_player_id_.has_value()) { - media_player_id_->render_frame_host->Send( - new MediaPlayerDelegateMsg_EndPictureInPictureMode( - media_player_id_->render_frame_host->GetRoutingID(), - media_player_id_->delegate_id)); - - if (should_reset_pip_player) { - DCHECK(service_); - service_->ResetPlayerId(); - media_player_id_.reset(); - } + active_session_->Shutdown(); + active_session_ = nullptr; + media_player_id_.reset(); } } void PictureInPictureWindowControllerImpl::CloseInternal( - bool should_pause_video, - bool should_reset_pip_player) { + bool should_pause_video) { if (initiator_->IsBeingDestroyed()) return; initiator_->SetHasPictureInPictureVideo(false); - OnLeavingPictureInPicture(should_pause_video, should_reset_pip_player); + OnLeavingPictureInPicture(should_pause_video); surface_id_ = viz::SurfaceId(); }
diff --git a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h index 2b070d9..166dfd74 100644 --- a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h +++ b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h
@@ -19,7 +19,7 @@ namespace content { class MediaWebContentsObserver; -class PictureInPictureServiceImpl; +class PictureInPictureSession; class WebContents; class WebContentsImpl; @@ -47,8 +47,7 @@ // PictureInPictureWindowController: CONTENT_EXPORT gfx::Size Show() override; - CONTENT_EXPORT void Close(bool should_pause_video, - bool should_reset_pip_player) override; + CONTENT_EXPORT void Close(bool should_pause_video) override; CONTENT_EXPORT void CloseAndFocusInitiator() override; CONTENT_EXPORT void OnWindowDestroyed() override; CONTENT_EXPORT void EmbedSurface(const viz::SurfaceId& surface_id, @@ -85,7 +84,11 @@ // state of this object. void UpdateMediaPlayerId(); - void set_service(PictureInPictureServiceImpl* service) { service_ = service; } + // Sets the active Picture-in-Picture session associated with the controller. + // This is different from the service's active session as there is one + // controller per WebContents and one service per RenderFrameHost. + // The current session may be shut down as a side effect of this. + void SetActiveSession(PictureInPictureSession* session); private: friend class WebContentsUserData<PictureInPictureWindowControllerImpl>; @@ -96,12 +99,11 @@ WebContents* initiator); // Signal to the media player that |this| is leaving Picture-in-Picture mode. - void OnLeavingPictureInPicture(bool should_pause_video, - bool should_reset_pip_player); + void OnLeavingPictureInPicture(bool should_pause_video); // Internal method to set the states after the window was closed, whether via // the system or Chromium. - void CloseInternal(bool should_pause_video, bool should_reset_pip_player); + void CloseInternal(bool should_pause_video); // Creates a new window if the previous one was destroyed. It can happen // because of the system control of the window. @@ -148,10 +150,11 @@ // origin trial is disabled. bool always_hide_mute_button_ = false; - // Service currently associated with the Picture-in-Picture window. The - // service makes the bridge with the renderer process by sending enter/exit - // requests. It is also holding the Picture-in-Picture MediaPlayerId. - PictureInPictureServiceImpl* service_ = nullptr; + // Session currently associated with the Picture-in-Picture window. The + // session object makes the bridge with the renderer process by handling + // requests and holding states such as the active player id. + // The session will be nullptr when there is no active session. + PictureInPictureSession* active_session_ = nullptr; WEB_CONTENTS_USER_DATA_KEY_DECL();
diff --git a/content/browser/service_worker/fake_service_worker.cc b/content/browser/service_worker/fake_service_worker.cc index 199ab56..bbc0a43 100644 --- a/content/browser/service_worker/fake_service_worker.cc +++ b/content/browser/service_worker/fake_service_worker.cc
@@ -147,6 +147,13 @@ NOTIMPLEMENTED(); } +void FakeServiceWorker::DispatchPeriodicSyncEvent( + const std::string& tag, + base::TimeDelta timeout, + DispatchSyncEventCallback callback) { + NOTIMPLEMENTED(); +} + void FakeServiceWorker::DispatchAbortPaymentEvent( payments::mojom::PaymentHandlerResponseCallbackPtr response_callback, DispatchAbortPaymentEventCallback callback) {
diff --git a/content/browser/service_worker/fake_service_worker.h b/content/browser/service_worker/fake_service_worker.h index ddf80fd..e565c4f 100644 --- a/content/browser/service_worker/fake_service_worker.h +++ b/content/browser/service_worker/fake_service_worker.h
@@ -86,6 +86,9 @@ bool last_chance, base::TimeDelta timeout, DispatchSyncEventCallback callback) override; + void DispatchPeriodicSyncEvent(const std::string& tag, + base::TimeDelta timeout, + DispatchSyncEventCallback callback) override; void DispatchAbortPaymentEvent( payments::mojom::PaymentHandlerResponseCallbackPtr response_callback, DispatchAbortPaymentEventCallback callback) override;
diff --git a/content/browser/service_worker/service_worker_metrics.cc b/content/browser/service_worker/service_worker_metrics.cc index 9e6ee70..f2ac9fe 100644 --- a/content/browser/service_worker/service_worker_metrics.cc +++ b/content/browser/service_worker/service_worker_metrics.cc
@@ -124,6 +124,8 @@ return "_LONG_RUNNING_MESSAGE"; case ServiceWorkerMetrics::EventType::BACKGROUND_FETCH_SUCCESS: return "_BACKGROUND_FETCH_SUCCESS"; + case ServiceWorkerMetrics::EventType::PERIODIC_SYNC: + return "_PERIODIC_SYNC"; } return "_UNKNOWN"; } @@ -238,6 +240,8 @@ return "Long Running Message"; case EventType::BACKGROUND_FETCH_SUCCESS: return "Background Fetch Success"; + case EventType::PERIODIC_SYNC: + return "Periodic Sync"; } NOTREACHED() << "Got unexpected event type: " << static_cast<int>(event_type); return "error"; @@ -572,6 +576,10 @@ // Since this event is expected to last indefinitely we don't need to log // how long they actually last. break; + case EventType::PERIODIC_SYNC: + UMA_HISTOGRAM_MEDIUM_TIMES( + "ServiceWorker.PeriodicBackgroundSyncEvent.Time", time); + break; case EventType::NAVIGATION_HINT: // The navigation hint should not be sent as an event.
diff --git a/content/browser/service_worker/service_worker_metrics.h b/content/browser/service_worker/service_worker_metrics.h index adc6a6a3..4bae11f 100644 --- a/content/browser/service_worker/service_worker_metrics.h +++ b/content/browser/service_worker/service_worker_metrics.h
@@ -175,8 +175,9 @@ COOKIE_CHANGE = 30, LONG_RUNNING_MESSAGE = 31, BACKGROUND_FETCH_SUCCESS = 32, + PERIODIC_SYNC = 33, // Add new events to record here. - kMaxValue = BACKGROUND_FETCH_SUCCESS, + kMaxValue = PERIODIC_SYNC, }; // Used for UMA. Append only.
diff --git a/content/browser/tracing/background_tracing_active_scenario.cc b/content/browser/tracing/background_tracing_active_scenario.cc index 81b3f458..f239682 100644 --- a/content/browser/tracing/background_tracing_active_scenario.cc +++ b/content/browser/tracing/background_tracing_active_scenario.cc
@@ -16,14 +16,8 @@ #include "content/browser/tracing/background_tracing_manager_impl.h" #include "content/browser/tracing/background_tracing_rule.h" #include "content/browser/tracing/tracing_controller_impl.h" -#include "content/public/common/service_manager_connection.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "mojo/public/cpp/system/data_pipe_drainer.h" -#include "services/service_manager/public/cpp/connector.h" -#include "services/tracing/public/cpp/perfetto/perfetto_config.h" #include "services/tracing/public/cpp/perfetto/trace_event_data_source.h" #include "services/tracing/public/cpp/tracing_features.h" -#include "services/tracing/public/mojom/constants.mojom.h" using base::trace_event::TraceConfig; using Metrics = content::BackgroundTracingManagerImpl::Metrics; @@ -56,216 +50,6 @@ BackgroundTracingManager::StartedFinalizingCallback callback_; }; -class BackgroundTracingActiveScenario::TracingSession { - public: - virtual ~TracingSession() = default; - virtual void BeginFinalizing(const base::RepeatingClosure& on_success, - const base::RepeatingClosure& on_failure) = 0; - virtual void AbortScenario( - const base::RepeatingClosure& on_abort_callback) = 0; -}; - -class PerfettoTracingSession - : public BackgroundTracingActiveScenario::TracingSession, - public tracing::mojom::TracingSessionClient, - public mojo::DataPipeDrainer::Client { - public: - PerfettoTracingSession(BackgroundTracingActiveScenario* parent_scenario, - const TraceConfig& chrome_config, - BackgroundTracingConfigImpl::CategoryPreset preset) - : parent_scenario_(parent_scenario), - category_preset_(preset), - raw_data_(std::make_unique<std::string>()) { -#if !defined(OS_ANDROID) - // TODO(crbug.com/941318): Re-enable startup tracing for Android once all - // Perfetto-related deadlocks are resolved. - if (!TracingControllerImpl::GetInstance()->IsTracing() && - tracing::TracingUsesPerfettoBackend()) { - tracing::TraceEventDataSource::GetInstance()->SetupStartupTracing( - /*privacy_filtering_enabled=*/true); - } -#endif - - ServiceManagerConnection::GetForProcess()->GetConnector()->BindInterface( - tracing::mojom::kServiceName, &consumer_host_); - - perfetto::TraceConfig perfetto_config = tracing::GetDefaultPerfettoConfig( - chrome_config, /*privacy_filtering_enabled=*/true); - - tracing::mojom::TracingSessionClientPtr tracing_session_client; - binding_.Bind(mojo::MakeRequest(&tracing_session_client)); - binding_.set_connection_error_handler( - base::BindOnce(&PerfettoTracingSession::OnTracingSessionEnded, - base::Unretained(this))); - - consumer_host_->EnableTracing( - mojo::MakeRequest(&tracing_session_host_), - std::move(tracing_session_client), std::move(perfetto_config), - tracing::mojom::TracingClientPriority::kBackground); - tracing_session_host_.set_connection_error_handler( - base::BindOnce(&PerfettoTracingSession::OnTracingSessionEnded, - base::Unretained(this))); - } - - // BackgroundTracingActiveScenario::TracingSession implementation. - void BeginFinalizing(const base::RepeatingClosure& on_success, - const base::RepeatingClosure& on_failure) override { - bool is_allowed_finalization = - BackgroundTracingManagerImpl::GetInstance()->IsAllowedFinalization(); - - if (!is_allowed_finalization) { - on_failure.Run(); - return; - } - - tracing_session_host_->DisableTracing(); - on_success.Run(); - } - - void AbortScenario(const base::RepeatingClosure& on_abort_callback) override { - on_abort_callback.Run(); - } - - // mojo::DataPipeDrainer::Client implementation: - void OnDataAvailable(const void* data, size_t num_bytes) override { - raw_data_->append(reinterpret_cast<const char*>(data), num_bytes); - } - - void OnDataComplete() override { - has_finished_receiving_data_ = true; - MaybeFinishedReceivingTrace(); - } - - // tracing::mojom::TracingSession implementation: - void OnTracingEnabled() override { - BackgroundTracingManagerImpl::GetInstance()->OnStartTracingDone( - category_preset_); - } - - void OnTracingDisabled() override { - mojo::ScopedDataPipeProducerHandle producer_handle; - mojo::ScopedDataPipeConsumerHandle consumer_handle; - - MojoResult result = - mojo::CreateDataPipe(nullptr, &producer_handle, &consumer_handle); - DCHECK_EQ(MOJO_RESULT_OK, result); - - drainer_ = std::make_unique<mojo::DataPipeDrainer>( - this, std::move(consumer_handle)); - tracing_session_host_->ReadBuffers( - std::move(producer_handle), - base::BindOnce(&PerfettoTracingSession::OnReadBuffersComplete, - base::Unretained(this))); - } - - void OnReadBuffersComplete() { - has_finished_read_buffers_ = true; - MaybeFinishedReceivingTrace(); - } - - void MaybeFinishedReceivingTrace() { - if (has_finished_read_buffers_ && has_finished_receiving_data_) { - DCHECK(raw_data_); - parent_scenario_->OnProtoDataComplete(std::move(raw_data_)); - } - } - - private: - void OnTracingSessionEnded() { parent_scenario_->AbortScenario(); } - - BackgroundTracingActiveScenario* const parent_scenario_; - mojo::Binding<tracing::mojom::TracingSessionClient> binding_{this}; - tracing::mojom::TracingSessionHostPtr tracing_session_host_; - std::unique_ptr<mojo::DataPipeDrainer> drainer_; - tracing::mojom::ConsumerHostPtr consumer_host_; - BackgroundTracingConfigImpl::CategoryPreset category_preset_; - std::unique_ptr<std::string> raw_data_; - bool has_finished_read_buffers_ = false; - bool has_finished_receiving_data_ = false; -}; - -class LegacyTracingSession - : public BackgroundTracingActiveScenario::TracingSession { - public: - LegacyTracingSession(BackgroundTracingActiveScenario* parent_scenario, - const TraceConfig& chrome_config, - BackgroundTracingConfigImpl::CategoryPreset preset) - : parent_scenario_(parent_scenario) { -#if !defined(OS_ANDROID) - // TODO(crbug.com/941318): Re-enable startup tracing for Android once all - // Perfetto-related deadlocks are resolved. - if (!TracingControllerImpl::GetInstance()->IsTracing() && - tracing::TracingUsesPerfettoBackend()) { - tracing::TraceEventDataSource::GetInstance()->SetupStartupTracing( - /*privacy_filtering_enabled=*/false); - } -#endif - - bool result = TracingControllerImpl::GetInstance()->StartTracing( - chrome_config, - base::BindOnce( - &BackgroundTracingManagerImpl::OnStartTracingDone, - base::Unretained(BackgroundTracingManagerImpl::GetInstance()), - preset)); - // We check IsEnabled() before creating the LegacyTracingSession, - // so any failures to start tracing at this point would be due to invalid - // configs which we treat as a failure scenario. - DCHECK(result); - } - - ~LegacyTracingSession() override { - DCHECK(!TracingControllerImpl::GetInstance()->IsTracing()); - } - - // BackgroundTracingActiveScenario::TracingSession implementation. - void BeginFinalizing(const base::RepeatingClosure& on_success, - const base::RepeatingClosure& on_failure) override { - if (!BackgroundTracingManagerImpl::GetInstance()->IsAllowedFinalization()) { - TracingControllerImpl::GetInstance()->StopTracing( - TracingControllerImpl::CreateCallbackEndpoint(base::BindRepeating( - [](const base::RepeatingClosure& on_failure, - std::unique_ptr<const base::DictionaryValue>, - base::RefCountedString*) { on_failure.Run(); }, - std::move(on_failure)))); - return; - } - - auto trace_data_endpoint = - TracingControllerImpl::CreateCompressedStringEndpoint( - TracingControllerImpl::CreateCallbackEndpoint(base::BindRepeating( - [](base::WeakPtr<BackgroundTracingActiveScenario> weak_this, - const base::RepeatingClosure& on_success, - std::unique_ptr<const base::DictionaryValue> metadata, - base::RefCountedString* file_contents) { - on_success.Run(); - if (weak_this) { - weak_this->OnJSONDataComplete(std::move(metadata), - file_contents); - } - }, - parent_scenario_->GetWeakPtr(), std::move(on_success))), - true /* compress_with_background_priority */); - - TracingControllerImpl::GetInstance()->StopTracing(trace_data_endpoint); - } - - void AbortScenario(const base::RepeatingClosure& on_abort_callback) override { - if (TracingControllerImpl::GetInstance()->IsTracing()) { - TracingControllerImpl::GetInstance()->StopTracing( - TracingControllerImpl::CreateCallbackEndpoint(base::BindRepeating( - [](const base::RepeatingClosure& on_abort_callback, - std::unique_ptr<const base::DictionaryValue>, - base::RefCountedString*) { on_abort_callback.Run(); }, - std::move(on_abort_callback)))); - } else { - on_abort_callback.Run(); - } - } - - private: - BackgroundTracingActiveScenario* const parent_scenario_; -}; - BackgroundTracingActiveScenario::BackgroundTracingActiveScenario( std::unique_ptr<BackgroundTracingConfigImpl> config, bool requires_anonymized_data, @@ -320,7 +104,6 @@ } if (scenario_state_ == State::kAborted) { - tracing_session_.reset(); std::move(on_aborted_callback_).Run(); } } @@ -335,11 +118,6 @@ rule_triggered_callback_for_testing_ = callback; } -base::WeakPtr<BackgroundTracingActiveScenario> -BackgroundTracingActiveScenario::GetWeakPtr() { - return weak_ptr_factory_.GetWeakPtr(); -} - void BackgroundTracingActiveScenario::StartTracingIfConfigNeedsIt() { DCHECK(config_); if (config_->tracing_mode() == BackgroundTracingConfigImpl::PREEMPTIVE) { @@ -354,45 +132,50 @@ void BackgroundTracingActiveScenario::StartTracing( BackgroundTracingConfigImpl::CategoryPreset preset, base::trace_event::TraceRecordMode record_mode) { - TraceConfig chrome_config = - BackgroundTracingConfigImpl::GetConfigForCategoryPreset(preset, - record_mode); + TraceConfig config = BackgroundTracingConfigImpl::GetConfigForCategoryPreset( + preset, record_mode); if (requires_anonymized_data_) - chrome_config.EnableArgumentFilter(); + config.EnableArgumentFilter(); #if defined(OS_ANDROID) // Set low trace buffer size on Android in order to upload small trace files. if (config_->tracing_mode() == BackgroundTracingConfigImpl::PREEMPTIVE) { - chrome_config.SetTraceBufferSizeInEvents(20000); - chrome_config.SetTraceBufferSizeInKb(500); + config.SetTraceBufferSizeInEvents(20000); + config.SetTraceBufferSizeInKb(500); + } +#else + // TODO(crbug.com/941318): Re-enable startup tracing for Android once all + // Perfetto-related deadlocks are resolved. + if (!TracingControllerImpl::GetInstance()->IsTracing() && + tracing::TracingUsesPerfettoBackend()) { + // TODO(oysteine): This should pass in |requires_anonymized_data_| instead + // of false only when using consumer API with proto output. But, for JSON + // output we still need this to be false since filtering happens in the JSON + // exporter. + tracing::TraceEventDataSource::GetInstance()->SetupStartupTracing( + /*privacy_filtering_enabled=*/false); } #endif - // If the tracing controller is tracing, i.e. DevTools or about://tracing, - // we don't start background tracing to not interfere with the user activity. - if (TracingControllerImpl::GetInstance()->IsTracing()) { + if (!TracingControllerImpl::GetInstance()->StartTracing( + config, + base::BindOnce( + &BackgroundTracingManagerImpl::OnStartTracingDone, + base::Unretained(BackgroundTracingManagerImpl::GetInstance()), + preset))) { AbortScenario(); return; } + SetState(State::kTracing); + // Activate the categories immediately. StartTracing eventually does this - // itself, but asynchronously via Mojo, and in the meantime events will be + // itself, but asynchronously via PostTask, and in the meantime events will be // dropped. This ensures that we start recording events for those categories // immediately. uint8_t modes = base::trace_event::TraceLog::RECORDING_MODE; - if (!chrome_config.event_filters().empty()) + if (!config.event_filters().empty()) modes |= base::trace_event::TraceLog::FILTERING_MODE; - base::trace_event::TraceLog::GetInstance()->SetEnabled(chrome_config, modes); - - DCHECK(!tracing_session_); - if (base::FeatureList::IsEnabled(features::kBackgroundTracingProtoOutput)) { - tracing_session_ = - std::make_unique<PerfettoTracingSession>(this, chrome_config, preset); - } else { - tracing_session_ = - std::make_unique<LegacyTracingSession>(this, chrome_config, preset); - } - - SetState(State::kTracing); + base::trace_event::TraceLog::GetInstance()->SetEnabled(config, modes); BackgroundTracingManagerImpl::RecordMetric(Metrics::RECORDING_ENABLED); } @@ -402,54 +185,56 @@ triggered_named_event_handle_ = -1; tracing_timer_.reset(); - auto on_begin_finalization_success = base::BindRepeating( - [](base::WeakPtr<BackgroundTracingActiveScenario> weak_this, - BackgroundTracingManager::StartedFinalizingCallback callback) { - if (!weak_this) { - return; - } + scoped_refptr<TracingControllerImpl::TraceDataEndpoint> trace_data_endpoint; + bool is_allowed_finalization = + BackgroundTracingManagerImpl::GetInstance()->IsAllowedFinalization(); + base::RepeatingClosure started_finalizing_closure; + if (!callback.is_null()) { + started_finalizing_closure = + base::BindRepeating(callback, is_allowed_finalization); + } - weak_this->SetState(State::kFinalizing); - BackgroundTracingManagerImpl::RecordMetric( - Metrics::FINALIZATION_ALLOWED); - DCHECK(!weak_this->started_finalizing_closure_); - if (!callback.is_null()) { - weak_this->started_finalizing_closure_ = - base::BindOnce(callback, /*is_allowed_finalization=*/true); - } - }, - weak_ptr_factory_.GetWeakPtr(), callback); + if (is_allowed_finalization) { + trace_data_endpoint = TracingControllerImpl::CreateCompressedStringEndpoint( + TracingControllerImpl::CreateCallbackEndpoint(base::BindRepeating( + &BackgroundTracingActiveScenario::OnTracingStopped, + weak_ptr_factory_.GetWeakPtr(), + std::move(started_finalizing_closure))), + true /* compress_with_background_priority */); + BackgroundTracingManagerImpl::RecordMetric(Metrics::FINALIZATION_ALLOWED); + } else { + trace_data_endpoint = + TracingControllerImpl::CreateCallbackEndpoint(base::BindRepeating( + [](base::RepeatingClosure closure, + base::WeakPtr<BackgroundTracingActiveScenario> active_scenario, + std::unique_ptr<const base::DictionaryValue> metadata, + base::RefCountedString* file_contents) { + if (active_scenario) { + active_scenario->SetState(State::kAborted); + } - auto on_begin_finalization_failure = base::BindRepeating( - [](base::WeakPtr<BackgroundTracingActiveScenario> weak_this, - BackgroundTracingManager::StartedFinalizingCallback callback) { - if (!weak_this) { - return; - } + if (closure) { + std::move(closure).Run(); + } + }, + std::move(started_finalizing_closure), + weak_ptr_factory_.GetWeakPtr())); + BackgroundTracingManagerImpl::RecordMetric( + Metrics::FINALIZATION_DISALLOWED); + } - BackgroundTracingManagerImpl::RecordMetric( - Metrics::FINALIZATION_DISALLOWED); - weak_this->SetState(State::kAborted); - - if (!callback.is_null()) { - callback.Run(false); - } - }, - weak_ptr_factory_.GetWeakPtr(), callback); - - tracing_session_->BeginFinalizing(std::move(on_begin_finalization_success), - std::move(on_begin_finalization_failure)); + TracingControllerImpl::GetInstance()->StopTracing(trace_data_endpoint); } -void BackgroundTracingActiveScenario::OnJSONDataComplete( +void BackgroundTracingActiveScenario::OnTracingStopped( + base::RepeatingClosure started_finalizing_closure, std::unique_ptr<const base::DictionaryValue> metadata, base::RefCountedString* file_contents) { + SetState(State::kFinalizing); BackgroundTracingManagerImpl::RecordMetric(Metrics::FINALIZATION_STARTED); UMA_HISTOGRAM_MEMORY_KB("Tracing.Background.FinalizingTraceSizeInKB", file_contents->size() / 1024); - // Send the finalized and compressed tracing data to the destination - // callback. if (!receive_callback_.is_null()) { receive_callback_.Run( file_contents, std::move(metadata), @@ -457,22 +242,8 @@ weak_ptr_factory_.GetWeakPtr())); } - if (started_finalizing_closure_) { - std::move(started_finalizing_closure_).Run(); - } -} - -void BackgroundTracingActiveScenario::OnProtoDataComplete( - std::unique_ptr<std::string> proto_trace) { - BackgroundTracingManagerImpl::RecordMetric(Metrics::FINALIZATION_STARTED); - UMA_HISTOGRAM_MEMORY_KB("Tracing.Background.FinalizingTraceSizeInKB", - proto_trace->size() / 1024); - - BackgroundTracingManagerImpl::GetInstance()->SetTraceToUpload( - std::move(proto_trace)); - - if (started_finalizing_closure_) { - std::move(started_finalizing_closure_).Run(); + if (!started_finalizing_closure.is_null()) { + std::move(started_finalizing_closure).Run(); } } @@ -483,7 +254,6 @@ BackgroundTracingManagerImpl::RecordMetric(Metrics::UPLOAD_FAILED); } - tracing_session_.reset(); SetState(State::kIdle); // Now that a trace has completed, we may need to enable recording again. @@ -491,18 +261,24 @@ } void BackgroundTracingActiveScenario::AbortScenario() { - if (tracing_session_) { - tracing_session_->AbortScenario(base::BindRepeating( - [](base::WeakPtr<BackgroundTracingActiveScenario> weak_this) { - if (weak_this) { - weak_this->SetState(State::kAborted); - } - }, - weak_ptr_factory_.GetWeakPtr())); - } else { + if ((state() != State::kTracing)) { // Setting the kAborted state will cause |this| to be destroyed. SetState(State::kAborted); + return; } + + auto trace_data_endpoint = + TracingControllerImpl::CreateCallbackEndpoint(base::BindRepeating( + [](base::WeakPtr<BackgroundTracingActiveScenario> active_scenario, + std::unique_ptr<const base::DictionaryValue>, + base::RefCountedString*) { + if (active_scenario) { + active_scenario->SetState(State::kAborted); + } + }, + weak_ptr_factory_.GetWeakPtr())); + + TracingControllerImpl::GetInstance()->StopTracing(trace_data_endpoint); } void BackgroundTracingActiveScenario::TriggerNamedEvent( @@ -595,10 +371,6 @@ BackgroundTracingManagerImpl::RecordMetric(Metrics::PREEMPTIVE_TRIGGERED); } - // Make a copy of the callback in case BeginFinalizing() ends up aborting the - // scenario and |this| gets deleted. - auto rule_triggered_callback_for_testing = - rule_triggered_callback_for_testing_; if (trace_delay < 0) { BeginFinalizing(std::move(callback)); } else { @@ -606,8 +378,8 @@ tracing_timer_->StartTimer(trace_delay); } - if (!rule_triggered_callback_for_testing.is_null()) { - rule_triggered_callback_for_testing.Run(); + if (!rule_triggered_callback_for_testing_.is_null()) { + rule_triggered_callback_for_testing_.Run(); } }
diff --git a/content/browser/tracing/background_tracing_active_scenario.h b/content/browser/tracing/background_tracing_active_scenario.h index 67bbc25..e64cb0f 100644 --- a/content/browser/tracing/background_tracing_active_scenario.h +++ b/content/browser/tracing/background_tracing_active_scenario.h
@@ -11,9 +11,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "content/browser/tracing/background_tracing_config_impl.h" -#include "content/browser/tracing/tracing_controller_impl.h" #include "content/public/browser/background_tracing_manager.h" -#include "services/tracing/public/mojom/perfetto_service.mojom.h" namespace base { class RefCountedString; @@ -26,14 +24,13 @@ class BackgroundTracingActiveScenario { public: enum class State { kIdle, kTracing, kFinalizing, kUploading, kAborted }; - class TracingSession; BackgroundTracingActiveScenario( std::unique_ptr<BackgroundTracingConfigImpl> config, bool requires_anonymized_data, BackgroundTracingManager::ReceiveCallback receive_callback, base::OnceClosure on_aborted_callback); - virtual ~BackgroundTracingActiveScenario(); + ~BackgroundTracingActiveScenario(); void StartTracingIfConfigNeedsIt(); void AbortScenario(); @@ -42,7 +39,6 @@ void GenerateMetadataDict(base::DictionaryValue* metadata_dict); State state() const { return scenario_state_; } bool requires_anonymized_data() const { return requires_anonymized_data_; } - base::WeakPtr<BackgroundTracingActiveScenario> GetWeakPtr(); void TriggerNamedEvent( BackgroundTracingManager::TriggerHandle handle, @@ -52,16 +48,6 @@ const BackgroundTracingRule* triggered_rule, BackgroundTracingManager::StartedFinalizingCallback callback); - // Called by LegacyTracingSession when the final trace data is ready. - void OnJSONDataComplete(std::unique_ptr<const base::DictionaryValue> metadata, - base::RefCountedString*); - // Called by the PerfettoTracingSession when the proto trace is ready. - void OnProtoDataComplete(std::unique_ptr<std::string> proto_trace); - - // Called when the finalized trace data has been uploaded/transferred away - // from the background tracing system. - void OnFinalizeComplete(bool success); - // For testing CONTENT_EXPORT void FireTimerForTesting(); CONTENT_EXPORT void SetRuleTriggeredCallbackForTesting( @@ -70,15 +56,20 @@ private: void StartTracing(BackgroundTracingConfigImpl::CategoryPreset, base::trace_event::TraceRecordMode); + void BeginFinalizing( BackgroundTracingManager::StartedFinalizingCallback callback); + void OnTracingStopped(base::RepeatingClosure started_finalizing_closure, + std::unique_ptr<const base::DictionaryValue> metadata, + base::RefCountedString*); + + void OnFinalizeComplete(bool success); BackgroundTracingRule* GetRuleAbleToTriggerTracing( const std::string& trigger_name); void SetState(State new_state); - std::unique_ptr<TracingSession> tracing_session_; std::unique_ptr<BackgroundTracingConfigImpl> config_; bool requires_anonymized_data_; State scenario_state_; @@ -87,7 +78,6 @@ BackgroundTracingManager::ReceiveCallback receive_callback_; BackgroundTracingManager::TriggerHandle triggered_named_event_handle_; base::OnceClosure on_aborted_callback_; - base::OnceClosure started_finalizing_closure_; class TracingTimer; std::unique_ptr<TracingTimer> tracing_timer_;
diff --git a/content/browser/tracing/background_tracing_manager_browsertest.cc b/content/browser/tracing/background_tracing_manager_browsertest.cc index 7f2ab1b..6e4b2c5 100644 --- a/content/browser/tracing/background_tracing_manager_browsertest.cc +++ b/content/browser/tracing/background_tracing_manager_browsertest.cc
@@ -16,11 +16,8 @@ #include "base/run_loop.h" #include "base/strings/pattern.h" #include "base/task/post_task.h" -#include "base/test/scoped_feature_list.h" -#include "base/test/test_timeouts.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" -#include "content/browser/devtools/protocol/devtools_protocol_test_support.h" #include "content/browser/tracing/background_startup_tracing_observer.h" #include "content/browser/tracing/background_tracing_active_scenario.h" #include "content/browser/tracing/background_tracing_manager_impl.h" @@ -31,7 +28,6 @@ #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" #include "content/public/test/test_utils.h" -#include "services/tracing/public/cpp/tracing_features.h" #include "third_party/zlib/zlib.h" using base::trace_event::TraceLog; @@ -52,21 +48,6 @@ bool enabled_ = false; }; -// Wait until |condition| returns true. -void WaitForCondition(base::RepeatingCallback<bool()> condition, - const std::string& description) { - const base::TimeDelta kTimeout = base::TimeDelta::FromSeconds(30); - const base::TimeTicks start_time = base::TimeTicks::Now(); - while (!condition.Run() && (base::TimeTicks::Now() - start_time < kTimeout)) { - base::RunLoop run_loop; - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout()); - run_loop.Run(); - } - ASSERT_TRUE(condition.Run()) - << "Timeout waiting for condition: " << description; -} - // An helper class that observes tracing states transition and allows // synchronisation with tests. The class adds itself as a tracelog // enable state observer and provides methods to wait for a given state. @@ -376,7 +357,7 @@ handle, trigger_helper.receive_closure(true)); trace_receiver_helper.WaitForTraceReceived(); - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + BackgroundTracingManager::GetInstance()->AbortScenario(); background_tracing_helper.WaitForScenarioAborted(); EXPECT_TRUE(trace_receiver_helper.trace_received()); @@ -407,7 +388,7 @@ handle, trigger_helper.receive_closure(false)); trace_receiver_helper.WaitForTraceReceived(); - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + BackgroundTracingManager::GetInstance()->AbortScenario(); background_tracing_helper.WaitForScenarioAborted(); EXPECT_TRUE(trace_receiver_helper.trace_received()); @@ -441,7 +422,7 @@ trigger_helper.WaitForTriggerReceived(); trace_receiver_helper.WaitForTraceReceived(); - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + BackgroundTracingManager::GetInstance()->AbortScenario(); background_tracing_helper.WaitForScenarioAborted(); EXPECT_TRUE(trace_receiver_helper.trace_received()); @@ -488,7 +469,7 @@ trigger_helper.WaitForTriggerReceived(); trace_receiver_helper.WaitForTraceReceived(); - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + BackgroundTracingManager::GetInstance()->AbortScenario(); background_tracing_helper.WaitForScenarioAborted(); EXPECT_TRUE(trace_receiver_helper.trace_received()); @@ -519,7 +500,7 @@ handle, trigger_helper.receive_closure(true)); trace_receiver_helper.WaitForTraceReceived(); - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + BackgroundTracingManager::GetInstance()->AbortScenario(); background_tracing_helper.WaitForScenarioAborted(); EXPECT_TRUE(trace_receiver_helper.trace_received()); @@ -558,7 +539,7 @@ handle, trigger_helper.receive_closure(true)); trace_receiver_helper.WaitForTraceReceived(); - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + BackgroundTracingManager::GetInstance()->AbortScenario(); background_tracing_helper.WaitForScenarioAborted(); EXPECT_TRUE(trace_receiver_helper.trace_received()); @@ -617,7 +598,7 @@ handle2, trigger_helper.receive_closure(false)); trace_receiver_helper.WaitForTraceReceived(); - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + BackgroundTracingManager::GetInstance()->AbortScenario(); background_tracing_helper.WaitForScenarioAborted(); EXPECT_TRUE(trace_receiver_helper.trace_received()); @@ -681,7 +662,7 @@ trace_receiver_helper.WaitForTraceReceived(); - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + BackgroundTracingManager::GetInstance()->AbortScenario(); background_tracing_helper.WaitForScenarioAborted(); EXPECT_TRUE(trace_receiver_helper.trace_received()); @@ -724,7 +705,7 @@ handle, trigger_helper.receive_closure(false)); // Abort the scenario. - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + BackgroundTracingManager::GetInstance()->AbortScenario(); background_tracing_helper.WaitForScenarioAborted(); EXPECT_FALSE(trace_receiver_helper.trace_received()); @@ -756,7 +737,7 @@ handle, trigger_helper.receive_closure(false)); // Abort the scenario. - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + BackgroundTracingManager::GetInstance()->AbortScenario(); background_tracing_helper.WaitForScenarioAborted(); EXPECT_FALSE(trace_receiver_helper.trace_received()); @@ -802,7 +783,7 @@ handle, trigger_helper.receive_closure(false)); // Abort the scenario. - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + BackgroundTracingManager::GetInstance()->AbortScenario(); background_tracing_helper.WaitForScenarioAborted(); EXPECT_FALSE(trace_receiver_helper.trace_received()); @@ -848,7 +829,7 @@ trigger_helper.WaitForTriggerReceived(); // Abort the scenario. - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + BackgroundTracingManager::GetInstance()->AbortScenario(); background_tracing_helper.WaitForScenarioAborted(); EXPECT_FALSE(trace_receiver_helper.trace_received()); @@ -891,7 +872,7 @@ LOCAL_HISTOGRAM_COUNTS("fake", 2); trace_receiver_helper.WaitForTraceReceived(); - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + BackgroundTracingManager::GetInstance()->AbortScenario(); background_tracing_helper.WaitForScenarioAborted(); EXPECT_TRUE(trace_receiver_helper.trace_received()); @@ -936,7 +917,7 @@ trace_receiver_helper.WaitForTraceReceived(); // Abort the scenario. - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + BackgroundTracingManager::GetInstance()->AbortScenario(); background_tracing_helper.WaitForScenarioAborted(); EXPECT_TRUE(trace_receiver_helper.trace_received()); @@ -980,7 +961,7 @@ LOCAL_HISTOGRAM_COUNTS("fake", 0); // Abort the scenario. - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + BackgroundTracingManager::GetInstance()->AbortScenario(); background_tracing_helper.WaitForScenarioAborted(); EXPECT_FALSE(trace_receiver_helper.trace_received()); @@ -1025,7 +1006,7 @@ LOCAL_HISTOGRAM_COUNTS("fake", 0); // Abort the scenario. - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + BackgroundTracingManager::GetInstance()->AbortScenario(); background_tracing_helper.WaitForScenarioAborted(); EXPECT_FALSE(trace_receiver_helper.trace_received()); @@ -1079,7 +1060,7 @@ ->FireTimerForTesting(); trace_receiver_helper.WaitForTraceReceived(); - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + BackgroundTracingManager::GetInstance()->AbortScenario(); background_tracing_helper.WaitForScenarioAborted(); EXPECT_TRUE(trace_receiver_helper.trace_received()); @@ -1109,7 +1090,7 @@ handle, trigger_helper.receive_closure(true)); trace_receiver_helper.WaitForTraceReceived(); - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + BackgroundTracingManager::GetInstance()->AbortScenario(); background_tracing_helper.WaitForScenarioAborted(); EXPECT_TRUE(trace_receiver_helper.trace_received()); @@ -1154,7 +1135,7 @@ EXPECT_TRUE(trace_receiver_helper.trace_received(1)); // Abort the scenario. - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + BackgroundTracingManager::GetInstance()->AbortScenario(); background_tracing_helper.WaitForScenarioAborted(); } @@ -1219,7 +1200,7 @@ handle1, trigger_helper.receive_closure(true)); trace_receiver_helper.WaitForTraceReceived(); - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + BackgroundTracingManager::GetInstance()->AbortScenario(); background_tracing_helper.WaitForScenarioAborted(); EXPECT_TRUE(trace_receiver_helper.trace_received()); @@ -1254,7 +1235,7 @@ handle, trigger_helper.receive_closure(false)); trace_receiver_helper.WaitForTraceReceived(); - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + BackgroundTracingManager::GetInstance()->AbortScenario(); background_tracing_helper.WaitForScenarioAborted(); EXPECT_TRUE(trace_receiver_helper.trace_received()); @@ -1314,7 +1295,7 @@ ->FireTimerForTesting(); trace_receiver_helper.WaitForTraceReceived(); - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + BackgroundTracingManager::GetInstance()->AbortScenario(); background_tracing_helper.WaitForScenarioAborted(); EXPECT_TRUE(trace_receiver_helper.trace_received()); @@ -1362,7 +1343,7 @@ EXPECT_TRUE(preferences->GetBackgroundStartupTracingEnabled()); // Abort the scenario. - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + BackgroundTracingManager::GetInstance()->AbortScenario(); background_tracing_helper.WaitForScenarioAborted(); EXPECT_FALSE(trace_receiver_helper.trace_received()); @@ -1421,85 +1402,11 @@ ->FireTimerForTesting(); trace_receiver_helper.WaitForTraceReceived(); - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); + BackgroundTracingManager::GetInstance()->AbortScenario(); background_tracing_helper.WaitForScenarioAborted(); EXPECT_TRUE(trace_receiver_helper.trace_received()); EXPECT_FALSE(preferences->GetBackgroundStartupTracingEnabled()); } -namespace { - -class ProtoBackgroundTracingTest : public DevToolsProtocolTest { - public: - ProtoBackgroundTracingTest() { - scoped_feature_list_.InitWithFeatures( - /*enabled_features=*/{features::kTracingPerfettoBackend, - features::kBackgroundTracingProtoOutput}, - /*disabled_features=*/{}); - } - - private: - base::test::ScopedFeatureList scoped_feature_list_; -}; - -} // namespace - -IN_PROC_BROWSER_TEST_F(ProtoBackgroundTracingTest, - DevtoolsInterruptsBackgroundTracing) { - TestBackgroundTracingHelper background_tracing_helper; - TestTraceReceiverHelper trace_receiver_helper; - - std::unique_ptr<BackgroundTracingConfig> config = CreatePreemptiveConfig(); - - EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario( - std::move(config), trace_receiver_helper.get_receive_callback(), - BackgroundTracingManager::NO_DATA_FILTERING)); - - background_tracing_helper.WaitForTracingEnabled(); - - NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1); - Attach(); - - base::Value* start_tracing_result = - SendCommand("Tracing.start", nullptr, true); - ASSERT_TRUE(start_tracing_result); - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); - background_tracing_helper.WaitForScenarioAborted(); -} - -IN_PROC_BROWSER_TEST_F(ProtoBackgroundTracingTest, ProtoTraceReceived) { - TestBackgroundTracingHelper background_tracing_helper; - - std::unique_ptr<BackgroundTracingConfig> config = CreatePreemptiveConfig(); - - BackgroundTracingManager::TriggerHandle handle = - BackgroundTracingManager::GetInstance()->RegisterTriggerType( - "preemptive_test"); - - EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario( - std::move(config), base::DoNothing(), - BackgroundTracingManager::NO_DATA_FILTERING)); - - background_tracing_helper.WaitForTracingEnabled(); - - TestTriggerHelper trigger_helper; - BackgroundTracingManager::GetInstance()->TriggerNamedEvent( - handle, trigger_helper.receive_closure(true)); - - WaitForCondition( - base::BindRepeating([]() { - return BackgroundTracingManager::GetInstance()->HasTraceToUpload(); - }), - "trace received"); - - std::string trace_data = - BackgroundTracingManager::GetInstance()->GetLatestTraceToUpload(); - - BackgroundTracingManager::GetInstance()->AbortScenarioForTesting(); - background_tracing_helper.WaitForScenarioAborted(); - - EXPECT_TRUE(!trace_data.empty()); -} - } // namespace content
diff --git a/content/browser/tracing/background_tracing_manager_impl.cc b/content/browser/tracing/background_tracing_manager_impl.cc index 055bafc..8bb32561 100644 --- a/content/browser/tracing/background_tracing_manager_impl.cc +++ b/content/browser/tracing/background_tracing_manager_impl.cc
@@ -162,19 +162,18 @@ } bool BackgroundTracingManagerImpl::HasTraceToUpload() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - return !trace_to_upload_.empty(); + // TODO(oysteine): This should return the collected trace once we have the new + // coordinator API to collect protos. https://crbug.com/925142. + // Note: This can be called on any thread and needs to be thread safe. + return !trace_to_upload_for_testing_.empty(); } std::string BackgroundTracingManagerImpl::GetLatestTraceToUpload() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); + // TODO(oysteine): This should return the collected trace once we have the new + // coordinator API to collect protos. https://crbug.com/925142. + // Note: This can be called on any thread and needs to be thread safe. std::string ret; - ret.swap(trace_to_upload_); - - if (active_scenario_) { - active_scenario_->OnFinalizeComplete(true); - } - + ret.swap(trace_to_upload_for_testing_); return ret; } @@ -242,18 +241,8 @@ } void BackgroundTracingManagerImpl::SetTraceToUploadForTesting( - std::unique_ptr<std::string> trace_data) { - SetTraceToUpload(std::move(trace_data)); -} - -void BackgroundTracingManagerImpl::SetTraceToUpload( - std::unique_ptr<std::string> trace_data) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (trace_data) { - trace_to_upload_.swap(*trace_data); - } else { - trace_to_upload_.clear(); - } + base::StringPiece data) { + trace_to_upload_for_testing_ = data.data(); } void BackgroundTracingManagerImpl::ValidateStartupScenario() { @@ -326,6 +315,7 @@ return static_cast<TriggerHandle>(trigger_handle_ids_); } + bool BackgroundTracingManagerImpl::IsTriggerHandleValid( BackgroundTracingManager::TriggerHandle handle) const { return trigger_handles_.find(handle) != trigger_handles_.end(); @@ -378,10 +368,6 @@ return metadata_dict; } -void BackgroundTracingManagerImpl::AbortScenarioForTesting() { - AbortScenario(); -} - void BackgroundTracingManagerImpl::AbortScenario() { if (active_scenario_) { active_scenario_->AbortScenario();
diff --git a/content/browser/tracing/background_tracing_manager_impl.h b/content/browser/tracing/background_tracing_manager_impl.h index b021c54..1c50eb5 100644 --- a/content/browser/tracing/background_tracing_manager_impl.h +++ b/content/browser/tracing/background_tracing_manager_impl.h
@@ -78,7 +78,7 @@ bool SetActiveScenario(std::unique_ptr<BackgroundTracingConfig>, ReceiveCallback, DataFiltering data_filtering) override; - void AbortScenario(); + CONTENT_EXPORT void AbortScenario() override; bool HasActiveScenario() override; // Named triggers @@ -92,7 +92,6 @@ StartedFinalizingCallback callback); bool HasTraceToUpload() override; std::string GetLatestTraceToUpload() override; - void SetTraceToUpload(std::unique_ptr<std::string> trace_data); // Add/remove EnabledStateObserver. CONTENT_EXPORT void AddEnabledStateObserver(EnabledStateObserver* observer); @@ -117,9 +116,9 @@ CONTENT_EXPORT void InvalidateTriggerHandlesForTesting(); CONTENT_EXPORT bool IsTracingForTesting(); void WhenIdle(IdleCallback idle_callback) override; - CONTENT_EXPORT void AbortScenarioForTesting() override; + CONTENT_EXPORT void SetTraceToUploadForTesting( - std::unique_ptr<std::string> trace_data) override; + base::StringPiece data) override; private: friend class base::NoDestructor<BackgroundTracingManagerImpl>; @@ -148,9 +147,8 @@ IdleCallback idle_callback_; base::RepeatingClosure tracing_enabled_callback_for_testing_; - // This field contains serialized trace log proto. - std::string trace_to_upload_; + std::string trace_to_upload_for_testing_; DISALLOW_COPY_AND_ASSIGN(BackgroundTracingManagerImpl); };
diff --git a/content/browser/webauth/DEPS b/content/browser/webauth/DEPS index 8d0f2ca5a..3030fce 100644 --- a/content/browser/webauth/DEPS +++ b/content/browser/webauth/DEPS
@@ -1,3 +1,9 @@ include_rules = [ - "+device", + "+device", ] + +specific_include_rules = { + "authenticator_impl_unittest\.cc": [ + "+components/autofill/content/browser/webauthn/internal_authenticator_impl.h" + ] +}
diff --git a/content/browser/webauth/authenticator_impl_unittest.cc b/content/browser/webauth/authenticator_impl_unittest.cc index ed20989..8d292a1 100644 --- a/content/browser/webauth/authenticator_impl_unittest.cc +++ b/content/browser/webauth/authenticator_impl_unittest.cc
@@ -27,6 +27,7 @@ #include "base/time/time.h" #include "base/timer/timer.h" #include "build/build_config.h" +#include "components/autofill/content/browser/webauthn/internal_authenticator_impl.h" #include "components/cbor/reader.h" #include "components/cbor/values.h" #include "content/browser/webauth/authenticator_common.h" @@ -77,6 +78,7 @@ using blink::mojom::CableAuthentication; using blink::mojom::CableAuthenticationPtr; using blink::mojom::GetAssertionAuthenticatorResponsePtr; +using blink::mojom::InternalAuthenticatorPtr; using blink::mojom::MakeCredentialAuthenticatorResponsePtr; using blink::mojom::PublicKeyCredentialCreationOptions; using blink::mojom::PublicKeyCredentialCreationOptionsPtr; @@ -3754,4 +3756,174 @@ } #endif // defined(OS_WIN) +class InternalAuthenticatorImplTest + : public content::RenderViewHostTestHarness { + public: + InternalAuthenticatorImplTest() = default; + + protected: + void TearDown() override { + // The |RenderFrameHost| must outlive |AuthenticatorImpl|. + internal_authenticator_impl_.reset(); + content::RenderViewHostTestHarness::TearDown(); + } + + void NavigateAndCommit(const GURL& url) { + // The |RenderFrameHost| must outlive |AuthenticatorImpl|. + internal_authenticator_impl_.reset(); + content::RenderViewHostTestHarness::NavigateAndCommit(url); + } + + InternalAuthenticatorPtr ConnectToAuthenticator(GURL effective_origin_url) { + internal_authenticator_impl_ = std::make_unique<InternalAuthenticatorImpl>( + main_rfh(), url::Origin::Create(effective_origin_url)); + InternalAuthenticatorPtr authenticator; + internal_authenticator_impl_->Bind(mojo::MakeRequest(&authenticator)); + return authenticator; + } + + InternalAuthenticatorPtr ConnectToAuthenticator( + GURL effective_origin_url, + service_manager::Connector* connector, + std::unique_ptr<base::OneShotTimer> timer) { + internal_authenticator_impl_.reset(new InternalAuthenticatorImpl( + main_rfh(), url::Origin::Create(effective_origin_url), + std::make_unique<AuthenticatorCommon>(main_rfh(), connector, + std::move(timer)))); + InternalAuthenticatorPtr authenticator; + internal_authenticator_impl_->Bind(mojo::MakeRequest(&authenticator)); + return authenticator; + } + + InternalAuthenticatorPtr ConstructAuthenticatorWithTimer( + GURL effective_origin_url, + scoped_refptr<base::TestMockTimeTaskRunner> task_runner) { + connector_ = service_manager::Connector::Create(&request_); + fake_hid_manager_ = std::make_unique<device::FakeHidManager>(); + connector_->OverrideBinderForTesting( + service_manager::ServiceFilter::ByName(device::mojom::kServiceName), + device::mojom::HidManager::Name_, + base::BindRepeating(&device::FakeHidManager::AddBinding, + base::Unretained(fake_hid_manager_.get()))); + + // Set up a timer for testing. + auto timer = + std::make_unique<base::OneShotTimer>(task_runner->GetMockTickClock()); + timer->SetTaskRunner(task_runner); + return ConnectToAuthenticator(effective_origin_url, connector_.get(), + std::move(timer)); + } + + protected: + std::unique_ptr<InternalAuthenticatorImpl> internal_authenticator_impl_; + service_manager::mojom::ConnectorRequest request_; + std::unique_ptr<service_manager::Connector> connector_; + std::unique_ptr<device::FakeHidManager> fake_hid_manager_; +}; + +// Verify behavior for various combinations of origins and RP IDs. +TEST_F(InternalAuthenticatorImplTest, MakeCredentialOriginAndRpIds) { + // These instances should return security errors (for circumstances + // that would normally crash the renderer). + for (auto test_case : kInvalidRelyingPartyTestCases) { + SCOPED_TRACE(std::string(test_case.claimed_authority) + " " + + std::string(test_case.origin)); + + GURL origin = GURL(test_case.origin); + if (url::Origin::Create(origin).opaque()) { + // Opaque origins will cause DCHECK to fail. + continue; + } + + NavigateAndCommit(origin); + InternalAuthenticatorPtr authenticator = ConnectToAuthenticator(origin); + PublicKeyCredentialCreationOptionsPtr options = + GetTestPublicKeyCredentialCreationOptions(); + options->relying_party->id = test_case.claimed_authority; + TestMakeCredentialCallback callback_receiver; + authenticator->MakeCredential(std::move(options), + callback_receiver.callback()); + callback_receiver.WaitForCallback(); + EXPECT_EQ(AuthenticatorStatus::INVALID_DOMAIN, callback_receiver.status()); + } + + // These instances should bypass security errors, by setting the effective + // origin to a valid one. + for (auto test_case : kValidRelyingPartyTestCases) { + SCOPED_TRACE(std::string(test_case.claimed_authority) + " " + + std::string(test_case.origin)); + + NavigateAndCommit(GURL("https://this.isthewrong.origin")); + auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>( + base::Time::Now(), base::TimeTicks::Now()); + auto authenticator = + ConstructAuthenticatorWithTimer(GURL(test_case.origin), task_runner); + PublicKeyCredentialCreationOptionsPtr options = + GetTestPublicKeyCredentialCreationOptions(); + options->relying_party->id = test_case.claimed_authority; + + device::test::ScopedVirtualFidoDevice virtual_device; + TestMakeCredentialCallback callback_receiver; + authenticator->MakeCredential(std::move(options), + callback_receiver.callback()); + callback_receiver.WaitForCallback(); + EXPECT_EQ(AuthenticatorStatus::SUCCESS, callback_receiver.status()); + } +} + +// Verify behavior for various combinations of origins and RP IDs. +TEST_F(InternalAuthenticatorImplTest, GetAssertionOriginAndRpIds) { + // These instances should return security errors (for circumstances + // that would normally crash the renderer). + for (const OriginClaimedAuthorityPair& test_case : + kInvalidRelyingPartyTestCases) { + SCOPED_TRACE(std::string(test_case.claimed_authority) + " " + + std::string(test_case.origin)); + + GURL origin = GURL(test_case.origin); + if (url::Origin::Create(origin).opaque()) { + // Opaque origins will cause DCHECK to fail. + continue; + } + + NavigateAndCommit(origin); + InternalAuthenticatorPtr authenticator = ConnectToAuthenticator(origin); + PublicKeyCredentialRequestOptionsPtr options = + GetTestPublicKeyCredentialRequestOptions(); + options->relying_party_id = test_case.claimed_authority; + + TestGetAssertionCallback callback_receiver; + authenticator->GetAssertion(std::move(options), + callback_receiver.callback()); + callback_receiver.WaitForCallback(); + EXPECT_EQ(AuthenticatorStatus::INVALID_DOMAIN, callback_receiver.status()); + } + + // These instances should bypass security errors, by setting the effective + // origin to a valid one. + for (const OriginClaimedAuthorityPair& test_case : + kValidRelyingPartyTestCases) { + SCOPED_TRACE(std::string(test_case.claimed_authority) + " " + + std::string(test_case.origin)); + + NavigateAndCommit(GURL("https://this.isthewrong.origin")); + auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>( + base::Time::Now(), base::TimeTicks::Now()); + auto authenticator = + ConstructAuthenticatorWithTimer(GURL(test_case.origin), task_runner); + PublicKeyCredentialRequestOptionsPtr options = + GetTestPublicKeyCredentialRequestOptions(); + options->relying_party_id = test_case.claimed_authority; + + device::test::ScopedVirtualFidoDevice virtual_device; + ASSERT_TRUE(virtual_device.mutable_state()->InjectRegistration( + options->allow_credentials[0]->id, test_case.claimed_authority)); + TestGetAssertionCallback callback_receiver; + authenticator->GetAssertion(std::move(options), + callback_receiver.callback()); + callback_receiver.WaitForCallback(); + EXPECT_EQ(AuthenticatorStatus::SUCCESS, callback_receiver.status()); + } +} + } // namespace content
diff --git a/content/common/font_list_win.cc b/content/common/font_list_win.cc index a05a3bc..9aefed1 100644 --- a/content/common/font_list_win.cc +++ b/content/common/font_list_win.cc
@@ -11,6 +11,7 @@ #include <utility> #include "base/strings/string16.h" +#include "base/trace_event/trace_event.h" #include "base/values.h" namespace content { @@ -32,6 +33,7 @@ } std::unique_ptr<base::ListValue> GetFontList_SlowBlocking() { + TRACE_EVENT0("fonts", "GetFontList_SlowBlocking"); std::set<base::string16> font_names; LOGFONTW logfont;
diff --git a/content/common/service_manager/OWNERS b/content/common/service_manager/OWNERS index 361b230..c05943e3 100644 --- a/content/common/service_manager/OWNERS +++ b/content/common/service_manager/OWNERS
@@ -1,4 +1,3 @@ -ben@chromium.org rockot@google.com per-file *_messages*.h=set noparent
diff --git a/content/public/app/content_main.h b/content/public/app/content_main.h index b3dd9ede..0120877 100644 --- a/content/public/app/content_main.h +++ b/content/public/app/content_main.h
@@ -70,6 +70,11 @@ // This should only be called once before ContentMainRunner actually running. // The ownership of |delegate| is transferred. CONTENT_EXPORT void SetContentMainDelegate(ContentMainDelegate* delegate); + +// In browser tests, ContentMain.java is not run either, and the browser test +// harness does not run ContentMain() at all. It does need to make use of the +// delegate though while replacing ContentMain(). +CONTENT_EXPORT ContentMainDelegate* GetContentMainDelegateForTesting(); #else // ContentMain should be called from the embedder's main() function to do the // initial setup for every process. The embedder has a chance to customize
diff --git a/content/public/app/content_main_delegate.h b/content/public/app/content_main_delegate.h index 01f81ee..d4f3b809 100644 --- a/content/public/app/content_main_delegate.h +++ b/content/public/app/content_main_delegate.h
@@ -140,6 +140,7 @@ protected: friend class ContentClientInitializer; + friend class BrowserTestBase; // Called once per relevant process type to allow the embedder to customize // content. If an embedder wants the default (empty) implementation, don't
diff --git a/content/public/browser/background_tracing_manager.h b/content/public/browser/background_tracing_manager.h index c6d4700..d3178a3c 100644 --- a/content/public/browser/background_tracing_manager.h +++ b/content/public/browser/background_tracing_manager.h
@@ -102,9 +102,8 @@ virtual std::string GetLatestTraceToUpload() = 0; // For tests - virtual void AbortScenarioForTesting() = 0; - virtual void SetTraceToUploadForTesting( - std::unique_ptr<std::string> trace_data) = 0; + virtual void AbortScenario() = 0; + virtual void SetTraceToUploadForTesting(base::StringPiece data) = 0; protected: virtual ~BackgroundTracingManager() {}
diff --git a/content/public/browser/picture_in_picture_window_controller.h b/content/public/browser/picture_in_picture_window_controller.h index 706b5079..8ed12997 100644 --- a/content/public/browser/picture_in_picture_window_controller.h +++ b/content/public/browser/picture_in_picture_window_controller.h
@@ -39,7 +39,7 @@ // Called to notify the controller that the window was requested to be closed // by the user or the content. - virtual void Close(bool should_pause_video, bool should_reset_pip_player) = 0; + virtual void Close(bool should_pause_video) = 0; // Called to notify the controller that the window was requested to be closed // by the content and that initiator should be focused.
diff --git a/content/public/test/browser_test_base.cc b/content/public/test/browser_test_base.cc index d9df824..0a13fa71 100644 --- a/content/public/test/browser_test_base.cc +++ b/content/public/test/browser_test_base.cc
@@ -58,6 +58,18 @@ #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_switches.h" +#if defined(OS_ANDROID) +#include "content/app/mojo/mojo_init.h" +#include "content/common/url_schemes.h" +#include "content/public/app/content_main_delegate.h" +#include "content/public/common/content_paths.h" +#include "ui/base/ui_base_paths.h" + +#ifdef V8_USE_EXTERNAL_STARTUP_DATA +#include "gin/v8_initializer.h" +#endif +#endif + #if defined(OS_MACOSX) #include "ui/events/test/event_generator.h" #include "ui/views/test/event_generator_delegate_mac.h" @@ -330,17 +342,65 @@ &BrowserTestBase::CreatedBrowserMainParts, base::Unretained(this))); #if defined(OS_ANDROID) - MainFunctionParams params(*command_line); - params.ui_task = ui_task.release(); - params.created_main_parts_closure = created_main_parts_closure.release(); - base::ThreadPool::Create("Browser"); - DCHECK(!field_trial_list_); - field_trial_list_ = SetUpFieldTrialsAndFeatureList(); - StartBrowserThreadPool(); - BrowserTaskExecutor::Create(); - BrowserTaskExecutor::PostFeatureListSetup(); - // TODO(phajdan.jr): Check return code, http://crbug.com/374738 . - BrowserMain(params); + // For all other platforms, we call ContentMain for browser tests which goes + // through the normal browser initialization paths. For Android, we must set + // things up manually. A meager re-implementation of ContentMainRunnerImpl + // follows. + + base::i18n::AllowMultipleInitializeCallsForTesting(); + base::i18n::InitializeICU(); + +#ifdef V8_USE_EXTERNAL_STARTUP_DATA + gin::V8Initializer::LoadV8Snapshot(); + gin::V8Initializer::LoadV8Natives(); +#endif + + ContentMainDelegate* delegate = GetContentMainDelegateForTesting(); + // The delegate should have been set by JNI_OnLoad for the test target. + DCHECK(delegate); + + bool startup_error = delegate->BasicStartupComplete(/*exit_code=*/nullptr); + DCHECK(!startup_error); + + InitializeMojo(); + + { + SetBrowserClientForTesting(delegate->CreateContentBrowserClient()); + if (command_line->HasSwitch(switches::kSingleProcess)) + SetRendererClientForTesting(delegate->CreateContentRendererClient()); + + content::RegisterPathProvider(); + content::RegisterContentSchemes(false); + ui::RegisterPathProvider(); + + delegate->PreSandboxStartup(); + + DCHECK(!field_trial_list_); + if (delegate->ShouldCreateFeatureList()) { + field_trial_list_ = SetUpFieldTrialsAndFeatureList(); + delegate->PostFieldTrialInitialization(); + } + + base::ThreadPool::Create("Browser"); + + delegate->PreCreateMainMessageLoop(); + BrowserTaskExecutor::Create(); + delegate->PostEarlyInitialization(/*is_running_tests=*/true); + + StartBrowserThreadPool(); + BrowserTaskExecutor::PostFeatureListSetup(); + delegate->PostTaskSchedulerStart(); + } + + // Run BrowserMain which ContentMain would normally run. + { + MainFunctionParams params(*command_line); + params.ui_task = ui_task.release(); + params.created_main_parts_closure = created_main_parts_closure.release(); + int exit_code = BrowserMain(params); + DCHECK_EQ(exit_code, 0); + } + BrowserTaskExecutor::ResetForTesting(); #else GetContentMainParams()->ui_task = ui_task.release();
diff --git a/content/public/test/content_browser_test.cc b/content/public/test/content_browser_test.cc index a61629a..137d881 100644 --- a/content/public/test/content_browser_test.cc +++ b/content/public/test/content_browser_test.cc
@@ -22,10 +22,6 @@ #include "content/test/test_content_client.h" #include "ui/events/platform/platform_event_source.h" -#if defined(OS_ANDROID) -#include "content/shell/app/shell_main_delegate.h" -#endif - #if defined(OS_MACOSX) #include "base/mac/foundation_util.h" #endif @@ -66,21 +62,7 @@ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); SetUpCommandLine(command_line); -#if defined(OS_ANDROID) - shell_main_delegate_.reset(new ShellMainDelegate); - shell_main_delegate_->PreSandboxStartup(); - if (command_line->HasSwitch(switches::kSingleProcess)) { - // We explicitly leak the new ContentRendererClient as we're - // setting a global that may be used after ContentBrowserTest is - // destroyed. - ContentRendererClient* old_client = - switches::IsRunWebTestsSwitchPresent() - ? SetRendererClientForTesting(new WebTestContentRendererClient) - : SetRendererClientForTesting(new ShellContentRendererClient); - // No-one should have set this value before we did. - DCHECK(!old_client); - } -#elif defined(OS_MACOSX) +#if defined(OS_MACOSX) // See InProcessBrowserTest::PrepareTestCommandLine(). base::FilePath subprocess_path; base::PathService::Get(base::FILE_EXE, &subprocess_path); @@ -116,10 +98,6 @@ #if !defined(OS_CHROMEOS) && defined(OS_LINUX) ui::ShutdownInputMethodForTesting(); #endif - -#if defined(OS_ANDROID) - shell_main_delegate_.reset(); -#endif } void ContentBrowserTest::PreRunTestOnMainThread() {
diff --git a/content/public/test/content_browser_test.h b/content/public/test/content_browser_test.h index 6373513..b08b9d5a 100644 --- a/content/public/test/content_browser_test.h +++ b/content/public/test/content_browser_test.h
@@ -18,7 +18,6 @@ namespace content { class Shell; -class ShellMainDelegate; // Base class for browser tests which use content_shell. class ContentBrowserTest : public BrowserTestBase { @@ -61,12 +60,6 @@ base::mac::ScopedNSAutoreleasePool* pool_ = nullptr; #endif -#if defined(OS_ANDROID) - // For all other platforms, this is done automatically when calling into - // ContentMain. For Android we set things up manually. - std::unique_ptr<ShellMainDelegate> shell_main_delegate_; -#endif - // Used to detect incorrect overriding of PreRunTestOnMainThread() with // missung call to base implementation. bool pre_run_test_executed_ = false;
diff --git a/content/public/test/content_test_suite_base.cc b/content/public/test/content_test_suite_base.cc index 758c15d..bab9080 100644 --- a/content/public/test/content_test_suite_base.cc +++ b/content/public/test/content_test_suite_base.cc
@@ -26,10 +26,6 @@ #include "gin/v8_initializer.h" // nogncheck #endif -#if defined(OS_ANDROID) && !defined(USE_AURA) -#include "content/public/browser/android/compositor.h" -#endif - namespace content { namespace { @@ -62,10 +58,6 @@ gin::V8Initializer::LoadV8Natives(); #endif -#if defined(OS_ANDROID) && !defined(USE_AURA) - content::Compositor::Initialize(); -#endif - ui::MaterialDesignController::Initialize(); }
diff --git a/content/renderer/accessibility/ax_image_annotator.cc b/content/renderer/accessibility/ax_image_annotator.cc index 07e88d51..ef669e56 100644 --- a/content/renderer/accessibility/ax_image_annotator.cc +++ b/content/renderer/accessibility/ax_image_annotator.cc
@@ -178,7 +178,7 @@ blink::WebAXObject parent = image.ParentObject(); for (int ancestor_count = 0; !parent.IsDetached() && ancestor_count < 2; parent = parent.ParentObject()) { - if (parent.AccessibilityIsIncludedInTree()) { + if (!parent.AccessibilityIsIgnored()) { ++ancestor_count; if (parent.Role() == ax::mojom::Role::kLink || parent.Role() == ax::mojom::Role::kRootWebArea) {
diff --git a/content/renderer/accessibility/blink_ax_enum_conversion.cc b/content/renderer/accessibility/blink_ax_enum_conversion.cc index 7892d1f5..cca4b0d 100644 --- a/content/renderer/accessibility/blink_ax_enum_conversion.cc +++ b/content/renderer/accessibility/blink_ax_enum_conversion.cc
@@ -71,7 +71,8 @@ else if (o.Orientation() == blink::kWebAXOrientationHorizontal) dst->AddState(ax::mojom::State::kHorizontal); - DCHECK(!o.AccessibilityIsIgnored()); + if (o.IsVisited()) + dst->AddState(ax::mojom::State::kVisited); } } // namespace content.
diff --git a/content/renderer/accessibility/blink_ax_tree_source.cc b/content/renderer/accessibility/blink_ax_tree_source.cc index cc38608..f2f3b9d 100644 --- a/content/renderer/accessibility/blink_ax_tree_source.cc +++ b/content/renderer/accessibility/blink_ax_tree_source.cc
@@ -161,7 +161,7 @@ WebAXObject ParentObjectUnignored(WebAXObject child) { WebAXObject parent = child.ParentObject(); - while (!parent.IsDetached() && !parent.AccessibilityIsIncludedInTree()) + while (!parent.IsDetached() && parent.AccessibilityIsIgnored()) parent = parent.ParentObject(); return parent; } @@ -488,7 +488,7 @@ if (node.Equals(root())) return WebAXObject(); node = node.ParentObject(); - } while (!node.IsDetached() && !node.AccessibilityIsIncludedInTree()); + } while (!node.IsDetached() && node.AccessibilityIsIgnored()); return node; }
diff --git a/content/renderer/appcache/web_application_cache_host_impl.cc b/content/renderer/appcache/web_application_cache_host_impl.cc index 9c3a69d..177462ba 100644 --- a/content/renderer/appcache/web_application_cache_host_impl.cc +++ b/content/renderer/appcache/web_application_cache_host_impl.cc
@@ -20,6 +20,7 @@ #include "third_party/blink/public/mojom/appcache/appcache.mojom.h" #include "third_party/blink/public/mojom/appcache/appcache_info.mojom.h" #include "third_party/blink/public/mojom/devtools/console_message.mojom.h" +#include "third_party/blink/public/mojom/frame/document_interface_broker.mojom.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_url.h" #include "third_party/blink/public/platform/web_url_response.h" @@ -64,9 +65,9 @@ } WebApplicationCacheHostImpl::WebApplicationCacheHostImpl( + blink::mojom::DocumentInterfaceBroker* interface_broker, WebApplicationCacheHostClient* client, int appcache_host_id, - int render_frame_id, scoped_refptr<base::SingleThreadTaskRunner> task_runner) : binding_(this), client_(client), @@ -85,6 +86,15 @@ } DCHECK(host_id_ != blink::mojom::kAppCacheNoHostId); + blink::mojom::AppCacheFrontendPtr frontend_ptr; + binding_.Bind(mojo::MakeRequest(&frontend_ptr, task_runner), task_runner); + if (interface_broker) { + interface_broker->RegisterAppCacheHost( + mojo::MakeRequest(&backend_host_, std::move(task_runner)), + std::move(frontend_ptr), host_id_); + return; + } + static const base::NoDestructor<blink::mojom::AppCacheBackendPtr> backend_ptr( [] { blink::mojom::AppCacheBackendPtr result; @@ -92,13 +102,13 @@ mojom::kBrowserServiceName, mojo::MakeRequest(&result)); return result; }()); - backend_ = backend_ptr->get(); - blink::mojom::AppCacheFrontendPtr frontend_ptr; - binding_.Bind(mojo::MakeRequest(&frontend_ptr, task_runner), task_runner); - backend_->RegisterHost( + // Once we have 'WebContextInterfaceBroker', we can call this function through + // it like render frame. + // Refer to the design document, 'https://bit.ly/2GT0rZv'. + backend_ptr->get()->RegisterHost( mojo::MakeRequest(&backend_host_, std::move(task_runner)), - std::move(frontend_ptr), host_id_, render_frame_id); + std::move(frontend_ptr), host_id_); } WebApplicationCacheHostImpl::~WebApplicationCacheHostImpl() {
diff --git a/content/renderer/appcache/web_application_cache_host_impl.h b/content/renderer/appcache/web_application_cache_host_impl.h index 59b4839..495acde 100644 --- a/content/renderer/appcache/web_application_cache_host_impl.h +++ b/content/renderer/appcache/web_application_cache_host_impl.h
@@ -17,6 +17,12 @@ #include "third_party/blink/public/platform/web_vector.h" #include "url/gurl.h" +namespace blink { +namespace mojom { +class DocumentInterfaceBroker; +} +} // namespace blink + namespace content { class WebApplicationCacheHostImpl : public blink::WebApplicationCacheHost, @@ -25,15 +31,15 @@ // Returns the host having given id or NULL if there is no such host. static WebApplicationCacheHostImpl* FromId(int id); + // |interface_broker| can be null for workers. WebApplicationCacheHostImpl( + blink::mojom::DocumentInterfaceBroker* interface_broker, blink::WebApplicationCacheHostClient* client, int appcache_host_id, - int render_frame_id, scoped_refptr<base::SingleThreadTaskRunner> task_runner); ~WebApplicationCacheHostImpl() override; int host_id() const { return host_id_; } - blink::mojom::AppCacheBackend* backend() const { return backend_; } blink::WebApplicationCacheHostClient* client() const { return client_; } // blink::mojom::AppCacheFrontend @@ -66,7 +72,6 @@ mojo::Binding<blink::mojom::AppCacheFrontend> binding_; blink::WebApplicationCacheHostClient* client_; - blink::mojom::AppCacheBackend* backend_; blink::mojom::AppCacheHostPtr backend_host_; int host_id_; blink::mojom::AppCacheStatus status_;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 82494a5..06919d0e 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -3986,8 +3986,7 @@ frame_->GetTaskRunner(blink::TaskType::kNetworking); return std::make_unique<RendererWebApplicationCacheHostImpl>( - RenderViewImpl::FromWebView(frame_->View()), client, - navigation_state->commit_params().appcache_host_id, routing_id_, + this, client, navigation_state->commit_params().appcache_host_id, std::move(task_runner)); }
diff --git a/content/renderer/render_frame_impl_browsertest.cc b/content/renderer/render_frame_impl_browsertest.cc index a351ea6..644316c 100644 --- a/content/renderer/render_frame_impl_browsertest.cc +++ b/content/renderer/render_frame_impl_browsertest.cc
@@ -861,6 +861,9 @@ void GetVirtualAuthenticatorManager( blink::test::mojom::VirtualAuthenticatorManagerRequest request) override { } + void RegisterAppCacheHost(blink::mojom::AppCacheHostRequest host_request, + blink::mojom::AppCacheFrontendPtr frontend, + int32_t id) override {} mojo::Binding<blink::mojom::DocumentInterfaceBroker> binding_; BinderCallback binder_callback_;
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 8a86edf..1981bdb 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -1972,14 +1972,12 @@ #if BUILDFLAG(USE_DEFAULT_RENDER_THEME) if (renderer_prefs.use_custom_colors) { blink::SetFocusRingColor(renderer_prefs.focus_ring_color); - - if (webview()) { - webview()->SetSelectionColors(renderer_prefs.active_selection_bg_color, - renderer_prefs.active_selection_fg_color, - renderer_prefs.inactive_selection_bg_color, - renderer_prefs.inactive_selection_fg_color); + blink::SetSelectionColors(renderer_prefs.active_selection_bg_color, + renderer_prefs.active_selection_fg_color, + renderer_prefs.inactive_selection_bg_color, + renderer_prefs.inactive_selection_fg_color); + if (webview()) webview()->MainFrameWidget()->ThemeChanged(); - } } #endif // BUILDFLAG(USE_DEFAULT_RENDER_THEME)
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index c52b7ce..6381e60 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -307,31 +307,29 @@ item_list.push_back(item); } - for (auto it = drop_data.filenames.begin(); it != drop_data.filenames.end(); - ++it) { + for (const ui::FileInfo& filename : drop_data.filenames) { WebDragData::Item item; item.storage_type = WebDragData::Item::kStorageTypeFilename; - item.filename_data = blink::FilePathToWebString(it->path); + item.filename_data = blink::FilePathToWebString(filename.path); item.display_name_data = - blink::FilePathToWebString(base::FilePath(it->display_name)); + blink::FilePathToWebString(base::FilePath(filename.display_name)); item_list.push_back(item); } - for (auto it = drop_data.file_system_files.begin(); - it != drop_data.file_system_files.end(); ++it) { + for (const DropData::FileSystemFileInfo& file : drop_data.file_system_files) { WebDragData::Item item; item.storage_type = WebDragData::Item::kStorageTypeFileSystemFile; - item.file_system_url = it->url; - item.file_system_file_size = it->size; - item.file_system_id = blink::WebString::FromASCII(it->filesystem_id); + item.file_system_url = file.url; + item.file_system_file_size = file.size; + item.file_system_id = blink::WebString::FromASCII(file.filesystem_id); item_list.push_back(item); } - for (const auto& it : drop_data.custom_data) { + for (const auto& data : drop_data.custom_data) { WebDragData::Item item; item.storage_type = WebDragData::Item::kStorageTypeString; - item.string_type = WebString::FromUTF16(it.first); - item.string_data = WebString::FromUTF16(it.second); + item.string_type = WebString::FromUTF16(data.first); + item.string_data = WebString::FromUTF16(data.second); item_list.push_back(item); }
diff --git a/content/renderer/renderer_webapplicationcachehost_impl.cc b/content/renderer/renderer_webapplicationcachehost_impl.cc index db213c0..289a3ea 100644 --- a/content/renderer/renderer_webapplicationcachehost_impl.cc +++ b/content/renderer/renderer_webapplicationcachehost_impl.cc
@@ -21,17 +21,16 @@ namespace content { RendererWebApplicationCacheHostImpl::RendererWebApplicationCacheHostImpl( - RenderViewImpl* render_view, + RenderFrameImpl* render_frame, WebApplicationCacheHostClient* client, int appcache_host_id, - int frame_routing_id, scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : WebApplicationCacheHostImpl(client, + : WebApplicationCacheHostImpl(render_frame->GetDocumentInterfaceBroker(), + client, appcache_host_id, - frame_routing_id, std::move(task_runner)), - routing_id_(render_view->GetRoutingID()), - frame_routing_id_(frame_routing_id) {} + routing_id_(render_frame->render_view()->GetRoutingID()), + frame_routing_id_(render_frame->GetRoutingID()) {} void RendererWebApplicationCacheHostImpl::LogMessage( blink::mojom::ConsoleMessageLevel log_level,
diff --git a/content/renderer/renderer_webapplicationcachehost_impl.h b/content/renderer/renderer_webapplicationcachehost_impl.h index b0dc037..f326c92 100644 --- a/content/renderer/renderer_webapplicationcachehost_impl.h +++ b/content/renderer/renderer_webapplicationcachehost_impl.h
@@ -12,15 +12,15 @@ #include "third_party/blink/public/mojom/devtools/console_message.mojom.h" namespace content { +class RenderFrameImpl; class RenderViewImpl; class RendererWebApplicationCacheHostImpl : public WebApplicationCacheHostImpl { public: RendererWebApplicationCacheHostImpl( - RenderViewImpl* render_view, + RenderFrameImpl* render_frame, blink::WebApplicationCacheHostClient* client, int appcache_host_id, - int frame_routing_id, scoped_refptr<base::SingleThreadTaskRunner> task_runner); // blink::mojom::AppCacheHostFrontend:
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc index 6495e895..a9454c1 100644 --- a/content/renderer/service_worker/service_worker_context_client.cc +++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -232,6 +232,8 @@ std::map<int, DispatchBackgroundFetchSuccessEventCallback> background_fetched_event_callbacks; std::map<int, DispatchSyncEventCallback> sync_event_callbacks; + std::map<int, DispatchPeriodicSyncEventCallback> + periodic_sync_event_callbacks; std::map<int, payments::mojom::PaymentHandlerResponseCallbackPtr> abort_payment_result_callbacks; std::map<int, DispatchCanMakePaymentEventCallback> @@ -897,6 +899,22 @@ context_->timeout_timer.get(), request_id, status); } +void ServiceWorkerContextClient::DidHandlePeriodicSyncEvent( + int request_id, + blink::mojom::ServiceWorkerEventStatus status) { + DCHECK(worker_task_runner_->RunsTasksInCurrentSequence()); + if (!context_) + return; + TRACE_EVENT_WITH_FLOW1( + "ServiceWorker", "ServiceWorkerContextClient::DidHandlePeriodicSyncEvent", + TRACE_ID_WITH_SCOPE(kServiceWorkerContextClientScope, + TRACE_ID_LOCAL(request_id)), + TRACE_EVENT_FLAG_FLOW_IN, "status", + ServiceWorkerUtils::MojoEnumToString(status)); + RunEventCallback(&context_->periodic_sync_event_callbacks, + context_->timeout_timer.get(), request_id, status); +} + void ServiceWorkerContextClient::RespondToAbortPaymentEvent( int event_id, bool payment_aborted) { @@ -1127,6 +1145,28 @@ last_chance); } +void ServiceWorkerContextClient::DispatchPeriodicSyncEvent( + const std::string& tag, + base::TimeDelta timeout, + DispatchSyncEventCallback callback) { + DCHECK(worker_task_runner_->RunsTasksInCurrentSequence()); + // |context_| is valid because the Mojo binding is on |worker_task_runner_|. + DCHECK(context_); + + int request_id = context_->timeout_timer->StartEventWithCustomTimeout( + CreateAbortCallback(&context_->periodic_sync_event_callbacks), timeout); + context_->periodic_sync_event_callbacks.emplace(request_id, + std::move(callback)); + TRACE_EVENT_WITH_FLOW0( + "ServiceWorker", "ServiceWorkerContextClient::DispatchPeriodicSyncEvent", + TRACE_ID_WITH_SCOPE(kServiceWorkerContextClientScope, + TRACE_ID_LOCAL(request_id)), + TRACE_EVENT_FLAG_FLOW_OUT); + + proxy_->DispatchPeriodicSyncEvent(request_id, + blink::WebString::FromUTF8(tag)); +} + void ServiceWorkerContextClient::DispatchAbortPaymentEvent( payments::mojom::PaymentHandlerResponseCallbackPtr response_callback, DispatchAbortPaymentEventCallback callback) {
diff --git a/content/renderer/service_worker/service_worker_context_client.h b/content/renderer/service_worker/service_worker_context_client.h index ddf79ccb..e777e18 100644 --- a/content/renderer/service_worker/service_worker_context_client.h +++ b/content/renderer/service_worker/service_worker_context_client.h
@@ -183,6 +183,9 @@ void DidHandleSyncEvent( int request_id, blink::mojom::ServiceWorkerEventStatus status) override; + void DidHandlePeriodicSyncEvent( + int request_id, + blink::mojom::ServiceWorkerEventStatus status) override; void RespondToAbortPaymentEvent(int event_id, bool payment_aborted) override; void DidHandleAbortPaymentEvent( int event_id, @@ -314,6 +317,9 @@ bool last_chance, base::TimeDelta timeout, DispatchSyncEventCallback callback) override; + void DispatchPeriodicSyncEvent(const std::string& tag, + base::TimeDelta timeout, + DispatchSyncEventCallback callback) override; void DispatchAbortPaymentEvent( payments::mojom::PaymentHandlerResponseCallbackPtr response_callback, DispatchAbortPaymentEventCallback callback) override;
diff --git a/content/renderer/service_worker/service_worker_context_client_unittest.cc b/content/renderer/service_worker/service_worker_context_client_unittest.cc index f5b4dc71..62d04c3 100644 --- a/content/renderer/service_worker/service_worker_context_client_unittest.cc +++ b/content/renderer/service_worker/service_worker_context_client_unittest.cc
@@ -177,6 +177,10 @@ bool last_chance) override { NOTREACHED(); } + void DispatchPeriodicSyncEvent(int sync_event_id, + const blink::WebString& tag) override { + NOTREACHED(); + } void DispatchAbortPaymentEvent(int event_id) override { NOTREACHED(); } void DispatchCanMakePaymentEvent( int event_id,
diff --git a/content/renderer/worker/application_cache_host_for_shared_worker.cc b/content/renderer/worker/application_cache_host_for_shared_worker.cc index 2241b19a..9ec1777 100644 --- a/content/renderer/worker/application_cache_host_for_shared_worker.cc +++ b/content/renderer/worker/application_cache_host_for_shared_worker.cc
@@ -10,9 +10,9 @@ blink::WebApplicationCacheHostClient* client, int appcache_host_id, scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : WebApplicationCacheHostImpl(client, + : WebApplicationCacheHostImpl(nullptr /* interface_broker */, + client, appcache_host_id, - MSG_ROUTING_NONE, std::move(task_runner)) {} ApplicationCacheHostForSharedWorker::~ApplicationCacheHostForSharedWorker() =
diff --git a/content/shell/android/browsertests_apk/content_browser_tests_jni_onload.cc b/content/shell/android/browsertests_apk/content_browser_tests_jni_onload.cc index c6c1674..05b8f3b 100644 --- a/content/shell/android/browsertests_apk/content_browser_tests_jni_onload.cc +++ b/content/shell/android/browsertests_apk/content_browser_tests_jni_onload.cc
@@ -2,11 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <memory> + #include "base/android/jni_android.h" #include "base/android/library_loader/library_loader_hooks.h" #include "base/bind.h" +#include "base/message_loop/message_loop.h" #include "content/public/app/content_jni_onload.h" #include "content/public/app/content_main.h" +#include "content/public/test/nested_message_pump_android.h" #include "content/shell/app/shell_main_delegate.h" #include "testing/android/native_test/native_test_launcher.h" @@ -15,6 +19,17 @@ base::android::InitVM(vm); if (!content::android::OnJNIOnLoadInit()) return -1; + + // This needs to be done before base::TestSuite::Initialize() is called, + // as it also tries to set MessagePumpForUIFactory. + bool success = base::MessageLoop::InitMessagePumpForUIFactory( + []() -> std::unique_ptr<base::MessagePump> { + return std::make_unique<content::NestedMessagePumpAndroid>(); + }); + // If this fails, MessagePumpForUIFactory is already set, and we're unable to + // override. + DCHECK(success); + content::SetContentMainDelegate(new content::ShellMainDelegate(true)); return JNI_VERSION_1_4; }
diff --git a/content/shell/android/linker_test_apk/chromium_linker_test_android.cc b/content/shell/android/linker_test_apk/chromium_linker_test_android.cc index 2d4d9b4..300a15a3 100644 --- a/content/shell/android/linker_test_apk/chromium_linker_test_android.cc +++ b/content/shell/android/linker_test_apk/chromium_linker_test_android.cc
@@ -7,7 +7,6 @@ #include "base/bind.h" #include "content/public/app/content_jni_onload.h" #include "content/public/app/content_main.h" -#include "content/public/browser/android/compositor.h" #include "content/shell/android/linker_test_apk/linker_test_jni_registration.h" #include "content/shell/app/shell_main_delegate.h" @@ -19,7 +18,6 @@ !content::android::OnJNIOnLoadInit()) { return -1; } - content::Compositor::Initialize(); content::SetContentMainDelegate(new content::ShellMainDelegate()); return JNI_VERSION_1_4; }
diff --git a/content/shell/android/shell_library_loader.cc b/content/shell/android/shell_library_loader.cc index e21b58d1..b22b9518 100644 --- a/content/shell/android/shell_library_loader.cc +++ b/content/shell/android/shell_library_loader.cc
@@ -5,17 +5,13 @@ #include "base/android/jni_android.h" #include "content/public/app/content_jni_onload.h" #include "content/public/app/content_main.h" -#include "content/public/browser/android/compositor.h" #include "content/shell/app/shell_main_delegate.h" // This is called by the VM when the shared library is first loaded. JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { base::android::InitVM(vm); - if (!content::android::OnJNIOnLoadInit()) return -1; - - content::Compositor::Initialize(); content::SetContentMainDelegate(new content::ShellMainDelegate()); return JNI_VERSION_1_4; }
diff --git a/content/shell/android/shell_test_library_loader.cc b/content/shell/android/shell_test_library_loader.cc index dda0556..cdf5de1 100644 --- a/content/shell/android/shell_test_library_loader.cc +++ b/content/shell/android/shell_test_library_loader.cc
@@ -5,7 +5,6 @@ #include "base/android/jni_android.h" #include "content/public/app/content_jni_onload.h" #include "content/public/app/content_main.h" -#include "content/public/browser/android/compositor.h" #include "content/shell/app/shell_main_delegate.h" // This is called by the VM when the shared library is first loaded. @@ -13,7 +12,6 @@ base::android::InitVM(vm); if (!content::android::OnJNIOnLoadInit()) return -1; - content::Compositor::Initialize(); content::SetContentMainDelegate(new content::ShellMainDelegate()); return JNI_VERSION_1_4; }
diff --git a/content/shell/app/shell_main_delegate.cc b/content/shell/app/shell_main_delegate.cc index 03c99e0..ffec0911 100644 --- a/content/shell/app/shell_main_delegate.cc +++ b/content/shell/app/shell_main_delegate.cc
@@ -64,6 +64,7 @@ #if defined(OS_ANDROID) #include "base/android/apk_assets.h" #include "base/posix/global_descriptors.h" +#include "content/public/browser/android/compositor.h" #include "content/public/test/nested_message_pump_android.h" #include "content/shell/android/shell_descriptors.h" #endif @@ -161,6 +162,9 @@ if (!exit_code) exit_code = &dummy; +#if defined(OS_ANDROID) + Compositor::Initialize(); +#endif #if defined(OS_WIN) // Enable trace control and transport through event tracing for Windows. logging::LogEventProvider::Initialize(kContentShellProviderName);
diff --git a/content/shell/test_runner/test_runner_for_specific_view.cc b/content/shell/test_runner/test_runner_for_specific_view.cc index 85812a7..e18cbbc4 100644 --- a/content/shell/test_runner/test_runner_for_specific_view.cc +++ b/content/shell/test_runner/test_runner_for_specific_view.cc
@@ -48,6 +48,7 @@ #include "third_party/blink/public/web/web_frame_widget.h" #include "third_party/blink/public/web/web_input_element.h" #include "third_party/blink/public/web/web_local_frame.h" +#include "third_party/blink/public/web/web_render_theme.h" #include "third_party/blink/public/web/web_script_source.h" #include "third_party/blink/public/web/web_security_policy.h" #include "third_party/blink/public/web/web_serialized_script_value.h" @@ -90,8 +91,7 @@ #if !defined(OS_MACOSX) && !defined(OS_WIN) // (Constants copied because we can't depend on the header that defined // them from this file.) - web_view()->SetSelectionColors(0xff1e90ff, 0xff000000, 0xffc8c8c8, - 0xff323232); + blink::SetSelectionColors(0xff1e90ff, 0xff000000, 0xffc8c8c8, 0xff323232); #endif if (web_view()->MainFrame()->IsWebLocalFrame()) { web_view()->MainFrame()->ToWebLocalFrame()->EnableViewSourceMode(false); @@ -483,8 +483,7 @@ } void TestRunnerForSpecificView::ForceRedSelectionColors() { - web_view()->SetSelectionColors(0xffee0000, 0xff00ee00, 0xff000000, - 0xffc0c0c0); + blink::SetSelectionColors(0xffee0000, 0xff00ee00, 0xff000000, 0xffc0c0c0); } void TestRunnerForSpecificView::SetPageVisibility(
diff --git a/content/shell/test_runner/web_ax_object_proxy.cc b/content/shell/test_runner/web_ax_object_proxy.cc index abf42f7..0e03fabc 100644 --- a/content/shell/test_runner/web_ax_object_proxy.cc +++ b/content/shell/test_runner/web_ax_object_proxy.cc
@@ -1657,8 +1657,7 @@ v8::Local<v8::Object> WebAXObjectProxy::ParentElement() { accessibility_object_.UpdateLayoutAndCheckValidity(); blink::WebAXObject parent_object = accessibility_object_.ParentObject(); - while (!parent_object.IsNull() && - !parent_object.AccessibilityIsIncludedInTree()) + while (parent_object.AccessibilityIsIgnored()) parent_object = parent_object.ParentObject(); return factory_->GetOrCreate(parent_object); }
diff --git a/content/shell/test_runner/web_view_test_proxy.cc b/content/shell/test_runner/web_view_test_proxy.cc index adacdb9f..8b291bf 100644 --- a/content/shell/test_runner/web_view_test_proxy.cc +++ b/content/shell/test_runner/web_view_test_proxy.cc
@@ -91,6 +91,11 @@ } void WebViewTestProxy::Reset() { + // TODO(https://crbug.com/961499): There is a race condition where Reset() + // can be called after GetWidget() has been nulled, but before this is + // destructed. + if (!GetWidget()) + return; accessibility_controller_.Reset(); // text_input_controller_ doesn't have any state to reset. view_test_runner_.Reset();
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 60e3dfc..0b9fe07 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -2229,6 +2229,7 @@ if (!is_linux_without_udev && !is_android) { sources += [ "../browser/webauth/authenticator_impl_unittest.cc" ] deps += [ + "//components/autofill/content/browser/webauthn", "//device/base", "//device/fido", "//device/fido:mocks",
diff --git a/content/test/content_test_launcher.cc b/content/test/content_test_launcher.cc index a5dd4b2..e8a53f3e 100644 --- a/content/test/content_test_launcher.cc +++ b/content/test/content_test_launcher.cc
@@ -24,29 +24,8 @@ #include "ui/base/buildflags.h" #include "ui/base/ui_base_switches.h" -#ifdef V8_USE_EXTERNAL_STARTUP_DATA -#include "gin/v8_initializer.h" -#endif - -#if defined(OS_ANDROID) -#include "base/message_loop/message_loop.h" -#include "content/app/mojo/mojo_init.h" -#include "content/common/url_schemes.h" -#include "content/public/common/content_paths.h" -#include "content/public/test/nested_message_pump_android.h" -#include "content/shell/browser/shell_content_browser_client.h" -#include "content/shell/common/shell_content_client.h" -#include "ui/base/ui_base_paths.h" -#endif - namespace content { -#if defined(OS_ANDROID) -std::unique_ptr<base::MessagePump> CreateMessagePumpForUI() { - return std::unique_ptr<base::MessagePump>(new NestedMessagePumpAndroid()); -} -#endif - class ContentBrowserTestSuite : public ContentTestSuiteBase { public: ContentBrowserTestSuite(int argc, char** argv) @@ -56,47 +35,16 @@ protected: void Initialize() override { -#if defined(OS_ANDROID) - base::i18n::AllowMultipleInitializeCallsForTesting(); - base::i18n::InitializeICU(); - -#ifdef V8_USE_EXTERNAL_STARTUP_DATA - gin::V8Initializer::LoadV8Snapshot(); - gin::V8Initializer::LoadV8Natives(); -#endif - - // This needs to be done before base::TestSuite::Initialize() is called, - // as it also tries to set MessagePumpForUIFactory. - if (!base::MessageLoop::InitMessagePumpForUIFactory( - &CreateMessagePumpForUI)) - VLOG(0) << "MessagePumpForUIFactory already set, unable to override."; - - // For all other platforms, we call ContentMain for browser tests which goes - // through the normal browser initialization paths. For Android, we must set - // things up manually. - content_client_.reset(new ShellContentClient); - browser_content_client_.reset(new ShellContentBrowserClient()); - SetContentClient(content_client_.get()); - SetBrowserClientForTesting(browser_content_client_.get()); - - content::RegisterContentSchemes(false); - RegisterPathProvider(); - ui::RegisterPathProvider(); - RegisterInProcessThreads(); - - InitializeMojo(); -#endif - - // Browser tests are expected not to tear-down various globals. + // Browser tests are expected not to tear-down various globals. (Must run + // before the base class is initialized.) base::TestSuite::DisableCheckForLeakedGlobals(); ContentTestSuiteBase::Initialize(); - } #if defined(OS_ANDROID) - std::unique_ptr<ShellContentClient> content_client_; - std::unique_ptr<ShellContentBrowserClient> browser_content_client_; + RegisterInProcessThreads(); #endif + } DISALLOW_COPY_AND_ASSIGN(ContentBrowserTestSuite); };
diff --git a/content/test/test_background_sync_manager.cc b/content/test/test_background_sync_manager.cc index f4c5f1d..67b30bd 100644 --- a/content/test/test_background_sync_manager.cc +++ b/content/test/test_background_sync_manager.cc
@@ -90,6 +90,14 @@ dispatch_sync_callback_.Run(active_version, std::move(callback)); } +void TestBackgroundSyncManager::DispatchPeriodicSyncEvent( + const std::string& tag, + scoped_refptr<ServiceWorkerVersion> active_version, + ServiceWorkerVersion::StatusCallback callback) { + ASSERT_TRUE(dispatch_periodic_sync_callback_); + dispatch_periodic_sync_callback_.Run(active_version, std::move(callback)); +} + void TestBackgroundSyncManager::ScheduleDelayedTask(base::OnceClosure callback, base::TimeDelta delay) { delayed_task_ = std::move(callback);
diff --git a/content/test/test_background_sync_manager.h b/content/test/test_background_sync_manager.h index 6f0b64b..58f5217 100644 --- a/content/test/test_background_sync_manager.h +++ b/content/test/test_background_sync_manager.h
@@ -71,6 +71,13 @@ dispatch_sync_callback_ = callback; } + // Set a callback for when the periodicSync event is dispatched, so tests can + // observe it. + void set_dispatch_periodic_sync_callback( + const DispatchSyncCallback& callback) { + dispatch_periodic_sync_callback_ = callback; + } + // Sets the response to checks for a main frame for register attempts. void set_has_main_frame_provider_host(bool value) { has_main_frame_provider_host_ = value; @@ -94,6 +101,11 @@ return soonest_one_shot_wakeup_delta_ == compare_to; } + void DispatchPeriodicSyncEvent( + const std::string& tag, + scoped_refptr<ServiceWorkerVersion> active_version, + ServiceWorkerVersion::StatusCallback callback) override; + // Override to allow the test to cache the result. base::TimeDelta GetSoonestWakeupDelta( blink::mojom::BackgroundSyncType sync_type) override; @@ -153,6 +165,7 @@ bool last_chance_ = false; base::OnceClosure continuation_; DispatchSyncCallback dispatch_sync_callback_; + DispatchSyncCallback dispatch_periodic_sync_callback_; base::OnceClosure delayed_task_; base::TimeDelta delayed_task_delta_; base::TimeDelta soonest_one_shot_wakeup_delta_;
diff --git a/device/vr/BUILD.gn b/device/vr/BUILD.gn index 8d29f9c..0e5aa71 100644 --- a/device/vr/BUILD.gn +++ b/device/vr/BUILD.gn
@@ -177,6 +177,8 @@ "windows_mixed_reality/wrappers/wmr_rendering.h", "windows_mixed_reality/wrappers/wmr_timestamp.cc", "windows_mixed_reality/wrappers/wmr_timestamp.h", + "windows_mixed_reality/wrappers/wmr_wrapper_factories.cc", + "windows_mixed_reality/wrappers/wmr_wrapper_factories.h", ] # Sources only meant to be actually used in tests, but need to be always
diff --git a/device/vr/OWNERS b/device/vr/OWNERS index 5fbbb06..f53264a 100644 --- a/device/vr/OWNERS +++ b/device/vr/OWNERS
@@ -1,3 +1,4 @@ +alcooper@chromium.org bajones@chromium.org bialpio@chromium.org billorr@chromium.org
diff --git a/device/vr/windows_mixed_reality/mixed_reality_renderloop.cc b/device/vr/windows_mixed_reality/mixed_reality_renderloop.cc index 4438a3a..1c79673 100644 --- a/device/vr/windows_mixed_reality/mixed_reality_renderloop.cc +++ b/device/vr/windows_mixed_reality/mixed_reality_renderloop.cc
@@ -29,6 +29,7 @@ #include "device/vr/windows_mixed_reality/wrappers/wmr_origins.h" #include "device/vr/windows_mixed_reality/wrappers/wmr_rendering.h" #include "device/vr/windows_mixed_reality/wrappers/wmr_timestamp.h" +#include "device/vr/windows_mixed_reality/wrappers/wmr_wrapper_factories.h" #include "ui/gfx/geometry/angle_conversions.h" #include "ui/gfx/geometry/vector3d_f.h" #include "ui/gfx/transform.h" @@ -287,13 +288,13 @@ // Try to get a stationary frame. We'll hand out all of our poses in this // space. if (!attached_) { - attached_ = WMRAttachedOrigin::CreateAtCurrentLocation(); + attached_ = WMRAttachedOriginFactory::CreateAtCurrentLocation(); if (!attached_) return; } std::unique_ptr<WMRStationaryOrigin> stationary_frame = - WMRStationaryOrigin::CreateAtCurrentLocation(); + WMRStationaryOriginFactory::CreateAtCurrentLocation(); if (!stationary_frame) return; @@ -328,7 +329,7 @@ if (stage_statics_) return true; - stage_statics_ = WMRStageStatics::Create(); + stage_statics_ = WMRStageStaticsFactory::Create(); if (!stage_statics_) return false; @@ -343,8 +344,6 @@ void MixedRealityRenderLoop::ClearStageStatics() { stage_changed_subscription_ = nullptr; - if (stage_statics_) - stage_statics_->Dispose(); stage_statics_ = nullptr; }
diff --git a/device/vr/windows_mixed_reality/mixed_reality_statics.cc b/device/vr/windows_mixed_reality/mixed_reality_statics.cc index 09d79d0..b58e5f3e 100644 --- a/device/vr/windows_mixed_reality/mixed_reality_statics.cc +++ b/device/vr/windows_mixed_reality/mixed_reality_statics.cc
@@ -56,6 +56,12 @@ return LockedVRTestHook(test_hook_); } +bool MixedRealityDeviceStatics::ShouldUseMocks() { + auto locked_hook = GetLockedTestHook(); + static bool should_use_mocks = (locked_hook.GetHook() != nullptr); + return should_use_mocks; +} + MixedRealityDeviceStatics::~MixedRealityDeviceStatics() {} MixedRealityDeviceStaticsImpl::MixedRealityDeviceStaticsImpl() {
diff --git a/device/vr/windows_mixed_reality/mixed_reality_statics.h b/device/vr/windows_mixed_reality/mixed_reality_statics.h index c1cb5ac..1a5c9df 100644 --- a/device/vr/windows_mixed_reality/mixed_reality_statics.h +++ b/device/vr/windows_mixed_reality/mixed_reality_statics.h
@@ -19,6 +19,7 @@ static std::unique_ptr<MixedRealityDeviceStatics> CreateInstance(); static void SetTestHook(VRTestHook* hook); static LockedVRTestHook GetLockedTestHook(); + static bool ShouldUseMocks(); virtual ~MixedRealityDeviceStatics();
diff --git a/device/vr/windows_mixed_reality/wrappers/test/mock_wmr_origins.cc b/device/vr/windows_mixed_reality/wrappers/test/mock_wmr_origins.cc index 9e794fc..e733032 100644 --- a/device/vr/windows_mixed_reality/wrappers/test/mock_wmr_origins.cc +++ b/device/vr/windows_mixed_reality/wrappers/test/mock_wmr_origins.cc
@@ -18,6 +18,11 @@ return true; } +ABI::Windows::Perception::Spatial::ISpatialCoordinateSystem* +MockWMRCoordinateSystem::GetRawPtr() const { + return nullptr; +} + // MockWMRStationaryOrigin MockWMRStationaryOrigin::MockWMRStationaryOrigin() {} @@ -61,14 +66,16 @@ // MockWMRStageStatics MockWMRStageStatics::MockWMRStageStatics() {} -MockWMRStageStatics::~MockWMRStageStatics() {} - -void MockWMRStageStatics::Dispose() { - dispose_called_ = true; -} +MockWMRStageStatics::~MockWMRStageStatics() = default; std::unique_ptr<WMRStageOrigin> MockWMRStageStatics::CurrentStage() { return std::make_unique<MockWMRStageOrigin>(); } +std::unique_ptr<base::CallbackList<void()>::Subscription> +MockWMRStageStatics::AddStageChangedCallback( + const base::RepeatingCallback<void()>& cb) { + return callback_list_.Add(cb); +} + } // namespace device
diff --git a/device/vr/windows_mixed_reality/wrappers/test/mock_wmr_origins.h b/device/vr/windows_mixed_reality/wrappers/test/mock_wmr_origins.h index 88fcc148..992482e2 100644 --- a/device/vr/windows_mixed_reality/wrappers/test/mock_wmr_origins.h +++ b/device/vr/windows_mixed_reality/wrappers/test/mock_wmr_origins.h
@@ -19,6 +19,9 @@ const WMRCoordinateSystem* other, ABI::Windows::Foundation::Numerics::Matrix4x4* this_to_other) override; + ABI::Windows::Perception::Spatial::ISpatialCoordinateSystem* GetRawPtr() + const override; + private: DISALLOW_COPY_AND_ASSIGN(MockWMRCoordinateSystem); }; @@ -68,9 +71,12 @@ std::unique_ptr<WMRStageOrigin> CurrentStage() override; - void Dispose() override; + std::unique_ptr<base::CallbackList<void()>::Subscription> + AddStageChangedCallback(const base::RepeatingCallback<void()>& cb) override; private: + base::CallbackList<void()> callback_list_; + DISALLOW_COPY_AND_ASSIGN(MockWMRStageStatics); };
diff --git a/device/vr/windows_mixed_reality/wrappers/wmr_origins.cc b/device/vr/windows_mixed_reality/wrappers/wmr_origins.cc index ab4e5cb..f6a8ab90 100644 --- a/device/vr/windows_mixed_reality/wrappers/wmr_origins.cc +++ b/device/vr/windows_mixed_reality/wrappers/wmr_origins.cc
@@ -37,46 +37,19 @@ using ABI::Windows::Perception::Spatial::ISpatialStationaryFrameOfReference; using Microsoft::WRL::ComPtr; -namespace { -ComPtr<ISpatialLocator> GetSpatialLocator() { - ComPtr<ISpatialLocatorStatics> spatial_locator_statics; - base::win::ScopedHString spatial_locator_string = - base::win::ScopedHString::Create( - RuntimeClass_Windows_Perception_Spatial_SpatialLocator); - HRESULT hr = base::win::RoGetActivationFactory( - spatial_locator_string.get(), IID_PPV_ARGS(&spatial_locator_statics)); - if (FAILED(hr)) { - device::WMRLogging::TraceError(device::WMRErrorLocation::kGetSpatialLocator, - hr); - return nullptr; - } - - ComPtr<ISpatialLocator> locator; - hr = spatial_locator_statics->GetDefault(&locator); - if (FAILED(hr)) { - device::WMRLogging::TraceError(device::WMRErrorLocation::kGetSpatialLocator, - hr); - return nullptr; - } - - return locator; -} -} // anonymous namespace - namespace device { // WMRCoordinateSystem -WMRCoordinateSystem::WMRCoordinateSystem( +WMRCoordinateSystemImpl::WMRCoordinateSystemImpl( ComPtr<ISpatialCoordinateSystem> coordinates) : coordinates_(coordinates) { DCHECK(coordinates_); } -WMRCoordinateSystem::WMRCoordinateSystem() {} +WMRCoordinateSystemImpl::~WMRCoordinateSystemImpl() = default; -WMRCoordinateSystem::~WMRCoordinateSystem() = default; - -bool WMRCoordinateSystem::TryGetTransformTo(const WMRCoordinateSystem* other, - WFN::Matrix4x4* this_to_other) { +bool WMRCoordinateSystemImpl::TryGetTransformTo( + const WMRCoordinateSystem* other, + WFN::Matrix4x4* this_to_other) { DCHECK(this_to_other); DCHECK(other); ComPtr<IReference<WFN::Matrix4x4>> this_to_other_ref; @@ -92,109 +65,66 @@ return true; } -ISpatialCoordinateSystem* WMRCoordinateSystem::GetRawPtr() const { +ISpatialCoordinateSystem* WMRCoordinateSystemImpl::GetRawPtr() const { return coordinates_.Get(); } // WMRStationaryOrigin -std::unique_ptr<WMRStationaryOrigin> -WMRStationaryOrigin::CreateAtCurrentLocation() { - if (MixedRealityDeviceStatics::GetLockedTestHook().GetHook()) { - return std::make_unique<MockWMRStationaryOrigin>(); - } - ComPtr<ISpatialLocator> locator = GetSpatialLocator(); - if (!locator) - return nullptr; - - ComPtr<ISpatialStationaryFrameOfReference> origin; - HRESULT hr = - locator->CreateStationaryFrameOfReferenceAtCurrentLocation(&origin); - if (FAILED(hr)) { - WMRLogging::TraceError(WMRErrorLocation::kStationaryReferenceCreation, hr); - return nullptr; - } - - return std::make_unique<WMRStationaryOrigin>(origin); -} - -WMRStationaryOrigin::WMRStationaryOrigin( +WMRStationaryOriginImpl::WMRStationaryOriginImpl( ComPtr<ISpatialStationaryFrameOfReference> stationary_origin) : stationary_origin_(stationary_origin) { DCHECK(stationary_origin_); } -WMRStationaryOrigin::WMRStationaryOrigin() {} +WMRStationaryOriginImpl::~WMRStationaryOriginImpl() = default; -WMRStationaryOrigin::~WMRStationaryOrigin() = default; - -std::unique_ptr<WMRCoordinateSystem> WMRStationaryOrigin::CoordinateSystem() { +std::unique_ptr<WMRCoordinateSystem> +WMRStationaryOriginImpl::CoordinateSystem() { ComPtr<ISpatialCoordinateSystem> coordinates; HRESULT hr = stationary_origin_->get_CoordinateSystem(&coordinates); DCHECK(SUCCEEDED(hr)); - return std::make_unique<WMRCoordinateSystem>(coordinates); + return std::make_unique<WMRCoordinateSystemImpl>(coordinates); } // WMRAttachedOrigin -std::unique_ptr<WMRAttachedOrigin> -WMRAttachedOrigin::CreateAtCurrentLocation() { - if (MixedRealityDeviceStatics::GetLockedTestHook().GetHook()) { - return std::make_unique<MockWMRAttachedOrigin>(); - } - ComPtr<ISpatialLocator> locator = GetSpatialLocator(); - if (!locator) - return nullptr; - - ComPtr<ISpatialLocatorAttachedFrameOfReference> origin; - HRESULT hr = locator->CreateAttachedFrameOfReferenceAtCurrentHeading(&origin); - if (FAILED(hr)) { - WMRLogging::TraceError(WMRErrorLocation::kAttachedReferenceCreation, hr); - return nullptr; - } - - return std::make_unique<WMRAttachedOrigin>(origin); -} - -WMRAttachedOrigin::WMRAttachedOrigin( +WMRAttachedOriginImpl::WMRAttachedOriginImpl( ComPtr<ISpatialLocatorAttachedFrameOfReference> attached_origin) : attached_origin_(attached_origin) { DCHECK(attached_origin_); } -WMRAttachedOrigin::WMRAttachedOrigin() {} - -WMRAttachedOrigin::~WMRAttachedOrigin() = default; +WMRAttachedOriginImpl::~WMRAttachedOriginImpl() = default; std::unique_ptr<WMRCoordinateSystem> -WMRAttachedOrigin::TryGetCoordinatesAtTimestamp(const WMRTimestamp* timestamp) { +WMRAttachedOriginImpl::TryGetCoordinatesAtTimestamp( + const WMRTimestamp* timestamp) { ComPtr<ISpatialCoordinateSystem> coordinates; HRESULT hr = attached_origin_->GetStationaryCoordinateSystemAtTimestamp( timestamp->GetRawPtr(), &coordinates); if (FAILED(hr)) return nullptr; - return std::make_unique<WMRCoordinateSystem>(coordinates); + return std::make_unique<WMRCoordinateSystemImpl>(coordinates); } // WMRStageOrigin -WMRStageOrigin::WMRStageOrigin( +WMRStageOriginImpl::WMRStageOriginImpl( ComPtr<ISpatialStageFrameOfReference> stage_origin) : stage_origin_(stage_origin) { DCHECK(stage_origin_); } -WMRStageOrigin::WMRStageOrigin() {} +WMRStageOriginImpl::~WMRStageOriginImpl() = default; -WMRStageOrigin::~WMRStageOrigin() = default; - -std::unique_ptr<WMRCoordinateSystem> WMRStageOrigin::CoordinateSystem() { +std::unique_ptr<WMRCoordinateSystem> WMRStageOriginImpl::CoordinateSystem() { ComPtr<ISpatialCoordinateSystem> coordinates; HRESULT hr = stage_origin_->get_CoordinateSystem(&coordinates); DCHECK(SUCCEEDED(hr)); - return std::make_unique<WMRCoordinateSystem>(coordinates); + return std::make_unique<WMRCoordinateSystemImpl>(coordinates); } -SpatialMovementRange WMRStageOrigin::MovementRange() { +SpatialMovementRange WMRStageOriginImpl::MovementRange() { SpatialMovementRange movement_range; HRESULT hr = stage_origin_->get_MovementRange(&movement_range); DCHECK(SUCCEEDED(hr)); @@ -202,7 +132,7 @@ return movement_range; } -std::vector<WFN::Vector3> WMRStageOrigin::GetMovementBounds( +std::vector<WFN::Vector3> WMRStageOriginImpl::GetMovementBounds( const WMRCoordinateSystem* coordinates) { DCHECK(coordinates); @@ -222,48 +152,26 @@ } // WMRStageStatics -std::unique_ptr<WMRStageStatics> WMRStageStatics::Create() { - if (MixedRealityDeviceStatics::GetLockedTestHook().GetHook()) - return std::make_unique<MockWMRStageStatics>(); - ComPtr<ISpatialStageFrameOfReferenceStatics> stage_statics; - base::win::ScopedHString spatial_stage_string = - base::win::ScopedHString::Create( - RuntimeClass_Windows_Perception_Spatial_SpatialStageFrameOfReference); - HRESULT hr = base::win::RoGetActivationFactory(spatial_stage_string.get(), - IID_PPV_ARGS(&stage_statics)); - if (FAILED(hr)) - return nullptr; - - return std::make_unique<WMRStageStatics>(stage_statics); -} - -WMRStageStatics::WMRStageStatics( +WMRStageStaticsImpl::WMRStageStaticsImpl( ComPtr<ISpatialStageFrameOfReferenceStatics> stage_statics) : stage_statics_(stage_statics) { DCHECK(stage_statics_); auto callback = Microsoft::WRL::Callback<IEventHandler<IInspectable*>>( - this, &WMRStageStatics::OnCurrentChanged); + this, &WMRStageStaticsImpl::OnCurrentChanged); HRESULT hr = stage_statics_->add_CurrentChanged(callback.Get(), &stage_changed_token_); DCHECK(SUCCEEDED(hr)); } -WMRStageStatics::WMRStageStatics() {} - -WMRStageStatics::~WMRStageStatics() { - DCHECK(dispose_called_); -} - -void WMRStageStatics::Dispose() { +WMRStageStaticsImpl::~WMRStageStaticsImpl() { if (stage_changed_token_.value != 0) { HRESULT hr = stage_statics_->remove_CurrentChanged(stage_changed_token_); stage_changed_token_.value = 0; DCHECK(SUCCEEDED(hr)); } - dispose_called_ = true; } -std::unique_ptr<WMRStageOrigin> WMRStageStatics::CurrentStage() { +std::unique_ptr<WMRStageOrigin> WMRStageStaticsImpl::CurrentStage() { ComPtr<ISpatialStageFrameOfReference> stage_origin; HRESULT hr = stage_statics_->get_Current(&stage_origin); if (FAILED(hr) || !stage_origin) { @@ -271,16 +179,16 @@ return nullptr; } - return std::make_unique<WMRStageOrigin>(stage_origin); + return std::make_unique<WMRStageOriginImpl>(stage_origin); } std::unique_ptr<base::CallbackList<void()>::Subscription> -WMRStageStatics::AddStageChangedCallback( +WMRStageStaticsImpl::AddStageChangedCallback( const base::RepeatingCallback<void()>& cb) { return callback_list_.Add(cb); } -HRESULT WMRStageStatics::OnCurrentChanged(IInspectable*, IInspectable*) { +HRESULT WMRStageStaticsImpl::OnCurrentChanged(IInspectable*, IInspectable*) { callback_list_.Notify(); return S_OK; }
diff --git a/device/vr/windows_mixed_reality/wrappers/wmr_origins.h b/device/vr/windows_mixed_reality/wrappers/wmr_origins.h index 1c64489..375c9c2 100644 --- a/device/vr/windows_mixed_reality/wrappers/wmr_origins.h +++ b/device/vr/windows_mixed_reality/wrappers/wmr_origins.h
@@ -18,127 +18,147 @@ class WMRCoordinateSystem { public: - explicit WMRCoordinateSystem( + virtual ~WMRCoordinateSystem() = default; + virtual bool TryGetTransformTo( + const WMRCoordinateSystem* other, + ABI::Windows::Foundation::Numerics::Matrix4x4* this_to_other) = 0; + + virtual ABI::Windows::Perception::Spatial::ISpatialCoordinateSystem* + GetRawPtr() const = 0; +}; + +class WMRCoordinateSystemImpl : public WMRCoordinateSystem { + public: + explicit WMRCoordinateSystemImpl( Microsoft::WRL::ComPtr< ABI::Windows::Perception::Spatial::ISpatialCoordinateSystem> coordinates); - virtual ~WMRCoordinateSystem(); + ~WMRCoordinateSystemImpl() override; - virtual bool TryGetTransformTo( + bool TryGetTransformTo( const WMRCoordinateSystem* other, - ABI::Windows::Foundation::Numerics::Matrix4x4* this_to_other); + ABI::Windows::Foundation::Numerics::Matrix4x4* this_to_other) override; ABI::Windows::Perception::Spatial::ISpatialCoordinateSystem* GetRawPtr() - const; - - protected: - // Necessary so subclasses don't call the explicit constructor. - WMRCoordinateSystem(); + const override; private: Microsoft::WRL::ComPtr< ABI::Windows::Perception::Spatial::ISpatialCoordinateSystem> coordinates_; - DISALLOW_COPY_AND_ASSIGN(WMRCoordinateSystem); + DISALLOW_COPY_AND_ASSIGN(WMRCoordinateSystemImpl); }; class WMRStationaryOrigin { public: - static std::unique_ptr<WMRStationaryOrigin> CreateAtCurrentLocation(); - explicit WMRStationaryOrigin( + virtual ~WMRStationaryOrigin() = default; + + virtual std::unique_ptr<WMRCoordinateSystem> CoordinateSystem() = 0; +}; + +class WMRStationaryOriginImpl : public WMRStationaryOrigin { + public: + explicit WMRStationaryOriginImpl( Microsoft::WRL::ComPtr< ABI::Windows::Perception::Spatial::ISpatialStationaryFrameOfReference> stationary_origin); - virtual ~WMRStationaryOrigin(); + ~WMRStationaryOriginImpl() override; - virtual std::unique_ptr<WMRCoordinateSystem> CoordinateSystem(); - - protected: - // Necessary so subclasses don't call the explicit constructor. - WMRStationaryOrigin(); + std::unique_ptr<WMRCoordinateSystem> CoordinateSystem() override; private: Microsoft::WRL::ComPtr< ABI::Windows::Perception::Spatial::ISpatialStationaryFrameOfReference> stationary_origin_; - DISALLOW_COPY_AND_ASSIGN(WMRStationaryOrigin); + DISALLOW_COPY_AND_ASSIGN(WMRStationaryOriginImpl); }; class WMRAttachedOrigin { public: - static std::unique_ptr<WMRAttachedOrigin> CreateAtCurrentLocation(); - explicit WMRAttachedOrigin( + virtual ~WMRAttachedOrigin() = default; + + virtual std::unique_ptr<WMRCoordinateSystem> TryGetCoordinatesAtTimestamp( + const WMRTimestamp* timestamp) = 0; +}; + +class WMRAttachedOriginImpl : public WMRAttachedOrigin { + public: + explicit WMRAttachedOriginImpl( Microsoft::WRL::ComPtr<ABI::Windows::Perception::Spatial:: ISpatialLocatorAttachedFrameOfReference> attached_origin); - virtual ~WMRAttachedOrigin(); + ~WMRAttachedOriginImpl() override; - virtual std::unique_ptr<WMRCoordinateSystem> TryGetCoordinatesAtTimestamp( - const WMRTimestamp* timestamp); - - protected: - // Necessary so subclasses don't call the explicit constructor. - WMRAttachedOrigin(); + std::unique_ptr<WMRCoordinateSystem> TryGetCoordinatesAtTimestamp( + const WMRTimestamp* timestamp) override; private: Microsoft::WRL::ComPtr<ABI::Windows::Perception::Spatial:: ISpatialLocatorAttachedFrameOfReference> attached_origin_; - DISALLOW_COPY_AND_ASSIGN(WMRAttachedOrigin); + DISALLOW_COPY_AND_ASSIGN(WMRAttachedOriginImpl); }; class WMRStageOrigin { public: - static std::unique_ptr<WMRStageOrigin> CreateAtCurrentLocation(); - explicit WMRStageOrigin( - Microsoft::WRL::ComPtr< - ABI::Windows::Perception::Spatial::ISpatialStageFrameOfReference> - stage_origin); - virtual ~WMRStageOrigin(); + virtual ~WMRStageOrigin() = default; - virtual std::unique_ptr<WMRCoordinateSystem> CoordinateSystem(); + virtual std::unique_ptr<WMRCoordinateSystem> CoordinateSystem() = 0; virtual ABI::Windows::Perception::Spatial::SpatialMovementRange - MovementRange(); + MovementRange() = 0; // This will return an empty array if no bounds are set. virtual std::vector<ABI::Windows::Foundation::Numerics::Vector3> - GetMovementBounds(const WMRCoordinateSystem* coordinates); + GetMovementBounds(const WMRCoordinateSystem* coordinates) = 0; +}; - protected: - // Necessary so subclasses don't call the explicit constructor. - WMRStageOrigin(); +class WMRStageOriginImpl : public WMRStageOrigin { + public: + explicit WMRStageOriginImpl( + Microsoft::WRL::ComPtr< + ABI::Windows::Perception::Spatial::ISpatialStageFrameOfReference> + stage_origin); + ~WMRStageOriginImpl() override; + + std::unique_ptr<WMRCoordinateSystem> CoordinateSystem() override; + ABI::Windows::Perception::Spatial::SpatialMovementRange MovementRange() + override; + std::vector<ABI::Windows::Foundation::Numerics::Vector3> GetMovementBounds( + const WMRCoordinateSystem* coordinates) override; private: Microsoft::WRL::ComPtr< ABI::Windows::Perception::Spatial::ISpatialStageFrameOfReference> stage_origin_; - DISALLOW_COPY_AND_ASSIGN(WMRStageOrigin); + DISALLOW_COPY_AND_ASSIGN(WMRStageOriginImpl); }; class WMRStageStatics { public: - static std::unique_ptr<WMRStageStatics> Create(); - explicit WMRStageStatics( + virtual ~WMRStageStatics() = default; + + virtual std::unique_ptr<WMRStageOrigin> CurrentStage() = 0; + + virtual std::unique_ptr<base::CallbackList<void()>::Subscription> + AddStageChangedCallback(const base::RepeatingCallback<void()>& cb) = 0; +}; + +class WMRStageStaticsImpl : public WMRStageStatics { + public: + explicit WMRStageStaticsImpl( Microsoft::WRL::ComPtr<ABI::Windows::Perception::Spatial:: ISpatialStageFrameOfReferenceStatics> stage_statics); - virtual ~WMRStageStatics(); + ~WMRStageStaticsImpl() override; - virtual std::unique_ptr<WMRStageOrigin> CurrentStage(); + std::unique_ptr<WMRStageOrigin> CurrentStage() override; std::unique_ptr<base::CallbackList<void()>::Subscription> - AddStageChangedCallback(const base::RepeatingCallback<void()>& cb); - - virtual void Dispose(); - - protected: - // Necessary so subclasses don't call the explicit constructor. - WMRStageStatics(); - bool dispose_called_ = false; + AddStageChangedCallback(const base::RepeatingCallback<void()>& cb) override; private: HRESULT OnCurrentChanged(IInspectable* sender, IInspectable* args); @@ -149,7 +169,7 @@ EventRegistrationToken stage_changed_token_; base::CallbackList<void()> callback_list_; - DISALLOW_COPY_AND_ASSIGN(WMRStageStatics); + DISALLOW_COPY_AND_ASSIGN(WMRStageStaticsImpl); }; } // namespace device
diff --git a/device/vr/windows_mixed_reality/wrappers/wmr_wrapper_factories.cc b/device/vr/windows_mixed_reality/wrappers/wmr_wrapper_factories.cc new file mode 100644 index 0000000..25c2b4aa --- /dev/null +++ b/device/vr/windows_mixed_reality/wrappers/wmr_wrapper_factories.cc
@@ -0,0 +1,118 @@ +// 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 "device/vr/windows_mixed_reality/wrappers/wmr_wrapper_factories.h" + +#include <windows.perception.spatial.h> +#include <wrl.h> + +#include "base/strings/string_util.h" +#include "base/win/core_winrt_util.h" +#include "base/win/scoped_hstring.h" +#include "device/vr/windows_mixed_reality/mixed_reality_statics.h" +#include "device/vr/windows_mixed_reality/wrappers/test/mock_wmr_origins.h" +#include "device/vr/windows_mixed_reality/wrappers/wmr_logging.h" + +namespace WFN = ABI::Windows::Foundation::Numerics; +using SpatialMovementRange = + ABI::Windows::Perception::Spatial::SpatialMovementRange; +using ABI::Windows::Foundation::IEventHandler; +using ABI::Windows::Foundation::IReference; +using ABI::Windows::Perception::Spatial::ISpatialCoordinateSystem; +using ABI::Windows::Perception::Spatial::ISpatialLocator; +using ABI::Windows::Perception::Spatial:: + ISpatialLocatorAttachedFrameOfReference; +using ABI::Windows::Perception::Spatial::ISpatialLocatorStatics; +using ABI::Windows::Perception::Spatial::ISpatialStageFrameOfReference; +using ABI::Windows::Perception::Spatial::ISpatialStageFrameOfReferenceStatics; +using ABI::Windows::Perception::Spatial::ISpatialStationaryFrameOfReference; +using Microsoft::WRL::ComPtr; + +namespace { +ComPtr<ISpatialLocator> GetSpatialLocator() { + ComPtr<ISpatialLocatorStatics> spatial_locator_statics; + base::win::ScopedHString spatial_locator_string = + base::win::ScopedHString::Create( + RuntimeClass_Windows_Perception_Spatial_SpatialLocator); + HRESULT hr = base::win::RoGetActivationFactory( + spatial_locator_string.get(), IID_PPV_ARGS(&spatial_locator_statics)); + if (FAILED(hr)) { + device::WMRLogging::TraceError(device::WMRErrorLocation::kGetSpatialLocator, + hr); + return nullptr; + } + + ComPtr<ISpatialLocator> locator; + hr = spatial_locator_statics->GetDefault(&locator); + if (FAILED(hr)) { + device::WMRLogging::TraceError(device::WMRErrorLocation::kGetSpatialLocator, + hr); + return nullptr; + } + + return locator; +} +} // anonymous namespace + +namespace device { + +std::unique_ptr<WMRStationaryOrigin> +WMRStationaryOriginFactory::CreateAtCurrentLocation() { + if (MixedRealityDeviceStatics::ShouldUseMocks()) { + return std::make_unique<MockWMRStationaryOrigin>(); + } + + ComPtr<ISpatialLocator> locator = GetSpatialLocator(); + if (!locator) + return nullptr; + + ComPtr<ISpatialStationaryFrameOfReference> origin; + HRESULT hr = + locator->CreateStationaryFrameOfReferenceAtCurrentLocation(&origin); + if (FAILED(hr)) { + WMRLogging::TraceError(WMRErrorLocation::kStationaryReferenceCreation, hr); + return nullptr; + } + + return std::make_unique<WMRStationaryOriginImpl>(origin); +} + +std::unique_ptr<WMRAttachedOrigin> +WMRAttachedOriginFactory::CreateAtCurrentLocation() { + if (MixedRealityDeviceStatics::ShouldUseMocks()) { + return std::make_unique<MockWMRAttachedOrigin>(); + } + + ComPtr<ISpatialLocator> locator = GetSpatialLocator(); + if (!locator) + return nullptr; + + ComPtr<ISpatialLocatorAttachedFrameOfReference> origin; + HRESULT hr = locator->CreateAttachedFrameOfReferenceAtCurrentHeading(&origin); + if (FAILED(hr)) { + WMRLogging::TraceError(WMRErrorLocation::kAttachedReferenceCreation, hr); + return nullptr; + } + + return std::make_unique<WMRAttachedOriginImpl>(origin); +} + +std::unique_ptr<WMRStageStatics> WMRStageStaticsFactory::Create() { + if (MixedRealityDeviceStatics::ShouldUseMocks()) { + return std::make_unique<MockWMRStageStatics>(); + } + + ComPtr<ISpatialStageFrameOfReferenceStatics> stage_statics; + base::win::ScopedHString spatial_stage_string = + base::win::ScopedHString::Create( + RuntimeClass_Windows_Perception_Spatial_SpatialStageFrameOfReference); + HRESULT hr = base::win::RoGetActivationFactory(spatial_stage_string.get(), + IID_PPV_ARGS(&stage_statics)); + if (FAILED(hr)) + return nullptr; + + return std::make_unique<WMRStageStaticsImpl>(stage_statics); +} + +} // namespace device
diff --git a/device/vr/windows_mixed_reality/wrappers/wmr_wrapper_factories.h b/device/vr/windows_mixed_reality/wrappers/wmr_wrapper_factories.h new file mode 100644 index 0000000..9104eeb --- /dev/null +++ b/device/vr/windows_mixed_reality/wrappers/wmr_wrapper_factories.h
@@ -0,0 +1,28 @@ +// 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 DEVICE_VR_WINDOWS_MIXED_REALITY_WRAPPERS_WMR_WRAPPER_FACTORIES_H_ +#define DEVICE_VR_WINDOWS_MIXED_REALITY_WRAPPERS_WMR_WRAPPER_FACTORIES_H_ + +#include "device/vr/windows_mixed_reality/wrappers/wmr_origins.h" + +namespace device { + +class WMRStationaryOriginFactory { + public: + static std::unique_ptr<WMRStationaryOrigin> CreateAtCurrentLocation(); +}; + +class WMRAttachedOriginFactory { + public: + static std::unique_ptr<WMRAttachedOrigin> CreateAtCurrentLocation(); +}; + +class WMRStageStaticsFactory { + public: + static std::unique_ptr<WMRStageStatics> Create(); +}; + +} // namespace device + +#endif // DEVICE_VR_WINDOWS_MIXED_REALITY_WRAPPERS_WMR_WRAPPER_FACTORIES_H_
diff --git a/extensions/browser/guest_view/extension_view/whitelist/OWNERS b/extensions/browser/guest_view/extension_view/whitelist/OWNERS index 548f26b2..c7ff256 100644 --- a/extensions/browser/guest_view/extension_view/whitelist/OWNERS +++ b/extensions/browser/guest_view/extension_view/whitelist/OWNERS
@@ -2,11 +2,7 @@ # chrome-eng-review@google.com. set noparent -ben@chromium.org -cpu@chromium.org -darin@chromium.org -jam@chromium.org -jochen@chromium.org +file://ENG_REVIEW_OWNERS # TEAM: extensions-dev@chromium.org # COMPONENT: Platform>Extensions
diff --git a/extensions/browser/url_loader_factory_manager.cc b/extensions/browser/url_loader_factory_manager.cc index 0bac1fb..7da47628 100644 --- a/extensions/browser/url_loader_factory_manager.cc +++ b/extensions/browser/url_loader_factory_manager.cc
@@ -173,6 +173,7 @@ "95E78675D2DB61DC688586CD7A24202A260907A4", "965A185A30475F208A7365E134F48C64CF08C997", "973E35633030AD27DABEC99609424A61386C7309", + "9784343657207FE88A629E8EAA7A4A19C7C8CBE0", "97E04C5632954E778306CAC40B3F95C470B463B6", "98EF7B1601119AEE1FCC28EE5CE247DED5676539", "999BD8D1929F9ABB817E9368480D93BAB2A0983D",
diff --git a/extensions/common/api/_api_features.json b/extensions/common/api/_api_features.json index 7970fc16..aef11c58 100644 --- a/extensions/common/api/_api_features.json +++ b/extensions/common/api/_api_features.json
@@ -229,6 +229,8 @@ "channel": "stable", "contexts": ["webui"], "matches": [ + "chrome://add-supervision/*", + "chrome://assistant-optin/*", "chrome://cast/*", "chrome://discards/*", "chrome://extensions-frame/*", @@ -239,8 +241,7 @@ "chrome://media-router/*", "chrome://mobilesetup/*", "chrome://oobe/*", - "chrome://password-change/*", - "chrome://assistant-optin/*" + "chrome://password-change/*" ] } ], @@ -624,6 +625,8 @@ "internal": true, "contexts": ["webui"], "matches": [ + "chrome://add-supervision/*", + "chrome://assistant-optin/*", "chrome://chrome-signin/*", "chrome://discards/*", "chrome://hats/*", @@ -631,8 +634,7 @@ "chrome://media-router/*", "chrome://mobilesetup/*", "chrome://oobe/*", - "chrome://password-change/*", - "chrome://assistant-optin/*" + "chrome://password-change/*" ] }], "webViewInternal": [{ @@ -644,6 +646,8 @@ "channel": "stable", "contexts": ["webui"], "matches": [ + "chrome://add-supervision/*", + "chrome://assistant-optin/*", "chrome://chrome-signin/*", "chrome://discards/*", "chrome://hats/*", @@ -651,8 +655,7 @@ "chrome://media-router/*", "chrome://mobilesetup/*", "chrome://oobe/*", - "chrome://password-change/*", - "chrome://assistant-optin/*" + "chrome://password-change/*" ] }], "webViewRequest": [{ @@ -662,14 +665,15 @@ "channel": "stable", "contexts": ["webui"], "matches": [ + "chrome://add-supervision/*", + "chrome://assistant-optin/*", "chrome://chrome-signin/*", "chrome://discards/*", "chrome://hats/*", "chrome://home/*", "chrome://media-router/*", "chrome://mobilesetup/*", - "chrome://oobe/*", - "chrome://assistant-optin/*" + "chrome://oobe/*" ] }] }
diff --git a/extensions/common/extensions_client.h b/extensions/common/extensions_client.h index 9491fb6..247458c1 100644 --- a/extensions/common/extensions_client.h +++ b/extensions/common/extensions_client.h
@@ -113,11 +113,6 @@ // (i.e., only logged) or allowed (i.e., logged before crashing). virtual bool ShouldSuppressFatalErrors() const = 0; - // Records that a fatal error was caught and suppressed. It is expected that - // embedders will only do so if ShouldSuppressFatalErrors at some point - // returned true. - virtual void RecordDidSuppressFatalError() = 0; - // Returns the base webstore URL prefix. virtual const GURL& GetWebstoreBaseURL() const = 0;
diff --git a/extensions/renderer/module_system.cc b/extensions/renderer/module_system.cc index d1d76376..c79a234 100644 --- a/extensions/renderer/module_system.cc +++ b/extensions/renderer/module_system.cc
@@ -63,7 +63,6 @@ if (client->ShouldSuppressFatalErrors()) { console::AddMessage(context, blink::mojom::ConsoleMessageLevel::kError, full_message); - client->RecordDidSuppressFatalError(); } else { console::Fatal(context, full_message); }
diff --git a/extensions/shell/common/shell_extensions_client.cc b/extensions/shell/common/shell_extensions_client.cc index a4f5623..df6bcb64 100644 --- a/extensions/shell/common/shell_extensions_client.cc +++ b/extensions/shell/common/shell_extensions_client.cc
@@ -126,9 +126,6 @@ return true; } -void ShellExtensionsClient::RecordDidSuppressFatalError() { -} - const GURL& ShellExtensionsClient::GetWebstoreBaseURL() const { return webstore_base_url_; }
diff --git a/extensions/shell/common/shell_extensions_client.h b/extensions/shell/common/shell_extensions_client.h index 32766c4..be07796 100644 --- a/extensions/shell/common/shell_extensions_client.h +++ b/extensions/shell/common/shell_extensions_client.h
@@ -34,7 +34,6 @@ const APIPermissionSet& api_permissions) const override; bool IsScriptableURL(const GURL& url, std::string* error) const override; bool ShouldSuppressFatalErrors() const override; - void RecordDidSuppressFatalError() override; const GURL& GetWebstoreBaseURL() const override; const GURL& GetWebstoreUpdateURL() const override; bool IsBlacklistUpdateURL(const GURL& url) const override;
diff --git a/extensions/test/test_extensions_client.cc b/extensions/test/test_extensions_client.cc index 5591d8b..7f5ac2f21 100644 --- a/extensions/test/test_extensions_client.cc +++ b/extensions/test/test_extensions_client.cc
@@ -93,9 +93,6 @@ return true; } -void TestExtensionsClient::RecordDidSuppressFatalError() { -} - const GURL& TestExtensionsClient::GetWebstoreBaseURL() const { return webstore_base_url_; }
diff --git a/extensions/test/test_extensions_client.h b/extensions/test/test_extensions_client.h index b5c4fd0..725f504 100644 --- a/extensions/test/test_extensions_client.h +++ b/extensions/test/test_extensions_client.h
@@ -43,7 +43,6 @@ const APIPermissionSet& api_permissions) const override; bool IsScriptableURL(const GURL& url, std::string* error) const override; bool ShouldSuppressFatalErrors() const override; - void RecordDidSuppressFatalError() override; const GURL& GetWebstoreBaseURL() const override; const GURL& GetWebstoreUpdateURL() const override; bool IsBlacklistUpdateURL(const GURL& url) const override;
diff --git a/fuchsia/runners/cast/sandbox_policy b/fuchsia/runners/cast/sandbox_policy index 66fc0cfc..472c7dc 100644 --- a/fuchsia/runners/cast/sandbox_policy +++ b/fuchsia/runners/cast/sandbox_policy
@@ -5,6 +5,7 @@ "fuchsia.fonts.Provider", "fuchsia.logger.LogSink", "fuchsia.media.Audio", + "fuchsia.mediacodec.CodecFactory", "fuchsia.net.SocketProvider", "fuchsia.netstack.Netstack", "fuchsia.process.Launcher",
diff --git a/google_apis/gaia/gaia_constants.cc b/google_apis/gaia/gaia_constants.cc index 2be7414..72c9da4 100644 --- a/google_apis/gaia/gaia_constants.cc +++ b/google_apis/gaia/gaia_constants.cc
@@ -44,7 +44,7 @@ // OAuth2 scope for access to Google Family Link kid scope. const char kKidFamilyOAuth2Scope[] = - "https://www.googleapis.com/auth/kid.family"; + "https://www.googleapis.com/auth/kid.family.readonly"; // OAuth2 scope for access to Google Talk APIs (XMPP). const char kGoogleTalkOAuth2Scope[] =
diff --git a/gpu/vulkan/semaphore_handle.cc b/gpu/vulkan/semaphore_handle.cc index 00ee966..40f27530 100644 --- a/gpu/vulkan/semaphore_handle.cc +++ b/gpu/vulkan/semaphore_handle.cc
@@ -38,7 +38,7 @@ base::ScopedFD(HANDLE_EINTR(dup(handle_.get())))); #elif defined(OS_WIN) HANDLE handle_dup; - if (!::DuplicateHandle(::GetCurrentProcess(), handle_.get(), + if (!::DuplicateHandle(::GetCurrentProcess(), handle_.Get(), ::GetCurrentProcess(), &handle_dup, 0, FALSE, DUPLICATE_SAME_ACCESS)) { return SemaphoreHandle();
diff --git a/gpu/vulkan/semaphore_handle.h b/gpu/vulkan/semaphore_handle.h index c59ad7a..3b13824 100644 --- a/gpu/vulkan/semaphore_handle.h +++ b/gpu/vulkan/semaphore_handle.h
@@ -51,7 +51,13 @@ VkExternalSemaphoreHandleTypeFlagBits vk_handle_type() { return type_; } - bool is_valid() const { return handle_.is_valid(); } + bool is_valid() const { +#if defined(OS_WIN) + return handle_.IsValid(); +#else + return handle_.is_valid(); +#endif + } // Returns underlying platform-specific handle for the semaphore. is_valid() // becomes false after this function returns.
diff --git a/gpu/vulkan/vulkan_swap_chain.h b/gpu/vulkan/vulkan_swap_chain.h index 6abc635..73037337 100644 --- a/gpu/vulkan/vulkan_swap_chain.h +++ b/gpu/vulkan/vulkan_swap_chain.h
@@ -22,7 +22,7 @@ class VULKAN_EXPORT VulkanSwapChain { public: - class ScopedWrite { + class VULKAN_EXPORT ScopedWrite { public: explicit ScopedWrite(VulkanSwapChain* swap_chain); ~ScopedWrite();
diff --git a/infra/config/cr-buildbucket.cfg b/infra/config/cr-buildbucket.cfg index 6630774..1e40f44 100644 --- a/infra/config/cr-buildbucket.cfg +++ b/infra/config/cr-buildbucket.cfg
@@ -2088,6 +2088,10 @@ execution_timeout_secs: 64800 # 18h. } builders { + name: "Win10 FYI Release XR Perf (NVIDIA)" + mixins: "win-gpu-fyi-ci" + } + builders { name: "Win7 FYI Debug (AMD)" mixins: "win-gpu-fyi-ci" }
diff --git a/infra/config/luci-milo.cfg b/infra/config/luci-milo.cfg index 4177633..0140b71 100644 --- a/infra/config/luci-milo.cfg +++ b/infra/config/luci-milo.cfg
@@ -2846,6 +2846,11 @@ short_name: "gtx" } builders { + name: "buildbucket/luci.chromium.ci/Win10 FYI Release XR Perf (NVIDIA)" + category: "Windows|10|Nvidia" + short_name: "xr" + } + builders { name: "buildbucket/luci.chromium.ci/Win10 FYI Release (AMD RX 550)" category: "Windows|10|AMD" short_name: "rel"
diff --git a/infra/config/luci-scheduler.cfg b/infra/config/luci-scheduler.cfg index 0562b374..d9b90ff 100644 --- a/infra/config/luci-scheduler.cfg +++ b/infra/config/luci-scheduler.cfg
@@ -2852,6 +2852,17 @@ } job { + id: "Win10 FYI Release XR Perf (NVIDIA)" + # Triggered by "GPU FYI Win Builder" + acl_sets: "triggered-by-parent-builders" + buildbucket: { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "Win10 FYI Release XR Perf (NVIDIA)" + } +} + +job { id: "Win7 ANGLE Tryserver (AMD)" # Triggered by "GPU FYI Win Builder" acl_sets: "triggered-by-parent-builders"
diff --git a/ios/chrome/browser/send_tab_to_self/BUILD.gn b/ios/chrome/browser/send_tab_to_self/BUILD.gn index 2da9c10..9f352bd7 100644 --- a/ios/chrome/browser/send_tab_to_self/BUILD.gn +++ b/ios/chrome/browser/send_tab_to_self/BUILD.gn
@@ -11,6 +11,8 @@ "send_tab_to_self_client_service_factory.mm", "send_tab_to_self_client_service_ios.h", "send_tab_to_self_client_service_ios.mm", + "send_tab_to_self_util.h", + "send_tab_to_self_util.mm", ] deps = [ "//base", @@ -19,6 +21,7 @@ "//components/keyed_service/ios", "//components/send_tab_to_self", "//components/sync", + "//components/sync_device_info", "//ios/chrome/app/strings", "//ios/chrome/app/theme:theme_grit", "//ios/chrome/browser", @@ -36,3 +39,22 @@ "//ui/strings:ui_strings_grit", ] } + +source_set("unit_tests") { + configs += [ "//build/config/compiler:enable_arc" ] + testonly = true + sources = [ + "send_tab_to_self_util_unittest.mm", + ] + deps = [ + ":send_tab_to_self", + "//base", + "//base/test:test_support", + "//components/send_tab_to_self", + "//components/sync", + "//ios/chrome/browser/browser_state:test_support", + "//testing/gtest", + "//third_party/ocmock", + "//url", + ] +}
diff --git a/ios/chrome/browser/send_tab_to_self/send_tab_to_self_util.h b/ios/chrome/browser/send_tab_to_self/send_tab_to_self_util.h new file mode 100644 index 0000000..1dd284f --- /dev/null +++ b/ios/chrome/browser/send_tab_to_self/send_tab_to_self_util.h
@@ -0,0 +1,45 @@ +// 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 IOS_CHROME_BROWSER_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_UTIL_H_ +#define IOS_CHROME_BROWSER_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_UTIL_H_ + +class GURL; + +namespace ios { +class ChromeBrowserState; +} + +namespace send_tab_to_self { + +// Returns true if the 'send tab to self' flag is enabled. +bool IsReceivingEnabled(); + +// Returns true if the 'send-tab-to-self' and 'send-tab-to-self-show-sending-ui' +// flags are enabled. +bool IsSendingEnabled(); + +// Returns true if the SendTabToSelf sync datatype is active. +bool IsUserSyncTypeActive(ios::ChromeBrowserState* browser_state); + +// Returns true if the user syncing on two or more devices. +bool IsSyncingOnMultipleDevices(ios::ChromeBrowserState* browser_state); + +// Returns true if the tab and web content requirements are met: +// User is viewing an HTTP or HTTPS page. +// User is not on a native page. +// User is not in Incongnito mode. +bool IsContentRequirementsMet(const GURL& gurl, + ios::ChromeBrowserState* browser_state); + +// Returns true if all conditions are true and shows the option onto the menu. +bool ShouldOfferFeature(); + +// Add a new entry to SendTabToSelfModel when user click "Share to your +// devices" option. +void CreateNewEntry(ios::ChromeBrowserState* browser_state); + +} // namespace send_tab_to_self + +#endif // IOS_CHROME_BROWSER_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_UTIL_H_
diff --git a/ios/chrome/browser/send_tab_to_self/send_tab_to_self_util.mm b/ios/chrome/browser/send_tab_to_self/send_tab_to_self_util.mm new file mode 100644 index 0000000..2146ff91 --- /dev/null +++ b/ios/chrome/browser/send_tab_to_self/send_tab_to_self_util.mm
@@ -0,0 +1,143 @@ +// 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 "ios/chrome/browser/send_tab_to_self/send_tab_to_self_util.h" + +#include "base/strings/utf_string_conversions.h" +#include "components/send_tab_to_self/features.h" +#include "components/send_tab_to_self/send_tab_to_self_model.h" +#include "components/send_tab_to_self/send_tab_to_self_sync_service.h" +#include "components/sync/driver/sync_driver_switches.h" +#include "components/sync/driver/sync_service.h" +#include "components/sync/driver/sync_user_settings.h" +#include "components/sync_device_info/device_info.h" +#include "components/sync_device_info/device_info_sync_service.h" +#include "components/sync_device_info/device_info_tracker.h" +#include "ios/chrome/browser/application_context.h" +#include "ios/chrome/browser/browser_state/chrome_browser_state.h" +#include "ios/chrome/browser/browser_state/chrome_browser_state_manager.h" +#include "ios/chrome/browser/chrome_url_constants.h" +#include "ios/chrome/browser/send_tab_to_self/send_tab_to_self_client_service_factory.h" +#include "ios/chrome/browser/sync/device_info_sync_service_factory.h" +#include "ios/chrome/browser/sync/send_tab_to_self_sync_service_factory.h" +#import "ios/chrome/browser/tabs/tab_model.h" +#import "ios/chrome/browser/tabs/tab_model_list.h" +#import "ios/chrome/browser/web_state_list/web_state_list.h" +#import "ios/web/public/navigation_item.h" +#import "ios/web/public/web_state/web_state.h" + +#include "url/gurl.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace send_tab_to_self { + +bool IsReceivingEnabled() { + return base::FeatureList::IsEnabled(switches::kSyncSendTabToSelf); +} + +bool IsSendingEnabled() { + return IsReceivingEnabled() && + base::FeatureList::IsEnabled(kSendTabToSelfShowSendingUI); +} + +bool IsUserSyncTypeActive(ios::ChromeBrowserState* browser_state) { + SendTabToSelfSyncService* service = + SendTabToSelfSyncServiceFactory::GetForBrowserState(browser_state); + // The service will be null if the user is in incognito mode so better to + // check for that. + return service && service->GetSendTabToSelfModel() && + service->GetSendTabToSelfModel()->IsReady(); +} + +bool IsSyncingOnMultipleDevices(ios::ChromeBrowserState* browser_state) { + syncer::DeviceInfoSyncService* device_sync_service = + DeviceInfoSyncServiceFactory::GetForBrowserState(browser_state); + return device_sync_service && device_sync_service->GetDeviceInfoTracker() && + device_sync_service->GetDeviceInfoTracker()->CountActiveDevices() > 1; +} + +bool IsContentRequirementsMet(const GURL& url, + ios::ChromeBrowserState* browser_state) { + bool is_http_or_https = url.SchemeIsHTTPOrHTTPS(); + bool is_native_page = url.SchemeIs(kChromeUIScheme); + bool is_incognito_mode = browser_state->IsOffTheRecord(); + return is_http_or_https && !is_native_page && !is_incognito_mode; +} + +bool ShouldOfferFeature() { + ios::ChromeBrowserStateManager* browser_state_manager = + GetApplicationContext()->GetChromeBrowserStateManager(); + if (!browser_state_manager) { + // Can happen in tests. + return false; + } + + ios::ChromeBrowserState* browser_state = + browser_state_manager->GetLastUsedBrowserState(); + if (!browser_state) { + return false; + } + + // If there is no web state or it is not visible then nothing should be + // shared. + TabModel* tab_model = + TabModelList::GetLastActiveTabModelForChromeBrowserState(browser_state); + if (!tab_model) { + return false; + } + + WebStateList* web_state_list = tab_model.webStateList; + if (!web_state_list) { + return false; + } + + web::WebState* web_state = web_state_list->GetActiveWebState(); + + // If sending is enabled, then so is receiving. + return IsSendingEnabled() && IsUserSyncTypeActive(browser_state) && + IsSyncingOnMultipleDevices(browser_state) && + IsContentRequirementsMet(web_state->GetVisibleURL(), browser_state); +} + +void CreateNewEntry(ios::ChromeBrowserState* browser_state) { + // If there is no web state or it is not visible then nothing should be + // shared. + TabModel* tab_model = + TabModelList::GetLastActiveTabModelForChromeBrowserState(browser_state); + + WebStateList* web_state_list = tab_model.webStateList; + if (!web_state_list) { + return; + } + + web::WebState* web_state = web_state_list->GetActiveWebState(); + if (!web_state) { + return; + } + + web::NavigationItem* cur_item = + web_state->GetNavigationManager()->GetLastCommittedItem(); + if (!cur_item) { + return; + } + + GURL url = cur_item->GetURL(); + + std::string title = base::UTF16ToUTF8(cur_item->GetTitle()); + + base::Time navigation_time = cur_item->GetTimestamp(); + // TODO(crbug.com/946804) Add target device. + std::string target_device; + + SendTabToSelfModel* model = + SendTabToSelfSyncServiceFactory::GetForBrowserState(browser_state) + ->GetSendTabToSelfModel(); + + model->AddEntry(url, title, navigation_time, target_device); +} + +} // namespace send_tab_to_self
diff --git a/ios/chrome/browser/send_tab_to_self/send_tab_to_self_util_unittest.mm b/ios/chrome/browser/send_tab_to_self/send_tab_to_self_util_unittest.mm new file mode 100644 index 0000000..f1ce137 --- /dev/null +++ b/ios/chrome/browser/send_tab_to_self/send_tab_to_self_util_unittest.mm
@@ -0,0 +1,100 @@ +// 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 "ios/chrome/browser/send_tab_to_self/send_tab_to_self_util.h" + +#include "base/test/scoped_feature_list.h" +#include "base/test/scoped_task_environment.h" +#include "components/send_tab_to_self/features.h" +#include "components/sync/driver/sync_driver_switches.h" +#include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" +#import "testing/gtest_mac.h" +#include "testing/platform_test.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace send_tab_to_self { + +class SendTabToSelfUtilTest : public PlatformTest { + public: + SendTabToSelfUtilTest() { + TestChromeBrowserState::Builder builder; + browser_state_ = builder.Build(); + } + ~SendTabToSelfUtilTest() override {} + + ios::ChromeBrowserState* browser_state() { return browser_state_.get(); } + ios::ChromeBrowserState* OffTheRecordChromeBrowserState() { + return browser_state_->GetOffTheRecordChromeBrowserState(); + } + + protected: + base::test::ScopedFeatureList scoped_feature_list_; + base::test::ScopedTaskEnvironment scoped_task_environment_; + + private: + std::unique_ptr<ios::ChromeBrowserState> browser_state_; +}; + +TEST_F(SendTabToSelfUtilTest, AreFlagsEnabled) { + scoped_task_environment_.RunUntilIdle(); + scoped_feature_list_.InitWithFeatures( + {switches::kSyncSendTabToSelf, kSendTabToSelfShowSendingUI}, {}); + + EXPECT_TRUE(IsSendingEnabled()); + EXPECT_TRUE(IsReceivingEnabled()); +} + +TEST_F(SendTabToSelfUtilTest, AreFlagsDisabled) { + scoped_task_environment_.RunUntilIdle(); + scoped_feature_list_.InitWithFeatures( + {}, {switches::kSyncSendTabToSelf, kSendTabToSelfShowSendingUI}); + + EXPECT_FALSE(IsSendingEnabled()); + EXPECT_FALSE(IsReceivingEnabled()); +} + +TEST_F(SendTabToSelfUtilTest, IsReceivingEnabled) { + scoped_task_environment_.RunUntilIdle(); + scoped_feature_list_.InitWithFeatures({switches::kSyncSendTabToSelf}, + {kSendTabToSelfShowSendingUI}); + + EXPECT_FALSE(IsSendingEnabled()); + EXPECT_TRUE(IsReceivingEnabled()); +} + +TEST_F(SendTabToSelfUtilTest, IsOnlySendingEnabled) { + scoped_task_environment_.RunUntilIdle(); + scoped_feature_list_.InitWithFeatures({kSendTabToSelfShowSendingUI}, + {switches::kSyncSendTabToSelf}); + + EXPECT_FALSE(IsSendingEnabled()); + EXPECT_FALSE(IsReceivingEnabled()); +} + +TEST_F(SendTabToSelfUtilTest, NotHTTPOrHTTPS) { + GURL url = GURL("192.168.0.0"); + EXPECT_FALSE(IsContentRequirementsMet(url, browser_state())); +} + +TEST_F(SendTabToSelfUtilTest, WebUIPage) { + GURL url = GURL("chrome://flags"); + EXPECT_FALSE(IsContentRequirementsMet(url, browser_state())); +} + +TEST_F(SendTabToSelfUtilTest, IncognitoMode) { + GURL url = GURL("https://www.google.com"); + EXPECT_FALSE(IsContentRequirementsMet(url, OffTheRecordChromeBrowserState())); +} + +TEST_F(SendTabToSelfUtilTest, ValidUrl) { + GURL url = GURL("https://www.google.com"); + EXPECT_TRUE(IsContentRequirementsMet(url, browser_state())); +} + +// TODO(crbug.com/961897) Add test for CreateNewEntry. + +} // namespace send_tab_to_self
diff --git a/ios/chrome/browser/ui/recent_tabs/BUILD.gn b/ios/chrome/browser/ui/recent_tabs/BUILD.gn index d783ff6..bef8e86 100644 --- a/ios/chrome/browser/ui/recent_tabs/BUILD.gn +++ b/ios/chrome/browser/ui/recent_tabs/BUILD.gn
@@ -126,7 +126,9 @@ ":recent_tabs_ui", "//base/test:test_support", "//components/strings", + "//ios/chrome/app:app_internal", "//ios/chrome/app/strings", + "//ios/chrome/browser/tabs", "//ios/chrome/browser/ui/authentication:eg_test_support", "//ios/chrome/browser/ui/history:history_ui", "//ios/chrome/browser/ui/table_view",
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_egtest.mm b/ios/chrome/browser/ui/recent_tabs/recent_tabs_egtest.mm index b49218b..520108b 100644 --- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_egtest.mm +++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_egtest.mm
@@ -10,6 +10,8 @@ #include "base/test/scoped_feature_list.h" #include "components/strings/grit/components_strings.h" +#import "ios/chrome/app/main_controller.h" +#import "ios/chrome/browser/tabs/tab_model.h" #import "ios/chrome/browser/ui/authentication/signin_earl_grey_ui.h" #import "ios/chrome/browser/ui/authentication/signin_earlgrey_utils.h" #import "ios/chrome/browser/ui/history/history_ui_constants.h" @@ -18,6 +20,7 @@ #import "ios/chrome/browser/ui/table_view/table_view_navigation_controller_constants.h" #include "ios/chrome/browser/ui/util/ui_util.h" #include "ios/chrome/grit/ios_strings.h" +#import "ios/chrome/test/app/chrome_test_util.h" #import "ios/chrome/test/app/tab_test_util.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" @@ -41,11 +44,23 @@ "<head><title>TestPageTitle</title></head><body>hello</body>"; NSString* const kTitleOfTestPage = @"TestPageTitle"; +// Closes all tabs in the normal TabModel. +void CloseAllNormalTabs() { + TabModel* tabModel = chrome_test_util::GetMainController() + .interfaceProvider.mainInterface.tabModel; + [tabModel closeAllTabs]; +} + // Makes sure at least one tab is opened and opens the recent tab panel. void OpenRecentTabsPanel() { // At least one tab is needed to be able to open the recent tabs panel. - if (chrome_test_util::GetMainTabCount() == 0) - CHROME_EG_ASSERT_NO_ERROR([ChromeEarlGrey openNewTab]); + if (chrome_test_util::IsIncognitoMode()) { + if (chrome_test_util::GetIncognitoTabCount() == 0) + CHROME_EG_ASSERT_NO_ERROR([ChromeEarlGrey openNewIncognitoTab]); + } else { + if (chrome_test_util::GetMainTabCount() == 0) + CHROME_EG_ASSERT_NO_ERROR([ChromeEarlGrey openNewTab]); + } [ChromeEarlGreyUI openToolsMenu]; [ChromeEarlGreyUI tapToolsMenuButton:RecentTabsMenuButton()]; @@ -123,6 +138,35 @@ testPageURL.GetContent())]; } +// Tests restoring a tab from incognito when the normal WebStateList is empty. +- (void)testRestoreTabFromIncognitoWithNoNormalTabsOpen { + const GURL testPageURL = web::test::HttpServer::MakeUrl(kURLOfTestPage); + + // Open the test page in a new tab. + CHROME_EG_ASSERT_NO_ERROR([ChromeEarlGrey loadURL:testPageURL]); + CHROME_EG_ASSERT_NO_ERROR( + [ChromeEarlGrey waitForWebViewContainingText:"hello"]); + + // Open a new incognito tab, then close the non-OTR tab. + CHROME_EG_ASSERT_NO_ERROR([ChromeEarlGrey openNewIncognitoTab]); + CloseAllNormalTabs(); + + // Open the Recent Tabs panel and check that the test page is present. + OpenRecentTabsPanel(); + [[EarlGrey selectElementWithMatcher:TitleOfTestPage()] + assertWithMatcher:grey_notNil()]; + + // Tap on the entry for the test page in the Recent Tabs panel and check that + // a tab containing the test page was opened in the main WebStateList. + GREYAssertTrue(chrome_test_util::GetMainTabCount() == 0, + @"Unexpected tabs in the main WebStateList"); + [[EarlGrey selectElementWithMatcher:TitleOfTestPage()] + performAction:grey_tap()]; + CHROME_EG_ASSERT_NO_ERROR([ChromeEarlGrey waitForMainTabCount:1]); + GREYAssertTrue(chrome_test_util::GetIncognitoTabCount() == 1, + @"Unexpected tab added to the incognito WebStateList"); +} + // Tests that tapping "Show Full History" open the history. - (void)testOpenHistory { OpenRecentTabsPanel();
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm index bbbca0d..f2ac8519 100644 --- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm +++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
@@ -899,7 +899,14 @@ base::UserMetricsAction("MobileRecentTabManagerRecentTabOpened")); new_tab_page_uma::RecordAction( self.browserState, new_tab_page_uma::ACTION_OPENED_RECENTLY_CLOSED_ENTRY); - RestoreTab(entry->id, self.restoredTabDisposition, self.browserState); + + // If RecentTabs is being displayed from incognito, the resulting tab will + // open in the corresponding normal BVC. Change the disposition to avoid + // clobbering any tabs. + WindowOpenDisposition disposition = + self.isIncognito ? WindowOpenDisposition::NEW_FOREGROUND_TAB + : self.restoredTabDisposition; + RestoreTab(entry->id, disposition, self.browserState); [self.presentationDelegate showActiveRegularTabFromRecentTabs]; }
diff --git a/ios/chrome/test/BUILD.gn b/ios/chrome/test/BUILD.gn index 349794f..585a884e 100644 --- a/ios/chrome/test/BUILD.gn +++ b/ios/chrome/test/BUILD.gn
@@ -170,6 +170,7 @@ "//ios/chrome/browser/reading_list:unit_tests", "//ios/chrome/browser/safe_mode:unit_tests", "//ios/chrome/browser/search_engines:unit_tests", + "//ios/chrome/browser/send_tab_to_self:unit_tests", "//ios/chrome/browser/sessions:unit_tests", "//ios/chrome/browser/signin:unit_tests", "//ios/chrome/browser/snapshots:unit_tests",
diff --git a/mojo/OWNERS b/mojo/OWNERS index 783cf55..23c057a 100644 --- a/mojo/OWNERS +++ b/mojo/OWNERS
@@ -1,4 +1,3 @@ -ben@chromium.org jam@chromium.org rockot@google.com sky@chromium.org
diff --git a/net/base/network_change_notifier_win.cc b/net/base/network_change_notifier_win.cc index 3393d9a..d93e5b9 100644 --- a/net/base/network_change_notifier_win.cc +++ b/net/base/network_change_notifier_win.cc
@@ -12,7 +12,10 @@ #include "base/logging.h" #include "base/macros.h" #include "base/metrics/histogram_macros.h" +#include "base/sequenced_task_runner.h" #include "base/single_thread_task_runner.h" +#include "base/task/post_task.h" +#include "base/task/task_traits.h" #include "base/task_runner_util.h" #include "base/threading/thread.h" #include "base/threading/thread_task_runner_handle.h" @@ -30,32 +33,18 @@ } // namespace -// Thread on which we can run DnsConfigService, which requires AssertIOAllowed -// to open registry keys and to handle FilePathWatcher updates. -class NetworkChangeNotifierWin::DnsConfigServiceThread : public base::Thread { - public: - DnsConfigServiceThread() : base::Thread("DnsConfigService") {} - - ~DnsConfigServiceThread() override { Stop(); } - - void Init() override { - service_ = DnsConfigService::CreateSystemService(); - service_->WatchConfig(base::Bind(&NetworkChangeNotifier::SetDnsConfig)); - } - - void CleanUp() override { service_.reset(); } - - private: - std::unique_ptr<DnsConfigService> service_; - - DISALLOW_COPY_AND_ASSIGN(DnsConfigServiceThread); -}; - NetworkChangeNotifierWin::NetworkChangeNotifierWin() : NetworkChangeNotifier(NetworkChangeCalculatorParamsWin()), is_watching_(false), sequential_failures_(0), - dns_config_service_thread_(new DnsConfigServiceThread()), + dns_config_service_runner_( + base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()})), + dns_config_service_( + DnsConfigService::CreateSystemService().release(), + // Ensure DnsConfigService lives on |dns_config_service_runner_| + // to prevent races where NetworkChangeNotifierWin outlives + // ScopedTaskEnvironment. https://crbug.com/938126 + base::OnTaskRunnerDeleter(dns_config_service_runner_)), last_computed_connection_type_(RecomputeCurrentConnectionType()), last_announced_offline_(last_computed_connection_type_ == CONNECTION_NONE), @@ -65,7 +54,7 @@ } NetworkChangeNotifierWin::~NetworkChangeNotifierWin() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (is_watching_) { CancelIPChangeNotify(&addr_overlapped_); addr_watcher_.StopWatching(); @@ -204,15 +193,15 @@ : NetworkChangeNotifier::CONNECTION_NONE; } -void NetworkChangeNotifierWin::RecomputeCurrentConnectionTypeOnDnsThread( - base::Callback<void(ConnectionType)> reply_callback) const { +void NetworkChangeNotifierWin::RecomputeCurrentConnectionTypeOnDnsSequence( + base::OnceCallback<void(ConnectionType)> reply_callback) const { // Unretained is safe in this call because this object owns the thread and the // thread is stopped in this object's destructor. base::PostTaskAndReplyWithResult( - dns_config_service_thread_->task_runner().get(), FROM_HERE, - base::Bind(&NetworkChangeNotifierWin::RecomputeCurrentConnectionType, - base::Unretained(this)), - reply_callback); + dns_config_service_runner_.get(), FROM_HERE, + base::BindOnce(&NetworkChangeNotifierWin::RecomputeCurrentConnectionType, + base::Unretained(this)), + std::move(reply_callback)); } NetworkChangeNotifier::ConnectionType @@ -228,19 +217,19 @@ } void NetworkChangeNotifierWin::OnObjectSignaled(HANDLE object) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(is_watching_); is_watching_ = false; // Start watching for the next address change. WatchForAddressChange(); - RecomputeCurrentConnectionTypeOnDnsThread(base::Bind( + RecomputeCurrentConnectionTypeOnDnsSequence(base::BindOnce( &NetworkChangeNotifierWin::NotifyObservers, weak_factory_.GetWeakPtr())); } void NetworkChangeNotifierWin::NotifyObservers(ConnectionType connection_type) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); SetCurrentConnectionType(connection_type); NotifyObserversOfIPAddressChange(); @@ -257,7 +246,7 @@ } void NetworkChangeNotifierWin::WatchForAddressChange() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!is_watching_); // NotifyAddrChange occasionally fails with ERROR_OPEN_FAILED for unknown @@ -287,7 +276,7 @@ // network change event, since network changes were not being observed in // that interval. if (sequential_failures_ > 0) { - RecomputeCurrentConnectionTypeOnDnsThread( + RecomputeCurrentConnectionTypeOnDnsSequence( base::Bind(&NetworkChangeNotifierWin::NotifyObservers, weak_factory_.GetWeakPtr())); } @@ -302,12 +291,13 @@ } bool NetworkChangeNotifierWin::WatchForAddressChangeInternal() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!dns_config_service_thread_->IsRunning()) { - dns_config_service_thread_->StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); - } + dns_config_service_runner_->PostTask( + FROM_HERE, base::BindOnce(&DnsConfigService::WatchConfig, + base::Unretained(dns_config_service_.get()), + base::BindRepeating( + &NetworkChangeNotifier::SetDnsConfig))); ResetEventIfSignaled(addr_overlapped_.hEvent); HANDLE handle = nullptr; @@ -320,7 +310,7 @@ } void NetworkChangeNotifierWin::NotifyParentOfConnectionTypeChange() { - RecomputeCurrentConnectionTypeOnDnsThread(base::Bind( + RecomputeCurrentConnectionTypeOnDnsSequence(base::BindOnce( &NetworkChangeNotifierWin::NotifyParentOfConnectionTypeChangeImpl, weak_factory_.GetWeakPtr())); }
diff --git a/net/base/network_change_notifier_win.h b/net/base/network_change_notifier_win.h index beef6ba..533c90ac 100644 --- a/net/base/network_change_notifier_win.h +++ b/net/base/network_change_notifier_win.h
@@ -12,17 +12,25 @@ #include "base/callback.h" #include "base/compiler_specific.h" #include "base/macros.h" +#include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" -#include "base/threading/thread_checker.h" +#include "base/sequence_checker.h" #include "base/timer/timer.h" #include "base/win/object_watcher.h" #include "net/base/net_export.h" #include "net/base/network_change_notifier.h" +namespace base { +class SequencedTaskRunner; +struct OnTaskRunnerDeleter; +} // namespace base + namespace net { -// NetworkChangeNotifierWin uses a ThreadChecker, as all its internal -// notification code must be called on the thread it is created and destroyed +class DnsConfigService; + +// NetworkChangeNotifierWin uses a SequenceChecker, as all its internal +// notification code must be called on the sequence it is created and destroyed // on. All the NetworkChangeNotifier methods it implements are threadsafe. class NET_EXPORT_PRIVATE NetworkChangeNotifierWin : public NetworkChangeNotifier, @@ -32,8 +40,8 @@ // Begins listening for a single subsequent address change. If it fails to // start watching, it retries on a timer. Must be called only once, on the - // thread |this| was created on. This cannot be called in the constructor, as - // WatchForAddressChangeInternal is mocked out in unit tests. + // sequence |this| was created on. This cannot be called in the constructor, + // as WatchForAddressChangeInternal is mocked out in unit tests. // TODO(mmenke): Consider making this function a part of the // NetworkChangeNotifier interface, so other subclasses can be // unit tested in similar fashion, as needed. @@ -48,30 +56,29 @@ int sequential_failures() { return sequential_failures_; } private: - class DnsConfigServiceThread; friend class NetworkChangeNotifierWinTest; // NetworkChangeNotifier methods: ConnectionType GetCurrentConnectionType() const override; // ObjectWatcher::Delegate methods: - // Must only be called on the thread |this| was created on. + // Must only be called on the sequence |this| was created on. void OnObjectSignaled(HANDLE object) override; // Does the actual work to determine the current connection type. // It is not thread safe, see crbug.com/324913. virtual ConnectionType RecomputeCurrentConnectionType() const; - // Calls RecomputeCurrentConnectionTypeImpl on the DNS thread and runs - // |reply_callback| with the type on the calling thread. - virtual void RecomputeCurrentConnectionTypeOnDnsThread( - base::Callback<void(ConnectionType)> reply_callback) const; + // Calls RecomputeCurrentConnectionTypeImpl on the DNS sequence and runs + // |reply_callback| with the type on the calling sequence. + virtual void RecomputeCurrentConnectionTypeOnDnsSequence( + base::OnceCallback<void(ConnectionType)> reply_callback) const; void SetCurrentConnectionType(ConnectionType connection_type); // Notifies IP address change observers of a change immediately, and notifies // network state change observers on a delay. Must only be called on the - // thread |this| was created on. + // sequence |this| was created on. void NotifyObservers(ConnectionType connection_type); // Forwards connection type notifications to parent class. @@ -80,14 +87,14 @@ // Tries to start listening for a single subsequent address change. Returns // false on failure. The caller is responsible for updating |is_watching_|. - // Virtual for unit tests. Must only be called on the thread |this| was + // Virtual for unit tests. Must only be called on the sequence |this| was // created on. virtual bool WatchForAddressChangeInternal(); static NetworkChangeCalculatorParams NetworkChangeCalculatorParamsWin(); - // All member variables may only be accessed on the thread |this| was created - // on. + // All member variables may only be accessed on the sequence |this| was + // created on. // False when not currently watching for network change events. This only // happens on initialization and when WatchForAddressChangeInternal fails and @@ -102,8 +109,11 @@ // Number of times WatchForAddressChange has failed in a row. int sequential_failures_; - // Thread on which we can run DnsConfigService. - std::unique_ptr<DnsConfigServiceThread> dns_config_service_thread_; + // |dns_config_service_| will live on this runner. + scoped_refptr<base::SequencedTaskRunner> dns_config_service_runner_; + // DnsConfigService that lives on |dns_config_service_runner_|. + std::unique_ptr<DnsConfigService, base::OnTaskRunnerDeleter> + dns_config_service_; mutable base::Lock last_computed_connection_type_lock_; ConnectionType last_computed_connection_type_; @@ -114,7 +124,7 @@ // Number of times polled to check if still offline. int offline_polls_; - THREAD_CHECKER(thread_checker_); + SEQUENCE_CHECKER(sequence_checker_); // Used for calling WatchForAddressChange again on failure. base::WeakPtrFactory<NetworkChangeNotifierWin> weak_factory_;
diff --git a/net/base/network_change_notifier_win_unittest.cc b/net/base/network_change_notifier_win_unittest.cc index ba695806..0d51205 100644 --- a/net/base/network_change_notifier_win_unittest.cc +++ b/net/base/network_change_notifier_win_unittest.cc
@@ -43,10 +43,10 @@ } // From NetworkChangeNotifierWin. - void RecomputeCurrentConnectionTypeOnDnsThread( - base::Callback<void(ConnectionType)> reply_callback) const override { + void RecomputeCurrentConnectionTypeOnDnsSequence( + base::OnceCallback<void(ConnectionType)> reply_callback) const override { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(reply_callback, + FROM_HERE, base::BindOnce(std::move(reply_callback), NetworkChangeNotifier::CONNECTION_UNKNOWN)); }
diff --git a/net/cert/root_cert_list_generated.h b/net/cert/root_cert_list_generated.h index 7cd8cc68..8491a24 100644 --- a/net/cert/root_cert_list_generated.h +++ b/net/cert/root_cert_list_generated.h
@@ -241,12 +241,19 @@ 388, true}, {{ + 0x12, 0x23, 0x12, 0xC0, 0x81, 0x94, 0x91, 0x06, 0xB7, 0x04, 0x9F, + 0x3F, 0xEB, 0xF1, 0x99, 0xC0, 0x10, 0xAD, 0xA1, 0x3E, 0x32, 0x81, + 0xCD, 0x35, 0x8A, 0x41, 0xE7, 0xBD, 0x09, 0xC8, 0x29, 0xD7, + }, + 514, + true}, + {{ 0x12, 0x55, 0xCA, 0xBE, 0x81, 0x52, 0xFA, 0x64, 0xDF, 0x94, 0x2F, 0x7A, 0x47, 0x41, 0x7E, 0x29, 0xF9, 0x6C, 0x1C, 0xE1, 0x1B, 0xF8, 0xC8, 0x4E, 0xCB, 0xE2, 0x81, 0x5C, 0xC1, 0x28, 0x08, 0x10, }, 469, - true}, + false}, {{ 0x14, 0x62, 0x00, 0x9B, 0x2D, 0xE6, 0x5D, 0x6D, 0x4D, 0x39, 0xBE, 0x89, 0x2B, 0xD2, 0xC1, 0x86, 0x49, 0x05, 0x31, 0xCE, 0x65, 0x90, @@ -281,7 +288,7 @@ 0x16, 0x96, 0x47, 0x19, 0x90, 0x7B, 0xDB, 0x01, 0xA6, 0x45, }, 40, - false}, + true}, {{ 0x15, 0xEE, 0xD3, 0x39, 0x59, 0x4B, 0x30, 0x4F, 0x8C, 0xF8, 0x47, 0xB4, 0x77, 0x37, 0x1D, 0x8D, 0x6F, 0xEC, 0x61, 0xF4, 0xDB, 0x2B, @@ -451,6 +458,13 @@ 226, true}, {{ + 0x22, 0xA3, 0x69, 0x94, 0xF2, 0x8F, 0x2F, 0xA3, 0xB1, 0x6A, 0xE8, + 0x72, 0xA7, 0x9D, 0xBB, 0x12, 0xA9, 0x82, 0xDA, 0x5B, 0x82, 0x4D, + 0x7A, 0xE4, 0x34, 0xF9, 0x61, 0x78, 0xAC, 0x54, 0x03, 0x51, + }, + 503, + true}, + {{ 0x23, 0x2C, 0xBE, 0x2D, 0x9E, 0x69, 0x94, 0xC1, 0xCE, 0xB7, 0xFB, 0xEE, 0x23, 0xAB, 0x16, 0x57, 0xDE, 0xFB, 0x6B, 0x35, 0x64, 0x72, 0x6F, 0x1E, 0x78, 0x95, 0x1C, 0xEF, 0x3A, 0x2B, 0x09, 0x5D, @@ -486,6 +500,13 @@ 460, true}, {{ + 0x25, 0x41, 0xE5, 0x3B, 0xA5, 0xB3, 0xB0, 0x7A, 0xCB, 0xE7, 0x09, + 0x7A, 0xC4, 0xA0, 0x3E, 0x04, 0x0C, 0x11, 0xCF, 0x7A, 0x6D, 0x4A, + 0x67, 0xCB, 0x21, 0x3D, 0x55, 0x8B, 0x50, 0x16, 0x7A, 0x06, + }, + 498, + false}, + {{ 0x25, 0x96, 0x90, 0x4D, 0xC4, 0xD6, 0x99, 0xAE, 0x20, 0xC2, 0xCE, 0xF4, 0xDC, 0xE4, 0x7F, 0x28, 0x59, 0x37, 0xD7, 0x74, 0x64, 0xAC, 0x37, 0x07, 0x46, 0xF5, 0x2D, 0xEA, 0x76, 0xBA, 0x0C, 0x28, @@ -647,6 +668,13 @@ 272, true}, {{ + 0x2E, 0x06, 0xCA, 0xE1, 0xFC, 0x20, 0xB2, 0x00, 0xE6, 0xFB, 0x74, + 0x85, 0x57, 0xA4, 0x44, 0x4B, 0xEC, 0x93, 0x17, 0xDF, 0xFF, 0x2E, + 0x41, 0x51, 0x66, 0x9E, 0x0F, 0x79, 0x44, 0xF0, 0xA9, 0xE0, + }, + 513, + true}, + {{ 0x2F, 0xC5, 0x66, 0x7A, 0x4B, 0x9A, 0x26, 0x78, 0xED, 0x6A, 0xC6, 0xAD, 0x25, 0x46, 0x5F, 0xCB, 0xF6, 0x09, 0x4B, 0xFC, 0xD9, 0x50, 0x40, 0x97, 0xC7, 0xA8, 0xFA, 0x47, 0xAD, 0xE5, 0xE8, 0x88, @@ -766,6 +794,13 @@ 150, true}, {{ + 0x35, 0xF5, 0x3C, 0xE1, 0x26, 0x46, 0x11, 0xE0, 0x33, 0x40, 0xFE, + 0x37, 0xE1, 0xEC, 0x7D, 0x4C, 0xC9, 0x86, 0xC5, 0x61, 0x3D, 0xCA, + 0x70, 0xFD, 0x04, 0xAA, 0x44, 0x54, 0x5F, 0x2D, 0xAF, 0x28, + }, + 508, + true}, + {{ 0x36, 0xAB, 0xC3, 0x26, 0x56, 0xAC, 0xFC, 0x64, 0x5C, 0x61, 0xB7, 0x16, 0x13, 0xC4, 0xBF, 0x21, 0xC7, 0x87, 0xF5, 0xCA, 0xBB, 0xEE, 0x48, 0x34, 0x8D, 0x58, 0x59, 0x78, 0x03, 0xD7, 0xAB, 0xC9, @@ -780,11 +815,25 @@ 94, false}, {{ + 0x36, 0xD7, 0xC7, 0x9F, 0x3D, 0x08, 0x9A, 0x0F, 0xF7, 0x99, 0x72, + 0xD9, 0x09, 0x23, 0xDE, 0xA5, 0xCA, 0x76, 0xB4, 0xCC, 0xBA, 0xF7, + 0xC2, 0x75, 0x1C, 0xB1, 0x52, 0xE9, 0x49, 0x4F, 0x52, 0xD0, + }, + 500, + true}, + {{ 0x36, 0xEC, 0xC6, 0x1F, 0xC7, 0xE5, 0xF1, 0x92, 0x3D, 0x16, 0x7E, 0x67, 0xDF, 0xDE, 0x34, 0x60, 0x85, 0x49, 0xB3, 0x4A, 0x63, 0xC7, 0xC6, 0xE6, 0x0F, 0xFD, 0x5C, 0x18, 0x40, 0x38, 0x1F, 0x5C, }, 74, + true}, + {{ + 0x37, 0x6A, 0x1A, 0x70, 0x82, 0xA5, 0x93, 0xDC, 0xCC, 0x20, 0xD5, + 0x61, 0xD1, 0x19, 0xE9, 0xAB, 0x8D, 0x30, 0xF1, 0x1C, 0xC3, 0x21, + 0xD0, 0xA3, 0x7F, 0xA4, 0x1F, 0x0D, 0xF2, 0x84, 0xE0, 0x1C, + }, + 494, false}, {{ 0x38, 0x07, 0x39, 0x62, 0x0E, 0x13, 0x33, 0x58, 0x05, 0xEA, 0xDA, @@ -862,7 +911,7 @@ 0x21, 0x7E, 0x4E, 0xBF, 0xFC, 0xE8, 0x92, 0x88, 0x99, 0xA6, }, 13, - false}, + true}, {{ 0x3C, 0x84, 0xD9, 0x96, 0x72, 0x2B, 0x3C, 0x18, 0x72, 0xF5, 0x3D, 0xDD, 0x77, 0x17, 0xBB, 0x2F, 0xA5, 0x0E, 0xBF, 0xA0, 0x7B, 0x3F, @@ -932,7 +981,7 @@ 0x08, 0x2C, 0x10, 0x60, 0xF8, 0x40, 0x96, 0x77, 0x43, 0x48, }, 485, - true}, + false}, {{ 0x42, 0x23, 0x89, 0x40, 0x03, 0xA8, 0x81, 0xC5, 0xDF, 0x6B, 0xAB, 0x16, 0x3D, 0xB2, 0x35, 0xC2, 0x21, 0xA1, 0x8D, 0x54, 0xBF, 0x75, @@ -1067,6 +1116,13 @@ 79, false}, {{ + 0x49, 0x71, 0x28, 0xFC, 0x90, 0x65, 0x6B, 0x87, 0x29, 0x04, 0x82, + 0xB2, 0x23, 0xEF, 0xB7, 0x22, 0x40, 0xFE, 0x9C, 0x42, 0x1E, 0x79, + 0x93, 0x8D, 0xE5, 0xF8, 0x11, 0x0C, 0xB0, 0xBE, 0x90, 0x56, + }, + 512, + true}, + {{ 0x49, 0x8B, 0xC0, 0xCD, 0x5A, 0x49, 0xB7, 0x14, 0x07, 0x1E, 0xC7, 0x6A, 0x41, 0x66, 0x1C, 0xE2, 0xF2, 0x7F, 0xC3, 0x9F, 0xE4, 0x16, 0x8B, 0xC7, 0xB7, 0x79, 0x9A, 0x0A, 0xE2, 0x5F, 0x65, 0x28, @@ -1247,7 +1303,7 @@ 0x26, 0xA5, 0x28, 0xAD, 0x65, 0x3E, 0x1C, 0xCE, 0xC7, 0xBF, }, 484, - true}, + false}, {{ 0x56, 0x17, 0x4D, 0x3A, 0xD9, 0x71, 0xA8, 0x94, 0x49, 0x64, 0xB1, 0x89, 0x81, 0x1F, 0x30, 0x08, 0x49, 0x3A, 0x6A, 0x90, 0x42, 0x2E, @@ -1345,7 +1401,7 @@ 0xDA, 0x56, 0xA9, 0x5B, 0x64, 0x6E, 0xB4, 0x8C, 0xCA, 0x34, }, 468, - true}, + false}, {{ 0x5D, 0xEE, 0x74, 0xCC, 0x34, 0x3D, 0xB9, 0x3F, 0x8D, 0xEA, 0xF9, 0xE4, 0x1F, 0xBC, 0x65, 0xB3, 0x34, 0x25, 0x4B, 0x5B, 0x23, 0xB5, @@ -1506,7 +1562,7 @@ 0x3D, 0x1D, 0x68, 0xB3, 0x89, 0x28, 0xD2, 0x78, 0x7F, 0x1E, }, 487, - true}, + false}, {{ 0x68, 0x9B, 0xF4, 0x5B, 0x30, 0x83, 0xFD, 0xEA, 0xD5, 0x5F, 0x14, 0x7F, 0xD1, 0x05, 0xE3, 0xCF, 0x21, 0x8A, 0xD5, 0x8E, 0xDF, 0x3E, @@ -1515,6 +1571,13 @@ 429, true}, {{ + 0x68, 0xAA, 0x63, 0x54, 0x51, 0xD8, 0x39, 0x62, 0x16, 0x7E, 0x88, + 0xFB, 0x08, 0xF8, 0x67, 0x8D, 0x73, 0xAE, 0xC6, 0x6F, 0xC5, 0x59, + 0x46, 0x21, 0x37, 0xCF, 0xF9, 0xD1, 0xBC, 0x3D, 0x38, 0x71, + }, + 506, + true}, + {{ 0x68, 0xC3, 0x69, 0x22, 0x14, 0x72, 0x4D, 0x4B, 0x55, 0xA7, 0x60, 0xF4, 0x70, 0xB4, 0xFC, 0xA8, 0xB5, 0xE0, 0xFE, 0x1D, 0x72, 0x9C, 0xFF, 0x22, 0xFE, 0xB4, 0xCA, 0x88, 0xAC, 0xD3, 0x98, 0x09, @@ -1522,6 +1585,13 @@ 231, true}, {{ + 0x68, 0xDE, 0xD9, 0xA2, 0x03, 0xFF, 0x6E, 0x36, 0x7E, 0x12, 0xAA, + 0x49, 0x97, 0x7C, 0xD2, 0x00, 0xF7, 0x12, 0x7A, 0x80, 0x0F, 0xAA, + 0x6F, 0x85, 0x9F, 0x0B, 0xAF, 0xED, 0x82, 0x86, 0xA4, 0xFB, + }, + 499, + true}, + {{ 0x6A, 0x43, 0x6B, 0x58, 0xD9, 0xD8, 0x30, 0xE8, 0xD5, 0xB8, 0xA6, 0x42, 0x50, 0x5A, 0xD6, 0xB4, 0x14, 0x06, 0xAD, 0xCD, 0x68, 0x94, 0xD9, 0x41, 0x4F, 0x7B, 0xE0, 0xA1, 0x46, 0x7B, 0xAD, 0xB7, @@ -1690,6 +1760,13 @@ 435, true}, {{ + 0x78, 0x6F, 0xFA, 0x57, 0x86, 0x18, 0xC3, 0xB9, 0xA3, 0x11, 0x17, + 0x5E, 0x50, 0x81, 0x6F, 0x4D, 0xDA, 0x06, 0x05, 0xC3, 0x86, 0x9F, + 0x29, 0x6E, 0xBC, 0x59, 0x43, 0xBF, 0x09, 0xF4, 0xE9, 0x04, + }, + 510, + true}, + {{ 0x78, 0xCF, 0x3D, 0x3C, 0x72, 0xDA, 0xF9, 0x1C, 0xC5, 0x1B, 0x87, 0x13, 0x57, 0xA5, 0x51, 0xCF, 0x95, 0xB8, 0x37, 0xD0, 0x74, 0xC2, 0x70, 0xB0, 0x8F, 0xAC, 0xD4, 0x63, 0xA8, 0xD3, 0x9B, 0xB3, @@ -1830,6 +1907,13 @@ 166, true}, {{ + 0x82, 0x8B, 0x0E, 0xEF, 0xF2, 0x46, 0x54, 0xE8, 0xFF, 0x58, 0x41, + 0xA2, 0x9D, 0xD5, 0xD4, 0xE3, 0xED, 0x30, 0x95, 0x2C, 0xA4, 0x34, + 0x25, 0xA7, 0x92, 0x83, 0x40, 0x72, 0x08, 0xD3, 0x9D, 0x16, + }, + 511, + true}, + {{ 0x82, 0xB5, 0xF8, 0x4D, 0xAF, 0x47, 0xA5, 0x9C, 0x7A, 0xB5, 0x21, 0xE4, 0x98, 0x2A, 0xEF, 0xA4, 0x0A, 0x53, 0x40, 0x6A, 0x3A, 0xEC, 0x26, 0x03, 0x9E, 0xFA, 0x6B, 0x2E, 0x0E, 0x72, 0x44, 0xC1, @@ -1898,7 +1982,7 @@ 0x5F, 0x13, 0x8C, 0xF8, 0x1F, 0x68, 0x0A, 0x7A, 0xDC, 0x67, }, 483, - true}, + false}, {{ 0x87, 0xAF, 0x34, 0xD6, 0x6F, 0xB3, 0xF2, 0xFD, 0xF3, 0x6E, 0x09, 0x11, 0x1E, 0x9A, 0xBA, 0x2F, 0x6F, 0x44, 0xB2, 0x07, 0xF3, 0x86, @@ -1991,6 +2075,13 @@ 418, true}, {{ + 0x8D, 0x41, 0x7D, 0xB2, 0xDD, 0x8B, 0xF5, 0xE3, 0x08, 0x4D, 0x1E, + 0x3F, 0x19, 0x6D, 0x58, 0x38, 0x49, 0xD8, 0x1B, 0xDD, 0x4C, 0x00, + 0xC7, 0x0B, 0x9D, 0x39, 0x36, 0x9E, 0x96, 0xB8, 0xC7, 0x82, + }, + 495, + false}, + {{ 0x8D, 0x76, 0x77, 0x64, 0xB3, 0xCB, 0xDA, 0x08, 0x92, 0x9D, 0x07, 0x2A, 0x22, 0xA5, 0x61, 0xF4, 0xDC, 0xDD, 0x1B, 0xC5, 0x7D, 0x3C, 0xBD, 0xDC, 0x94, 0x8C, 0x47, 0xD2, 0xB4, 0x7F, 0x91, 0x22, @@ -2017,7 +2108,7 @@ 0xCF, 0xA5, 0x46, 0x57, 0x14, 0x35, 0x11, 0x2D, 0x17, 0xE5, }, 463, - true}, + false}, {{ 0x8E, 0x8B, 0x56, 0xF5, 0x91, 0x8A, 0x25, 0xBD, 0x85, 0xDC, 0xE7, 0x66, 0x63, 0xFD, 0x94, 0xCC, 0x23, 0x69, 0x0F, 0x10, 0xEA, 0x95, @@ -2040,6 +2131,13 @@ 77, false}, {{ + 0x90, 0x91, 0xE3, 0x1F, 0xE9, 0x25, 0x46, 0xA5, 0xF5, 0xE1, 0xB3, + 0xED, 0x40, 0x71, 0xF4, 0x44, 0x0B, 0x84, 0x0C, 0x1E, 0x80, 0xDB, + 0xFC, 0xBA, 0x7A, 0x7E, 0xC6, 0xD5, 0x82, 0x5F, 0x0B, 0x24, + }, + 509, + true}, + {{ 0x91, 0x19, 0xE2, 0xF4, 0x13, 0x57, 0x97, 0x77, 0x95, 0x49, 0x91, 0x70, 0x3E, 0xEE, 0x23, 0xA0, 0x45, 0x23, 0xA3, 0x12, 0xB5, 0xC6, 0x5F, 0x7F, 0x93, 0x74, 0xAA, 0x31, 0x00, 0xEB, 0xD8, 0xE7, @@ -2199,7 +2297,7 @@ 0x1D, 0xDC, 0x5D, 0xD5, 0x92, 0x33, 0x22, 0x98, 0x68, 0xDE, }, 66, - false}, + true}, {{ 0x97, 0x9F, 0x6F, 0x6A, 0x8A, 0x41, 0xC4, 0x21, 0xCC, 0x67, 0x34, 0x73, 0xD5, 0x8A, 0x63, 0x79, 0x81, 0x7B, 0xE7, 0x3D, 0x2E, 0x52, @@ -2227,7 +2325,7 @@ 0xD7, 0x36, 0x6D, 0x50, 0x69, 0x88, 0xE8, 0xD8, 0x43, 0x47, }, 486, - true}, + false}, {{ 0x98, 0xB3, 0xF1, 0x0A, 0x02, 0x50, 0x41, 0x91, 0x0F, 0x19, 0x7C, 0xF1, 0x7C, 0xA0, 0xFC, 0xDF, 0xED, 0x75, 0xFB, 0x2C, 0x8C, 0x14, @@ -2633,7 +2731,7 @@ 0x9D, 0xA2, 0xED, 0x92, 0xE6, 0x18, 0x23, 0x9D, 0x9C, 0x98, }, 142, - false}, + true}, {{ 0xB1, 0x12, 0x41, 0x42, 0xA5, 0xA1, 0xA5, 0xA2, 0x88, 0x19, 0xC7, 0x35, 0x34, 0x0E, 0xFF, 0x8C, 0x9E, 0x2F, 0x81, 0x68, 0xFE, 0xE3, @@ -2677,6 +2775,13 @@ 48, true}, {{ + 0xB2, 0xF7, 0x29, 0x8B, 0x52, 0xBF, 0x2C, 0x3C, 0xAC, 0x4D, 0xDF, + 0xE7, 0x2D, 0xE4, 0xD6, 0x82, 0xAC, 0x58, 0x95, 0x75, 0x95, 0x98, + 0x2F, 0x2B, 0x62, 0x30, 0x1A, 0xF5, 0x97, 0xC6, 0x99, 0xC5, + }, + 507, + true}, + {{ 0xB3, 0x18, 0x2E, 0x28, 0x9A, 0xE3, 0x4D, 0xDF, 0x2B, 0xE6, 0x43, 0xAB, 0x79, 0xC2, 0x44, 0x30, 0x16, 0x05, 0xFA, 0x0F, 0x1E, 0xAA, 0xE6, 0xD1, 0x0F, 0xB9, 0x29, 0x60, 0x0A, 0xF8, 0x4D, 0xF0, @@ -2733,6 +2838,13 @@ 207, false}, {{ + 0xB7, 0x40, 0x8B, 0x4D, 0x2B, 0xE0, 0x23, 0x8B, 0xA3, 0x70, 0x04, + 0xDD, 0x34, 0xE2, 0x76, 0xC6, 0x01, 0x9B, 0xD2, 0xF2, 0x4C, 0x9D, + 0xB7, 0xD4, 0x98, 0x0F, 0x5F, 0x6C, 0x35, 0x9A, 0x4B, 0xCC, + }, + 496, + false}, + {{ 0xB8, 0x9B, 0xCB, 0xB8, 0xAC, 0xD4, 0x74, 0xC1, 0xBE, 0xA7, 0xDA, 0xD6, 0x50, 0x37, 0xF4, 0x8D, 0xCE, 0xCC, 0x9D, 0xFA, 0xA0, 0x61, 0x2C, 0x3C, 0x24, 0x45, 0x95, 0x64, 0x19, 0xDF, 0x32, 0xFE, @@ -2789,6 +2901,13 @@ 71, false}, {{ + 0xBE, 0x32, 0x80, 0xC6, 0x86, 0x3C, 0x77, 0x0A, 0x33, 0xC9, 0x04, + 0x0B, 0xD9, 0x7D, 0x55, 0x40, 0xB2, 0x16, 0xD1, 0xD9, 0x1D, 0xB8, + 0xB0, 0x88, 0xCE, 0xAC, 0x11, 0x97, 0xDA, 0xE1, 0xD6, 0x60, + }, + 501, + true}, + {{ 0xBE, 0x3D, 0xB7, 0xB7, 0x9B, 0xFE, 0x57, 0x9D, 0xCF, 0x9B, 0x07, 0xCA, 0x4C, 0xAD, 0x75, 0xAF, 0xF1, 0x69, 0x75, 0x56, 0x8E, 0x5B, 0x45, 0xCF, 0xCA, 0xE4, 0xD6, 0x1F, 0xB6, 0x31, 0x75, 0xA8, @@ -2838,6 +2957,13 @@ 124, false}, {{ + 0xC3, 0x72, 0xF6, 0xD1, 0x8E, 0xBE, 0xE5, 0xAA, 0x23, 0xD9, 0xE9, + 0x19, 0xF3, 0xE6, 0xBE, 0x98, 0x48, 0x8E, 0xC0, 0x16, 0x07, 0xDF, + 0x31, 0x62, 0xFC, 0x19, 0x2E, 0x4B, 0x13, 0x46, 0xAF, 0xB3, + }, + 505, + true}, + {{ 0xC3, 0xBC, 0x61, 0x00, 0xF5, 0x7E, 0x32, 0x0D, 0x86, 0x59, 0xF2, 0x25, 0x84, 0x67, 0x7E, 0x56, 0x86, 0x0A, 0xAB, 0x10, 0x14, 0xE0, 0x08, 0x4A, 0x49, 0x6F, 0xFF, 0x8C, 0x88, 0x0B, 0x6B, 0xA3, @@ -2873,6 +2999,13 @@ 213, true}, {{ + 0xC5, 0x75, 0x0B, 0xF8, 0x5F, 0x45, 0x9F, 0xB7, 0x0E, 0x2B, 0x6C, + 0xD1, 0x89, 0x8D, 0x37, 0x5E, 0x92, 0xD7, 0x93, 0x8E, 0x47, 0xA6, + 0xE0, 0x34, 0xCC, 0xE0, 0xC1, 0x2D, 0x30, 0x37, 0x2C, 0xCD, + }, + 502, + true}, + {{ 0xC5, 0xEA, 0x25, 0x9C, 0x62, 0x98, 0x03, 0x50, 0x86, 0x49, 0xF0, 0x21, 0x77, 0xF6, 0x3C, 0x32, 0xFA, 0x85, 0xCC, 0x4A, 0xD5, 0xC3, 0x5F, 0x0D, 0x54, 0x1C, 0x45, 0xDF, 0x10, 0xA4, 0x9F, 0xD7, @@ -3004,7 +3137,7 @@ 0xDB, 0xA4, 0x68, 0xE2, 0x76, 0xDF, 0x82, 0x06, 0x5A, 0xDF, }, 132, - false}, + true}, {{ 0xD1, 0xC4, 0x53, 0x77, 0xEB, 0xDC, 0xD6, 0x18, 0xCD, 0x16, 0x51, 0xDC, 0x2E, 0x02, 0xC2, 0x1D, 0x75, 0x1E, 0x5A, 0xA9, 0xFC, 0xD1, @@ -3165,7 +3298,7 @@ 0x6B, 0x9A, 0x31, 0x47, 0xEE, 0x75, 0xF8, 0xD1, 0x62, 0x0A, }, 493, - false}, + true}, {{ 0xE0, 0xEF, 0x88, 0x2D, 0xA4, 0x8A, 0xB0, 0xB7, 0xEF, 0xB0, 0xD9, 0xBA, 0x15, 0xB2, 0x71, 0x7D, 0xD0, 0x8F, 0x04, 0x3C, 0x25, 0xAC, @@ -3251,6 +3384,13 @@ 289, false}, {{ + 0xEA, 0xBC, 0x18, 0x5C, 0x4E, 0x82, 0xD9, 0x42, 0xB1, 0xA5, 0x97, + 0x8B, 0xA3, 0xC0, 0x18, 0x14, 0x87, 0xD6, 0xB3, 0xB9, 0x97, 0x4E, + 0x5C, 0x49, 0xF7, 0x2F, 0x6D, 0x0B, 0xD9, 0x63, 0x71, 0x50, + }, + 497, + false}, + {{ 0xEB, 0x49, 0x93, 0xEF, 0xA9, 0xB0, 0x89, 0xE5, 0x93, 0x41, 0x8A, 0xA8, 0x93, 0xF8, 0xE9, 0x3A, 0x73, 0x74, 0xD8, 0x10, 0xE5, 0x2F, 0xCB, 0xE0, 0x1E, 0x7F, 0x1D, 0x7E, 0x92, 0xA6, 0xD0, 0x24, @@ -3314,6 +3454,13 @@ 171, false}, {{ + 0xF2, 0x6C, 0xDA, 0xA1, 0xC4, 0x8E, 0x2D, 0x36, 0x9E, 0xAF, 0x24, + 0x99, 0x3A, 0x42, 0x4F, 0x82, 0x90, 0x98, 0x3A, 0xF7, 0x09, 0x4A, + 0x5B, 0xDE, 0x9C, 0x7D, 0x44, 0x34, 0x1F, 0x2E, 0x24, 0x28, + }, + 504, + true}, + {{ 0xF2, 0xA4, 0xE6, 0xB2, 0x63, 0xD0, 0xA5, 0x52, 0xAD, 0xFF, 0x5D, 0x85, 0xDC, 0x96, 0xB5, 0x82, 0x0F, 0xD6, 0x6A, 0xA0, 0xB1, 0x82, 0x28, 0xF4, 0x8F, 0xDB, 0x08, 0x7C, 0x8D, 0xB3, 0x41, 0x33, @@ -3452,7 +3599,7 @@ 0x85, 0x5F, 0xA0, 0xAD, 0x63, 0x0D, 0x90, 0xEE, 0xF8, 0x2E, }, 490, - true}, + false}, {{ 0xFD, 0x87, 0x2D, 0x17, 0x66, 0x17, 0xE5, 0x0C, 0x26, 0x61, 0x19, 0xD0, 0xFD, 0xB0, 0x47, 0xB0, 0x73, 0x2D, 0xA2, 0x04, 0x8B, 0x12,
diff --git a/net/data/ssl/root_stores/root_stores.json b/net/data/ssl/root_stores/root_stores.json index aac30f7..401eba8 100644 --- a/net/data/ssl/root_stores/root_stores.json +++ b/net/data/ssl/root_stores/root_stores.json
@@ -35,7 +35,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "007e452fd5cf838946696dfe37a2db2ef3991436d27bcbab45922053c15a87a8": [ "windows/080328202117", @@ -89,7 +99,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "00ab444abd6bdba33da8de569ac4ecde326d1be1a61442d5eec3975a0c243f04": [ "windows/070201011524", @@ -148,7 +168,24 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" + ], + "016e1dcd5f78841bbebbae9ddea08c8d7ec54e698e95bb778ecdd1e10d8bf4f9": [ + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "02ed0eb28c14da45165c566791700d6451d7fb56f0b2ab1d3b8eb070e56edff5": [ "android/kitkat-cts-release", @@ -164,6 +201,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -178,6 +216,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -189,6 +230,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/130626232015", "windows/131003230417", @@ -216,7 +261,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "03458b6abeecc214953d97149af45391691de9f9cdcc2647863a3d67c95c243b": [ "android/kitkat-cts-release", @@ -270,6 +325,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -284,6 +340,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -296,6 +355,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/100503224537", "windows/100719231554", @@ -339,7 +402,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "0378b202ccabba99a12e569a11a077db1edb39482061c75d0073059d9ab5b513": [ "windows/071219233937", @@ -430,7 +503,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "04048028bf1f2864d48f9ad4d83294366a828856553f3b14303f90147f5d40ef": [ "android/kitkat-cts-release", @@ -446,6 +529,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -460,6 +544,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -472,6 +559,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/091029013045", "windows/100503224537", @@ -516,7 +607,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "04acfb3b24793f300f67ef87e44dd72cb9b28b204f389a7cd5ae28785c7d42cd": [ "macos/10.10.0", @@ -533,6 +634,7 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -584,7 +686,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "04f1bec36951bc1454a904ce32890c5da3cde1356b7900f6e62dfa2041ebad51": [ "windows/170228174808", @@ -596,7 +708,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "0536801fbb443b3e905fd6d70d8c81eb88551be8061299110d2b4f82e64cade1": [ "windows/100719231554", @@ -640,7 +762,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "058a40323ec8c46262c3052a5d357b91ac24d3da26351b3ff4407e99f7a4e9b4": [ "windows/070201011524", @@ -699,7 +831,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "05d38c2a70bfc500ccb0cb509159b46b065c6ac9cb42d2e6f16167841434572a": [ "windows/120223022238", @@ -733,7 +875,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "063e4afac491dfd332f3089b8542e94617d893d7fe944e10a7937ee29d9693c0": [ "android/kitkat-cts-release", @@ -749,6 +901,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -763,6 +916,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -774,6 +930,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/090501224247", "windows/090825180842", @@ -821,7 +981,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "0687260331a72403d909f105e69bcf0d32e1bd2493ffc6d9206d11bcd6770739": [ "android/kitkat-cts-release", @@ -837,6 +1007,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -851,6 +1022,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -863,6 +1037,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -921,7 +1099,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "06a2c9a3379ab3c156159a27ca9ecdbd4ef75309b409cf70aeca9a12330f380e": [ "macos/10.9.0", @@ -998,7 +1186,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "07453d53793bf41819a5251c69f88e2bb344b59ca828b5a543781599eaf3d602": [ "windows/070109202240", @@ -1039,10 +1237,15 @@ "windows/150122021939" ], "0753e940378c1bd5e3836e395daea5cb839e5046f1bd0eae1951cf10fec7c965": [ + "android/pie-cts-release", "mozilla/2.18", "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "windows/161112005943", "windows/170228174808", "windows/170419224008", @@ -1053,7 +1256,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "075bfcca2d55ae6e35742c32afd0ca8ea4c958feefc23224999541c033d69c8d": [ "windows/120125230451", @@ -1088,7 +1301,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "0771920c8cb874d5c5a4dc0d6a51a2d495d38c4de2cd5b83d2a06faa051935f6": [ "windows/121102212406", @@ -1120,7 +1343,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "0791ca0749b20782aad3c7d7bd0cdfc9485835843eb2d7996009ce43ab6c6927": [ "android/kitkat-cts-release", @@ -1222,7 +1455,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "0a81ec5a929777f145904af38d5d509f66b5e2c58fcdb531058b0e17f3f0b41b": [ "android/kitkat-cts-release", @@ -1238,6 +1481,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -1252,6 +1496,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -1264,6 +1511,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/100503224537", "windows/100719231554", @@ -1307,7 +1558,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "0b5eed4e846403cf55e065848440ed2a82758bf5b9aa1f253d4613cfa080ff3f": [ "android/kitkat-cts-release", @@ -1413,7 +1674,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "0c0b6b2bd1edd7b27fead157f8e846b335b784a39f06c47216c8746f64c5ceda": [ "windows/140912180251", @@ -1437,7 +1708,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "0c258a12a5674aef25f28ba7dcfaeceea348e541e6f5cc4ee63b71b361606ac3": [ "android/kitkat-cts-release", @@ -1453,6 +1734,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -1467,6 +1749,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -1534,7 +1819,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "0c2cd63df7806fa399ede809116b575bf87989f06518f9808c860503178baf66": [ "android/kitkat-cts-release", @@ -1550,6 +1845,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -1564,6 +1860,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -1576,6 +1875,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -1616,6 +1919,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -1662,7 +1968,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "0ed3ffab6c149c8b4e71058e8668d429abfda681c2fff508207641f0d751a3e5": [ "macos/10.10.0", @@ -1679,6 +1995,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5" @@ -1770,6 +2089,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -1784,6 +2104,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -1796,6 +2119,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -1854,7 +2181,28 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" + ], + "125609aa301da0a249b97a8239cb6a34216f44dcac9f3954b14292f2e8c8608f": [ + "mozilla/2.32", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "126bf01c1094d2f0ca2e352380b3c724294546ccc65597bef7f12d8a171f1984": [ "macos/10.10.0", @@ -1871,6 +2219,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -1899,7 +2250,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "12d480c1a3c664781b99d9df0e9faf3f1cacee1b3c30c3123a337a4a454ffed2": [ "windows/071219233937", @@ -1954,7 +2315,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "136335439334a7698016a0d324de72284e079d7b5220bb8fbd747816eebebaca": [ "android/kitkat-cts-release", @@ -1970,6 +2341,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -1984,6 +2356,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -1995,6 +2370,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/090501224247", "windows/090825180842", @@ -2042,7 +2421,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "1465fa205397b876faa6f0a9958e5590e40fcc7faa4fb7c2c8677521fb5fb658": [ "android/kitkat-cts-release", @@ -2058,6 +2447,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -2072,6 +2462,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -2084,6 +2477,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -2142,7 +2539,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "1501f89c5c4dcf36cf588a17c9fd7cfceb9ee01e8729be355e25de80eb6284b4": [ "windows/160414222039", @@ -2157,15 +2564,29 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "152a402bfcdf2cd548054d2275b39c7fca3ec0978078b0f0ea76e561a6c7433e": [ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -2194,7 +2615,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "1594cb5b826c315de3bc932c56895ff23a3a988b5dc1f034d214dfd858d89ee8": [ "windows/070109202240", @@ -2235,13 +2666,25 @@ "windows/150122021939" ], "15d5b8774619ea7d54ce1ca6d0b0c403e037a917f131e8a04e1e6b7a71babce5": [ + "mozilla/2.30", + "mozilla/2.32", "windows/170922155710", "windows/171121202507", "windows/180122185731", "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "15f0ba00a3ac7af3ac884c072b1011a077bd77c097f40164b2f8598abd83860c": [ "android/kitkat-cts-release", @@ -2257,6 +2700,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -2271,6 +2715,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -2283,6 +2730,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -2322,6 +2773,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -2336,6 +2788,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -2348,6 +2803,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -2406,7 +2865,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "1793927a0614549789adce2f8f34f7f0b66d0f3ae3a3b84d21ec15dbba4fadc7": [ "android/kitkat-cts-release", @@ -2422,12 +2891,16 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.12.1", "macos/10.12.2", "macos/10.13.0", "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -2436,6 +2909,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/081103235012", "windows/090203164005", @@ -2485,7 +2962,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "179fbc148a3dd00fd24ea13458cc43bfa7f59c8182d783a513f6ebec100c8924": [ "android/lollipop-mr1-cts-release", @@ -2497,6 +2984,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -2511,6 +2999,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -2522,6 +3013,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/130626232015", "windows/131003230417", @@ -2549,14 +3044,28 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "18ce6cfe7bf14e60b2e347b8dfe868cb31d02ebb3ada271569f50343b46db3a4": [ "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "mozilla/2.11", "mozilla/2.14", "mozilla/2.16", @@ -2564,6 +3073,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "windows/160113232859", "windows/160123000836", "windows/160128175153", @@ -2579,7 +3092,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "18f1fc7f205df8adddeb7fe007dd57e3af375a9c4d8d73546bf4f1fed1e18d35": [ "android/kitkat-cts-release", @@ -2595,6 +3118,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -2609,6 +3133,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -2621,6 +3148,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -2679,7 +3210,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "19abcdff3a74402fa8f0ca206bf7fab0dffff3ae2bbd719584d21090a4353207": [ "windows/170613190204", @@ -2689,7 +3230,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "1a0d20445de5ba1862d19ef880858cbce50102b36e8f0a040c3c69e74522fe6e": [ "windows/110919210309", @@ -2726,7 +3277,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "1a2512cda6744abea11432a2fdc9f8c088db5a98c89e13352574cde4d9e80cdd": [ "windows/140912180251", @@ -2750,7 +3311,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "1aa980c8c0d316f25029978982f033cbb3a3f4188d669f2de6a8d84ee00a1575": [ "windows/080328202117", @@ -2804,14 +3375,28 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "1ba5b2aa8c65401a82960118f80bec4f62304d83cec4713a19c39c011ea46db4": [ "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "mozilla/2.11", "mozilla/2.14", "mozilla/2.16", @@ -2819,6 +3404,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "windows/160113232859", "windows/160123000836", "windows/160128175153", @@ -2834,7 +3423,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "1ba622b36325544ae922afc22ef9d367943794f6e16874f368a733c65c9d5279": [ "windows/111018233154", @@ -2870,7 +3469,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "1c01c6f4dbb2fefc22558b2bca32563f49844acfc32b7be4b0ff599f9e8c7af7": [ "android/kitkat-cts-release", @@ -2934,7 +3543,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "1d4f0596fca2611d09f84c78f2ea565ef2eab9cfc272a1718bd336e6e0ae021a": [ "windows/070109202240", @@ -3007,7 +3626,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "1e49ac5dc69e86d0565da2c1305c419330b0b781bfec50e54a1b35af7fddd501": [ "macos/10.11.0", @@ -3021,6 +3650,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "windows/100927165108", "windows/110125205412", "windows/110218005058", @@ -3061,7 +3693,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "1e51942b84fd467bf77d1c89da241c04254dc8f3ef4c22451fe7a89978bdcd4f": [ "windows/160916174005", @@ -3075,7 +3717,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "1e910b40c08184c0ca20468e824502ff2485163f77b03bb73296823f03885621": [ "windows/111018233154", @@ -3111,7 +3763,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "209e956af04df3996507c887d356230d6eb49fdbdd2d8a058ff50b8f80f690aa": [ "windows/170228174808", @@ -3123,7 +3785,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "2193cfea381211a1aeaa2de984e630643a87160b1208118145eafb8e1bc69958": [ "windows/170228174808", @@ -3135,7 +3807,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "21db20123660bb2ed418205da11ee7a85a65e2bc6e55b5af7e7899c8a266d92e": [ "android/kitkat-cts-release", @@ -3164,6 +3846,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -3229,7 +3914,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "229ccc196d32c98421cc119e78486eebef603aecd525c6b88b47abb740692b96": [ "windows/150618202535", @@ -3251,13 +3946,29 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "22a2c1f7bded704cc1e701b5f408c310880fe956b5de2a4a44f99c873a25a7c8": [ + "android/pie-cts-release", + "macos/10.14.0", "mozilla/2.18", "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "windows/160916174005", "windows/161112005943", "windows/170228174808", @@ -3269,7 +3980,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "22e0d11dc9207e16c92b2ee18cfdb2c2e940626847921fc528cedd2f7932f714": [ "windows/070109202240", @@ -3322,6 +4043,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -3377,7 +4101,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "2399561127a57125de8cefea610ddf2fa078b5c8067f4e828290bfb860e84b3c": [ "android/kitkat-cts-release", @@ -3393,6 +4127,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -3407,6 +4142,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -3418,6 +4156,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/090825180842", "windows/091013033632", @@ -3464,7 +4206,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "248302a977f40f7dd6a2b770586adfaac3eb1e85fd1a102dbd7863c72b8f8ef2": [ "macos/10.10.0", @@ -3483,7 +4235,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "2530cc8e98321502bad96f9b1fba1b099e2d299e0f4548bb914f363bc0d4531f": [ "android/kitkat-cts-release", @@ -3499,6 +4261,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -3513,6 +4276,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -3524,6 +4290,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9" ], "2602d21e81277a83f6048128f61d794a06f474e1f75e49740a817c2666f62211": [ @@ -3579,6 +4349,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -3616,15 +4389,29 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "27995829fe6a7515c1bfe848f9c4761db16c225929257bf40d0894f29ea8baf2": [ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -3653,7 +4440,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "2834991cf677466d22baac3b0055e5b911d9a9e55f5b85ba02dc566782c30e8a": [ "macos/10.10.0", @@ -3738,13 +4535,25 @@ "windows/150122021939" ], "2a575471e31340bc21581cbd2cf13e158463203ece94bcf9d3cc196bf09a5472": [ + "mozilla/2.30", + "mozilla/2.32", "windows/170922155710", "windows/171121202507", "windows/180122185731", "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "2a8da2f8d23e0cd3b5871ecfb0f42276ca73230667f474eede71c5ee32cc3ec6": [ "windows/160414222039", @@ -3759,7 +4568,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "2a99f5bc1174b73cbb1d620884e01c34e51ccb3978da125f0e33268883bf4158": [ "android/marshmallow-cts-release", @@ -3770,6 +4589,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -3784,6 +4604,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.4", "macos/10.9.5", "mozilla/2.10", @@ -3794,6 +4617,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/140912180251", "windows/150122021939", @@ -3817,16 +4644,40 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "2cabeafe37d06ca22aba7391c0033d25982952c453647349763a3ab5ad6ccf69": [ + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "windows/170922155710", "windows/171121202507", "windows/180122185731", "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "2ce1cb0bf9d2f9e102993fbe215152c3b2dd0cabde1c68e5319b839154dbb7f5": [ "android/kitkat-cts-release", @@ -3842,6 +4693,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -3856,6 +4708,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -3868,6 +4723,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/100503224537", "windows/100719231554", @@ -3911,7 +4770,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "2d47437de17951215a12f3c58e51c729a58026ef1fcc0a5fb3d9dc012f600d19": [ "android/kitkat-cts-release", @@ -3994,7 +4863,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "2d66a702ae81ba03af8cff55ab318afa919039d9f31b4d64388680f81311b65a": [ "windows/110919210309", @@ -4031,7 +4910,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "2dc62c3f6c0cc9020bba77e1c511511024b943ee598856da5a22e222b7277a20": [ "macos/10.9.0", @@ -4105,7 +4994,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "2dfcbacadf22a6ff107a51fd3e8b9e17858028879b13f7c3b57b3e1bd2315809": [ "windows/070109202240", @@ -4146,17 +5045,33 @@ "windows/150122021939" ], "2e7bf16cc22485a7bbe2aa8696750761b0ae39be3b2fe9d0cc6d4ef73491425c": [ + "android/pie-cts-release", + "macos/10.14.0", "mozilla/2.18", "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "windows/170922155710", "windows/171121202507", "windows/180122185731", "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "2f1062f8bf84e7eb83a0f64c98d891fbe2c811b17ffac0bce1a6dc9c7c3dcbb7": [ "macos/10.9.0", @@ -4252,6 +5167,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.3", "macos/10.10.4", "macos/10.11.0", @@ -4265,6 +5181,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -4273,6 +5192,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/140912180251", "windows/150122021939", @@ -4297,7 +5220,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "31ad6648f8104138c738f39ea4320133393e3a18cc02296ef97c2ac9ef6731d0": [ "android/lollipop-cts-release", @@ -4310,6 +5243,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -4324,6 +5258,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -4335,6 +5272,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/131003230417", "windows/140312052931", @@ -4361,7 +5302,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "31eace9b4c9c71734a185680bc24866ca6cbd82b3cb61bcc8706261b59ce1073": [ "windows/070109202240", @@ -4527,13 +5478,29 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "3417bb06cc6007da1b961c920b8ab4ce3fad820e4aa30b9acbc4a74ebdcebc65": [ + "android/pie-cts-release", + "macos/10.14.0", "mozilla/2.18", "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "windows/160916174005", "windows/161112005943", "windows/170228174808", @@ -4545,7 +5512,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "341de98b1392abf7f4ab90a960cf25d4bd6ec65b9a51ce6ed067d00ec7ce9b7f": [ "macos/10.10.0", @@ -4580,7 +5557,20 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" + ], + "34ff2a4409dc1383e9f8966e8adfe5719eba373fd0ad5e2f49f90ee07cf5d4c1": [ + "windows/190416222336" ], "35ae5bddd8f7ae635cffba5682a8f00b95f48462c7108ee9a0e5292b074aafb2": [ "android/kitkat-cts-release", @@ -4663,7 +5653,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "363f3c849eab03b0a2a0f636d7b86d04d3ac7fcfe26a0a9121ab9795f6e176df": [ "macos/10.10.0", @@ -4680,6 +5680,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5" @@ -4741,7 +5744,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "37d51006c512eaab626421f1ec8c92013fc5f82ae98ee533eb4619b8deb4d06c": [ "android/kitkat-cts-release", @@ -4757,6 +5770,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -4771,6 +5785,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -4783,6 +5800,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -4841,7 +5862,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "37d8dc8af7867845da3344a6b1bade448d8a80e47b5579f96bf631768f9f30f6": [ "windows/070201011524", @@ -5039,6 +6070,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -5099,7 +6133,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "3c4fb0b95ab8b30032f432b86f535fe172c185d0fd39865837cf36187fa6f428": [ "android/marshmallow-cts-release", @@ -5110,6 +6154,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.11.0", "macos/10.11.1", "macos/10.11.2", @@ -5121,6 +6166,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -5129,6 +6177,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/140912180251", "windows/150122021939", @@ -5153,7 +6205,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "3c5f81fea5fab82c64bfa2eaecafcde8e077fc8620a7cae537163df36edbf378": [ "android/kitkat-cts-release", @@ -5169,6 +6231,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -5183,6 +6246,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.4", "macos/10.9.5", "mozilla/2.10", @@ -5193,6 +6259,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/100927165108", "windows/110125205412", @@ -5234,7 +6304,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "3ccc3ccfe45496d07b620dbf1328e8a1490018f48633c8a28a995ca60408b0be": [ "windows/070109202240", @@ -5294,7 +6374,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "3cfc3c14d1f684ff17e38c43ca440c00b967ec933e8bfe064ca1d72c90f2adb0": [ "mozilla/2.10", @@ -5330,6 +6420,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -5344,6 +6435,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -5355,6 +6449,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/110627203812", "windows/110830002513", @@ -5393,7 +6491,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "3e9099b5015e8f486c00bcea9d111ee721faba355a89bcf1df69561e3dc6325c": [ "android/kitkat-cts-release", @@ -5409,6 +6517,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -5423,6 +6532,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -5435,6 +6547,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -5493,7 +6609,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "3f06e55681d496f5be169eb5389f9f2b8ff61e1708df6881724849cd5d27cb69": [ "android/kitkat-cts-release", @@ -5618,6 +6744,14 @@ "windows/140912180251", "windows/150122021939" ], + "3fd4be8baad2f26e1bde06c7584bb720dd1a972d111f5a4999bc44b08fb4960d": [ + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" + ], "407c276bead2e4af0661ef6697341dec0a1f9434e4eafb2d3d32a90549d9de4a": [ "windows/120406192127", "windows/121102212406", @@ -5649,10 +6783,41 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" + ], + "40f6af0346a99aa1cd1d555a4e9cce62c7f9634603ee406615833dc8c8d00367": [ + "mozilla/2.32", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "416b1f9e84e74c1d19b23d8d7191c6ad81246e641601f599132729f507beb3cc": [ - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "417dcf3180f4ed1a3747acf1179316cd48cb05c5788435168aed98c98cdcb615": [ "windows/121102212406", @@ -5684,7 +6849,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "41c923866ab4cad6b7ad578081582e020797a6cbdf4fff78ce8396b38937d7f5": [ "android/kitkat-cts-release", @@ -5700,6 +6875,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -5714,6 +6890,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -5726,6 +6905,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070201011524", "windows/070522004642", @@ -5783,7 +6966,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "41d4f6dcf130b9843a3b9a9530953e925fdd84e8b7aeb8f205b8fae39352617d": [ "macos/10.10.0", @@ -5808,6 +7001,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -5822,6 +7016,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -5834,6 +7031,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -5892,7 +7093,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "4210f199499a9ac33c8de02ba6dbaa14408bdd8a6e324689c1922d069715a332": [ "windows/100503224537", @@ -5937,7 +7148,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "42143a511a3afcdd80d555debb4191ec6bb285ee66e62ec657ed20adf7d55faa": [ "windows/090825180842", @@ -5985,7 +7206,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "4348a0e9444c78cb265e058d5e8944b4d84f9662bd26db257f8934a443c70161": [ "android/kitkat-cts-release", @@ -6001,6 +7232,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -6015,6 +7247,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -6027,6 +7262,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -6085,7 +7324,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "43df5774b03e7fef5fe40d931a7bedf1bb2e6b42738c4e6d3841103d3aa7f339": [ "android/kitkat-cts-release", @@ -6101,6 +7350,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -6115,6 +7365,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -6126,6 +7379,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/090825180842", "windows/091013033632", @@ -6172,7 +7429,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "43f257412d440d627476974f877da8f1fc2444565a367ae60eddc27a412531ae": [ "macos/10.10.0", @@ -6189,6 +7456,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -6311,6 +7581,8 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", + "macos/10.14.0", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -6319,6 +7591,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/151119231843", "windows/160113232859", @@ -6336,7 +7612,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "45140b3247eb9cc8c5b4f0d7b53091f73292089e6e5a63e2749dd3aca9198eda": [ "android/kitkat-cts-release", @@ -6352,6 +7638,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -6366,6 +7653,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -6378,6 +7668,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/100503224537", "windows/100719231554", @@ -6421,7 +7715,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "46273285615d96e52da9fc2ed8c036f10af3d9f6280f8d288706c52b2011b4da": [ "windows/090501224247", @@ -6470,16 +7774,31 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "46edc3689046d53a453fb3104ab80dcaec658b2660ea1629dd7e867990648716": [ "android/oreo-mr1-cts-release", + "android/pie-cts-release", "mozilla/2.14", "mozilla/2.16", "mozilla/2.18", "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "windows/160916174005", "windows/161112005943", "windows/170228174808", @@ -6491,7 +7810,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "488e134f30c5db56b76473e608086842bf21af8ab3cd7ac67ebdf125d531834e": [ "windows/090825180842", @@ -6539,7 +7868,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "488fca189eaadf54a3f920ed39e587183ba512232999fae3e4a285fe98e298d1": [ "windows/150122021939", @@ -6608,6 +7947,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -6639,7 +7979,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "49c8175a9815e08bef129a929de1bacad04e4db67a8c839293953e5031c81ca0": [ "windows/070109202240", @@ -6693,6 +8043,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -6707,6 +8058,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -6718,6 +8072,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/120223022238", "windows/120406192127", @@ -6750,7 +8108,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "49f74f824f2e059fe99c98af3219ec0d9a004d1b64dd2fd1452616318ab806c0": [ "windows/070109202240", @@ -6804,6 +8172,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -6818,6 +8187,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -6829,6 +8201,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/090825180842", "windows/091013033632", @@ -6875,7 +8251,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "4b22d5a6aec99f3cdb79aa5ec06838479cd5ecba7164f7f22dc1d65f63d85708": [ "android/lollipop-cts-release", @@ -6915,7 +8301,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "4bdb7418bdf7ffe33ba0884afa7c0c61fd85a153972f65f7d01cb3ec7eb4073c": [ "windows/070109202240", @@ -6990,7 +8386,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "4d2491414cfe956746ec4cefa6cf6f72e28a1329432f9d8a907ac4cb5dadc15a": [ "android/marshmallow-cts-release", @@ -7001,6 +8407,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -7015,6 +8422,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.4", "macos/10.9.5", "mozilla/2.10", @@ -7025,6 +8435,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/140912180251", "windows/150122021939", @@ -7049,7 +8463,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "4d9ebb28825c9643ab15d54e5f9614f13cb3e95de3cf4eac971301f320f9226e": [ "windows/090825180842", @@ -7097,7 +8521,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "4dbb0157a691fa7382289d65c0332ddb1dcb640b40ad10f010a43e20f3afed1e": [ "windows/070109202240", @@ -7185,12 +8619,16 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.12.1", "macos/10.12.2", "macos/10.13.0", "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -7199,6 +8637,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/100927165108", "windows/110125205412", @@ -7240,7 +8682,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "507941c74460a0b47086220d4e9932572ab5d1b5bbcb8980ab1cb17651a844d2": [ "android/kitkat-cts-release", @@ -7266,6 +8718,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -7326,7 +8781,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "513b2cecb810d4cde5dd85391adfc6c2dd60d87bb736d2b521484aa47a0ebef6": [ "android/kitkat-cts-release", @@ -7342,6 +8807,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -7356,6 +8822,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -7368,6 +8837,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/091029013045", "windows/100503224537", @@ -7412,7 +8885,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "51847c8cbd2e9a72c91e292d2ae247d7de1e3fd270547a20ef7d610f38b8842c": [ "macos/10.10.0", @@ -7519,12 +9002,16 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.12.1", "macos/10.12.2", "macos/10.13.0", "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -7533,6 +9020,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/100927165108", "windows/110125205412", @@ -7574,7 +9065,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "53dfdfa4e297fcfe07594e8c62d5b8ab06b32c7549f38a163094fd6429d5da43": [ "macos/10.10.0", @@ -7591,6 +9092,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -7620,11 +9124,22 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "54455f7129c20b1447c418f997168f24c58fc5023bf5da5be2eb6e1dd8902ed5": [ "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "mozilla/2.11", "mozilla/2.14", "mozilla/2.16", @@ -7632,6 +9147,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "windows/160916174005", "windows/161112005943", "windows/170228174808", @@ -7643,7 +9162,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "54ae8a683fe2d78ff1ef0e0b3f58425092953ba08c67fe4a95595d1cebcdcb30": [ "windows/140912180251", @@ -7667,7 +9196,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "54b4fc43d44aa4ca9fc03ca7e9949fbae267a064d02da21852412a381b5d1537": [ "windows/140912180251", @@ -7693,7 +9232,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "552f7bdcf1a7af9e6ce672017f4f12abf77240c78e761ac203d1d9d20ac89988": [ "android/lollipop-cts-release", @@ -7706,6 +9255,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -7720,6 +9270,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -7731,6 +9284,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/131003230417", "windows/140312052931", @@ -7757,7 +9314,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "5533a0401f612c688ebce5bf53f2ec14a734eb178bfae00e50e85dae6723078a": [ "windows/131003230417", @@ -7785,7 +9352,20 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" + ], + "55903859c8c0c3ebb8759ece4e2557225ff5758bbd38ebd48276601e1bd58097": [ + "windows/190416222336" ], "55926084ec963a64b96e2abe01ce0ba86a64fbfebcc7aab5afc155b37fd76066": [ "android/kitkat-cts-release", @@ -7800,6 +9380,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -7814,6 +9395,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -7825,6 +9409,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/111018233154", "windows/120125230451", @@ -7859,7 +9447,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "5607e260163f49c8ea4175a1c0a53b13195cb7d07845611e943a2ff507036834": [ "windows/070522004642", @@ -7917,7 +9515,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "568d6905a2c88708a4b3025190edcfedb1974a606a13c6e5290fcb2ae63edab5": [ "android/kitkat-cts-release", @@ -7933,6 +9541,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -7947,6 +9556,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -7959,6 +9571,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/100503224537", "windows/100719231554", @@ -8002,15 +9618,29 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "56c77128d98c18d91b4cfdffbc25ee9103d4758ea2abad826a90f3457d460eb4": [ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -8039,7 +9669,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "56ce347cc6df4c35943dfdeaee023f9739a3f1cedeee0cd88dc2386bc8a91eaf": [ "windows/070109202240", @@ -8154,6 +9794,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -8168,6 +9809,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -8179,6 +9823,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/140912180251", "windows/150122021939", @@ -8203,7 +9851,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "59b3829f1ff443344958fae8bff621b684c848cfbf7ead6b63a6ca50f2794f89": [ "macos/10.11.0", @@ -8217,6 +9875,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "windows/100927165108", "windows/110125205412", "windows/110218005058", @@ -8257,7 +9918,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "5a1b5d6bc65523b40a6deffa45b48e4288ae8dd86dd70a5b858d4a5affc94f71": [ "windows/071219233937", @@ -8312,13 +9983,38 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" + ], + "5a2fc03f0c83b090bbfa40604b0988446c7636183df9846e17101a447fb8efd6": [ + "mozilla/2.32", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "5a885db19c01d912c5759388938cafbbdf031ab2d48e91ee15589b42971d039c": [ + "android/pie-cts-release", "mozilla/2.18", "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "windows/160414222039", "windows/160916174005", "windows/161112005943", @@ -8331,7 +10027,26 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" + ], + "5ab4fcdb180b5b6af0d262a2375a2c77d25602015d96648756611e2e78c53ad3": [ + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "5adfa25013bed3710831572de51c4b9a21171c00313249c4cb4719d37fbb8d20": [ "windows/160916174005", @@ -8345,7 +10060,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "5b1d9d24de0afea8b35ba04a1c3e25d0812cdf7c4625de0a89af9fe4bbd1bb15": [ "windows/110919210309", @@ -8382,7 +10107,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "5b38bd129e83d5a0cad23921089490d50d4aae370428f8ddfffffa4c1564e184": [ "macos/10.10.0", @@ -8407,6 +10142,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -8421,6 +10157,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -8433,6 +10172,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/090501224247", "windows/090825180842", @@ -8480,7 +10223,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "5cc3d78e4e1d5e45547a04e6873e64f90cf9536d1ccc2ef800f355c4c5fd70fd": [ "android/marshmallow-cts-release", @@ -8491,12 +10244,16 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.12.1", "macos/10.12.2", "macos/10.13.0", "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -8505,6 +10262,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/130420010442", "windows/130626232015", @@ -8533,7 +10294,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "5d56499be4d2e08bcfcad08a3e38723d50503bde706948e42f55603019e528ae": [ "android/marshmallow-cts-release", @@ -8544,6 +10315,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.3", "macos/10.10.4", "macos/10.11.0", @@ -8557,6 +10329,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -8565,6 +10340,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/140912180251", "windows/150122021939", @@ -8589,7 +10368,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "5e3571f33f45a7df1537a68b5ffb9e036af9d2f5bc4c9717130dc43d7175aac7": [ "windows/070201011524", @@ -8647,7 +10436,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "5edb7ac43b82a06a8761e8d7be4979ebf2611f7dd79bf91c1c6b566a219ed766": [ "android/kitkat-cts-release", @@ -8663,6 +10462,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -8677,6 +10477,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -8688,6 +10491,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/090825180842", "windows/091013033632", @@ -8734,7 +10541,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "5f0b62eab5e353ea6521651658fbb65359f443280a4afbd104d77d10f9f04c07": [ "android/kitkat-cts-release", @@ -8804,7 +10621,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "5f960eebd716dbcb4d8a78b996e680ec2547441e69b4e44e98a595502e28a002": [ "android/kitkat-mr1-release", @@ -8865,7 +10692,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "604d32d036895aed3bfefaeb727c009ec0f2b3cdfa42a1c71730e6a72c3be9d4": [ "windows/150618202535", @@ -8887,7 +10724,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "606223d9db80df3939601e74b7e828e2800cce4273f76f276aa62db0a8e3b6c1": [ "windows/071219233937", @@ -9062,7 +10909,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "62dd0be9b9f50a163ea0f8e75c053b1eca57ea55c8688f647c6881f2c8357b95": [ "android/kitkat-cts-release", @@ -9078,6 +10935,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -9092,6 +10950,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -9104,6 +10965,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070201011524", "windows/070522004642", @@ -9161,7 +11026,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "62f240278c564c4dd8bf7d9d4f6f366ea894d22f5f34d989a983acec2fffed50": [ "android/kitkat-cts-release", @@ -9304,7 +11179,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "63343abfb89a6a03ebb57e9b3f5fa7be7c4f5c756f3017b3a8c488c3653e9179": [ "macos/10.10.0", @@ -9321,6 +11206,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.4", "macos/10.9.5" ], @@ -9356,14 +11244,34 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "657cfe2fa73faa38462571f332a2363a46fce7020951710702cdfbb6eeda3305": [ "windows/180122185731", "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "6639d13cab85df1ad9a23c443b3a60901e2b138d456fa71183578108884ec6bf": [ "macos/10.10.0", @@ -9380,6 +11288,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -9399,6 +11310,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -9413,6 +11325,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -9425,6 +11340,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/090203164005", "windows/090501224247", @@ -9473,7 +11392,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "67ec2059fbf52d2e6ab51a5a9b3fc2e1dcd658a1ef3a8f31107bc98028b494a2": [ "windows/070109202240", @@ -9603,6 +11532,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -9617,6 +11547,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -9629,6 +11562,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/090825180842", "windows/091013033632", @@ -9675,7 +11612,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "68ad50909b04363c605ef13581a939ff2c96372e3f12325b0a6861e1d59f6603": [ "windows/100927165108", @@ -9718,7 +11665,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "69ddd7ea90bb57c93e135dc85ea6fcd5480b603239bdc454fc758b2a26cf7f79": [ "android/kitkat-cts-release", @@ -9734,6 +11691,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -9748,6 +11706,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -9759,6 +11720,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/090825180842", "windows/091013033632", @@ -9805,7 +11770,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "69fac9bd55fb0ac78d53bbee5cf1d597989fd0aaab20a25151bdf1733ee7d122": [ "android/kitkat-cts-release", @@ -9821,6 +11796,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -9835,6 +11811,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -9847,6 +11826,7 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -9905,13 +11885,31 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" + ], + "6aea30bc02ca85afcfec2f65f60881893c926925fd0704bd8ada3f0f6eddb699": [ + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "6b9c08e86eb0f767cfad65cd98b62149e5494a67f5845e7bd1ed019f27b86bd6": [ "android/nougat-cts-release", "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.11.4", "macos/10.12.0", "macos/10.12.1", @@ -9920,6 +11918,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -9928,6 +11929,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/160113232859", "windows/160123000836", @@ -9944,7 +11949,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "6baf50ae3467eff3c35fefdc76a02a97fab6267723eda91e99f1b3dc2b28f82e": [ "windows/090825180842", @@ -9992,7 +12007,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "6c61dac3a2def031506be036d2a6fe401994fbd13df9c8d466599274c446ec98": [ "android/kitkat-cts-release", @@ -10008,6 +12033,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -10022,6 +12048,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -10034,6 +12063,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/090203164005", "windows/090501224247", @@ -10082,15 +12115,29 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "6cc05041e6445e74696c4cfbc9f80f543b7eabbb44b4ce6f787c6a9971c42f17": [ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -10119,7 +12166,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "6ccfd302fc44bf4599329b9750878ea44e7e8566564bcbd586169762dd10c74e": [ "windows/130626232015", @@ -10148,7 +12205,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "6cf5f658436d10507eba9df463987480bc8560a8e26ef4691e1d3c9a878a0952": [ "macos/10.10.0", @@ -10181,6 +12248,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -10195,6 +12263,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -10207,6 +12278,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/091029013045", "windows/100503224537", @@ -10251,7 +12326,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "6dea86a1e66620a040c3c5943cb215d2ca87fb6ac09b59707e29d2facbd66b4e": [ "android/kitkat-mr1-release", @@ -10351,6 +12436,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -10416,7 +12504,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "6ec6614e9a8efd47d6318ffdfd0bf65b493a141f77c38d0b319be1bbbc053dd2": [ "windows/110919210309", @@ -10453,7 +12551,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "6f2bc4cb632c24eae6782c0f39758932d1e1dc9b3e070f9303073fff38b288e2": [ "macos/10.9.0" @@ -10476,6 +12584,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -10537,7 +12648,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "6fff78e400a70c11011cd85977c459fb5af96a3df0540820d0f4b8607875e58f": [ "macos/10.10.0", @@ -10554,6 +12675,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -10573,6 +12697,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -10587,6 +12712,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -10599,6 +12727,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/100503224537", "windows/100719231554", @@ -10642,7 +12774,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "70b922bfda0e3f4a342e4ee22d579ae598d071cc5ec9c30f123680340388aea5": [ "macos/10.10.0", @@ -10659,6 +12801,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -10684,16 +12829,38 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "71cca5391f9e794b04802530b363e121da8a3043bb26662fea4dca7fc951a4bd": [ + "mozilla/2.30", + "mozilla/2.32", "windows/170922155710", "windows/171121202507", "windows/180122185731", "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "7286ce249fe9e32bd4752257c17cd8f6991a9c1e6f1a3cc73304ed023e6ae4eb": [ "windows/131003230417", @@ -10721,7 +12888,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "730b619eaa759863c65360b7412e1457eca96844ef2f16d91fcf2efe46a647e9": [ "windows/070109202240", @@ -10812,7 +12989,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "73c176434f1bc6d5adf45b0e76e727287c8de57616c1e6e6141a2b2cbc7d8e4c": [ "android/kitkat-cts-release", @@ -10828,6 +13015,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -10842,6 +13030,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -10854,6 +13045,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -10912,7 +13107,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "7431e5f4c3c1ce4690774f0b61e05440883ba9a01ed00ba6abd7806ed3b118cf": [ "android/kitkat-cts-release", @@ -10928,6 +13133,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -10942,6 +13148,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -10954,6 +13163,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -11012,7 +13225,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "744b1147b4a9a69c32785e9e37c3323241ef29f63e76f1603d6761a783d8a0fe": [ "windows/150122021939", @@ -11077,7 +13300,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "75c9d4361cb96e993abd9620cf043be9407a4633f202f0f4c0e17851cc6089cd": [ "macos/10.10.0", @@ -11141,6 +13374,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -11149,6 +13383,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -11207,7 +13445,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "767c955a76412c89af688e90a1c70f556cfd6b6025dbea10416d7eb6831f8c40": [ "android/kitkat-cts-release", @@ -11237,6 +13485,7 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -11336,6 +13585,10 @@ "windows/140312052931", "windows/140912180251" ], + "7707bb2be9f7ce057060b8308c3bc087b56529b3638eaf5b2a8049c8e15ed720": [ + "windows/190315181653", + "windows/190416222336" + ], "77407312c63a153d5bc00b4e51759cdfdac237dc2a33b67946e98e9bfa680ae3": [ "android/kitkat-cts-release", "android/kitkat-mr1-release", @@ -11439,7 +13692,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "77e04c9a751c73f23e2a1336112ec8d5153d382a152fed89d7532c3102771f3c": [ "windows/090501224247", @@ -11488,7 +13751,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "781d64dfa77b00f2c006700b1fda86bf68b865a603c7a656f92e90c042ca2873": [ "windows/080328202117", @@ -11540,7 +13813,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "7908b40314c138100b518d0735807ffbfcf8518a0095337105ba386b153dd927": [ "android/kitkat-cts-release", @@ -11556,6 +13839,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -11570,6 +13854,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -11582,6 +13869,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -11640,7 +13931,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "793cbf4559b9fde38ab22df16869f69881ae14c4b0139ac788a78a1afcca02fb": [ "android/kitkat-cts-release", @@ -11785,7 +14086,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "7af6ea9f753a1e709bd64d0beb867c11e8c295a56e24a6e0471459dccdaa1558": [ "macos/10.11.0", @@ -11799,6 +14110,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "windows/100927165108", "windows/110125205412", "windows/110218005058", @@ -11839,7 +14153,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "7afc9d01a62f03a2de9637936d4afe68090d2de18d03f29c88cfb0b1ba63587f": [ "macos/10.10.0", @@ -11856,6 +14180,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -11969,6 +14296,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -11983,6 +14311,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -11994,6 +14325,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/131003230417", "windows/140312052931", @@ -12020,7 +14355,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "7d2bf3489ebc9ad3448b8b0827715a3cbfe3d523e3b56a9b5fc1d2a2da2f20fe": [ "windows/100503224537", @@ -12065,7 +14410,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "7d3b465a6014e526c0affcee2127d2311727ad811c26842d006af37306cc80bd": [ "android/kitkat-cts-release", @@ -12175,7 +14530,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "7e37cb8b4c47090cab36551ba6f45db840680fba166a952db100717f43053fc2": [ "android/lollipop-cts-release", @@ -12188,6 +14553,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -12202,6 +14568,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -12213,6 +14582,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/131003230417", "windows/140312052931", @@ -12239,7 +14612,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "7f12cd5f7e5e290ec7d85179d5b72c20a5be7508ffdb5bf81ab9684a7fc9f667": [ "android/kitkat-cts-release", @@ -12319,7 +14702,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "8095210805db4bbc355e4428d8fd6ec2cde3ab5fb97a9942988eb8f4dcd06016": [ "android/kitkat-cts-release", @@ -12406,7 +14799,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "81c2568503eb3be5eec366653960e6d1be9448915e4605b793fbeb34ccb2470f": [ "windows/120223022238", @@ -12440,7 +14843,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "82d42db3d657f1944e65c192b1dd58db8df8417b89165b045f5c6a70c5f8939e": [ "windows/130626232015", @@ -12473,6 +14886,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -12525,7 +14941,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "83ce3c1229688a593d485f81973c0f9195431eda37cc5e36430e79c7a888638b": [ "android/kitkat-cts-release", @@ -12595,7 +15021,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "847df6a78497943f27fc72eb93f9a637320a02b561d0a91b09e87a7807ed7c61": [ "windows/110919210309", @@ -12632,21 +15068,50 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "8560f91c3624daba9570b5fea0dbe36ff11a8323be9486854fb3f34a5571198d": [ + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "windows/171121202507", "windows/180122185731", "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "85666a562ee0be5ce925c1d8890a6f76a87ec16d4d7d5f29ea7419cf20123b69": [ + "android/pie-cts-release", + "macos/10.14.0", "mozilla/2.18", "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "windows/160916174005", "windows/161112005943", "windows/170228174808", @@ -12658,7 +15123,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "85a0dd7dd720adb7ff05f83d542b209dc7ff4528f7d677b18389fea5e5c49e86": [ "android/kitkat-cts-release", @@ -12674,6 +15149,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -12688,6 +15164,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -12700,6 +15179,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -12757,7 +15240,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "85e0dfae3e55a843195f8b08c8349050e4689372f6e133ad0d199af96e95cc08": [ "windows/070109202240", @@ -12821,6 +15314,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -12885,7 +15381,28 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" + ], + "86a1ecba089c4a8d3bbe2734c612ba341d813e043cf9e8a862cd5c57a36bbe6b": [ + "mozilla/2.32", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "87c678bfb8b25f38f7e97b336956bbcf144bbacaa53647e61a2325bc1055316b": [ "android/kitkat-cts-release", @@ -12936,6 +15453,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -12944,6 +15462,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -13002,7 +15524,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "885de64c340e3ea70658f01e1145f957fcda27aabeea1ab9faa9fdb0102d4077": [ "windows/070109202240", @@ -13062,7 +15594,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "88ef81de202eb018452e43f864725cea5fbd1fc2d9d205730709c5d8b8690f46": [ "android/lollipop-cts-release", @@ -13075,6 +15617,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.3", "macos/10.10.4", "macos/10.11.0", @@ -13088,6 +15631,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -13096,6 +15642,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/130626232015", "windows/131003230417", @@ -13123,7 +15673,21 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" + ], + "88f438dcf8ffd1fa8f429115ffe5f82ae1e06e0c70c375faad717b34a49e7265": [ + "windows/190315181653", + "windows/190416222336" ], "894ce6ddb012cb3f736954668de63f436080e95f17b7a81bd924eb21bee9e440": [ "windows/071219233937", @@ -13178,7 +15742,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "894ebc0b23da2a50c0186b7f8f25ef1f6b2935af32a94584ef80aaf877a3a06e": [ "macos/10.10.0", @@ -13195,6 +15769,8 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -13238,7 +15814,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "8a866fd1b276b57e578e921c65828a2bed58e9f2f288054134b7f1f4bfc9cc74": [ "android/lollipop-cts-release", @@ -13251,6 +15837,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.3", "macos/10.10.4", "macos/10.11.0", @@ -13264,6 +15851,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -13272,6 +15862,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/130626232015", "windows/131003230417", @@ -13299,7 +15893,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "8a968aadd88b20519672a452a3d6e31eacb71c26bcaf65b32f9793bf2ffa54a9": [ "macos/10.10.0", @@ -13338,7 +15942,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "8b45da1c06f791eb0cabf26be588f5fb23165c2e614bf885562d0dce50b29b02": [ "android/nougat-cts-release", @@ -13368,7 +15982,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "8ba1bd9c88efb3947e60ebe21137f81df7f09994cef27f097055018b8194c634": [ "windows/140912180251", @@ -13392,7 +16016,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "8c4edfd04348f322969e7e29a4cd4dca004655061c16e1b076422ef342ad630e": [ "android/kitkat-cts-release", @@ -13463,7 +16097,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "8c7209279ac04e275e16d07fd3b775e80154b5968046e31f52dd25766324e9a7": [ "android/kitkat-cts-release", @@ -13491,6 +16135,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -13514,6 +16161,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -13528,6 +16176,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -13540,6 +16191,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -13598,7 +16253,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "8da084fcf99ce07722f89b3205939806fa5cb811e1c813f6a108c7d336b3408e": [ "android/kitkat-cts-release", @@ -13708,7 +16373,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "8dbb5a7c06c20ef62dd912a36740992ff6e1e8583d42ede257c3affd7c769399": [ "windows/070109202240", @@ -13782,7 +16457,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "8e8c6ebf77dc73db3e38e93f4803e62b6b5933beb51ee4152f68d7aa14426b31": [ "windows/090825180842", @@ -13794,9 +16479,13 @@ "8ecde6884f3d87b1125ba31ac3fcb13d7016de7f57cc904fe1cb97c6ae98196e": [ "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "mozilla/2.11", "mozilla/2.14", "mozilla/2.16", @@ -13804,6 +16493,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "windows/160113232859", "windows/160123000836", "windows/160128175153", @@ -13819,7 +16512,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "8f1ecdaf29bcd56eddd6b5d56a07fcac2b74d4bcd179179144a0365c27dcf14b": [ "windows/121102212406", @@ -13905,7 +16608,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "8f9e2751dcd574e9ba90e744ea92581fd0af640ae86ac1ce2198c90f96b44823": [ "windows/070109202240", @@ -14002,6 +16715,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.3", "macos/10.10.4", "macos/10.11.0", @@ -14015,6 +16729,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -14023,6 +16740,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/130626232015", "windows/131003230417", @@ -14047,7 +16768,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "90f3e05396995ff20922c44592db62d7845e1bf64aef512cca75bc669caa2479": [ "windows/070702210503", @@ -14104,7 +16835,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "9111240747e1f652f66d1f712a11f698963b491702e312f7513da3d0fc1e5a28": [ "windows/150122021939", @@ -14129,6 +16870,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -14143,6 +16885,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -14154,6 +16899,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/131003230417", "windows/140312052931", @@ -14180,7 +16929,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "92a9d9833fe1944db366e8bfae7a95b6480c2d6c6c2a1be65d4236b608fca1bb": [ "macos/10.10.0", @@ -14197,6 +16956,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -14271,7 +17033,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "92d8092ee77bc9208f0897dc05271894e63ef27933ae537fb983eef0eae3eec8": [ "macos/10.10.0", @@ -14288,6 +17060,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5" @@ -14307,6 +17082,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -14359,7 +17137,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "940ef46536713d8e2eb4b501e80b6abd8eb4e9928dba44784ce7d7e98595dfe8": [ "macos/10.9.0" @@ -14373,6 +17161,9 @@ "macos/10.9.4", "macos/10.9.5" ], + "945bbc825ea554f489d1fd51a73ddf2ea624ac7019a05205225c22a78ccfa8b4": [ + "windows/190416222336" + ], "956057517ff3bb35049342288c1c9dce852daca652b465e9747253b5f93b1f5e": [ "windows/070109202240", "windows/070201011524", @@ -14420,7 +17211,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "959dc5880c457cd92e5447aaa5609db09ed47bd02c17a0edefdc819e756c74e5": [ "macos/10.10.0", @@ -14445,6 +17246,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -14453,6 +17255,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070201011524", "windows/070522004642", @@ -14510,7 +17316,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "9676f287356c89a12683d65234098cb77c4f1c18f23c0e541de0e196725b7ebe": [ "macos/10.10.0", @@ -14531,12 +17347,16 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.12.1", "macos/10.12.2", "macos/10.13.0", "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -14545,7 +17365,23 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", - "mozilla/2.9" + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", + "mozilla/2.9", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" + ], + "97552015f5ddfc3c8788c006944555408894450084f100867086bc1a2bb58dc8": [ + "windows/190416222336" ], "978cd966f2faa07ba7aa9500d9c02e9d77f2cdada6ad6ba74af4b91c66593c50": [ "android/kitkat-cts-release", @@ -14574,6 +17410,7 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -14642,7 +17479,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "9806ab8509e2f35e192f275f0c308b9409b42512f90c659598c22be613962272": [ "windows/070109202240", @@ -14690,7 +17537,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "9a114025197c5bb95d94e63d55cd43790847b646b23cdf11ada4a00eff15fb48": [ "android/kitkat-cts-release", @@ -14706,6 +17563,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -14720,6 +17578,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -14731,6 +17592,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/111018233154", "windows/120125230451", @@ -14765,7 +17630,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "9a6ec012e1a7da9dbe34194d478ad7c0db1822fb071df12981496ed104384113": [ "android/kitkat-cts-release", @@ -14781,6 +17656,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -14789,6 +17665,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/130420010442", "windows/130626232015", @@ -14817,7 +17697,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "9a73929a500f1a0bf49dcb046e8039169696557345e9f813f10ff9380db22695": [ "macos/10.10.0", @@ -14834,6 +17724,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -14853,6 +17746,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -14867,6 +17761,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -14879,6 +17776,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -14937,7 +17838,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "9b14e8f5f6ea167666e76dcd6becc190861d5e8970b99a9470f0231236049704": [ "windows/131003230417", @@ -14951,6 +17862,8 @@ "windows/150820181119" ], "9bea11c976fe014764c1be56a6f914b5a560317abd9988393382e5161aa0493c": [ + "mozilla/2.30", + "mozilla/2.32", "windows/161112005943", "windows/170228174808", "windows/170419224008", @@ -14961,7 +17874,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "9cefb0cb7b74e642932532831e0dc8f4d68ad414261fc3f474b795e72a164e57": [ "windows/150618202535", @@ -14983,7 +17906,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "9d190b2e314566685be8a889e27aa8c7d7ae1d8aaddba3c1ecf9d24863cd34b9": [ "macos/10.10.0", @@ -15000,6 +17933,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5" @@ -15118,6 +18054,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -15137,6 +18076,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -15145,6 +18085,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -15203,12 +18147,24 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "a040929a02ce53b4acf4f2ffc6981ce4496f755e6d45fe0b2a692bcd52523f36": [ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", + "macos/10.14.0", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -15217,6 +18173,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/151119231843", "windows/160113232859", @@ -15234,7 +18194,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "a0459b9f63b22559f5fa5d4c6db3f9f72ff19342033578f073bf1d1b46cbb912": [ "android/kitkat-cts-release", @@ -15250,6 +18220,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -15258,6 +18229,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -15316,13 +18291,24 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "a1339d33281a0b56e557d3d32b1ce7f9367eb094bd5fa72a7e5004c8ded7cafe": [ "android/nougat-cts-release", "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -15331,6 +18317,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/170228174808", "windows/170419224008", @@ -15341,12 +18331,25 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "a1a86d04121eb87f027c66f53303c28e5739f943fc84b38ad6af009035dd9457": [ "macos/10.13.1", "macos/10.13.2", - "macos/10.13.3" + "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0" ], "a1b2dbeb64e706c6169e3c4118b23baa09018a8427666d8bf0e28891ec051950": [ "windows/110919210309", @@ -15383,7 +18386,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "a1f05ccb80c2d710ec7d479abdcbb879e58d7edb7149fe78a87884e3d0bad0f9": [ "macos/10.10.0", @@ -15400,6 +18413,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -15452,7 +18468,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "a22dba681e97376e2d397d728aae3a9b6296b9fdba60bc2e11f647f2c675fb37": [ "android/kitkat-cts-release", @@ -15468,6 +18494,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -15482,6 +18509,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -15546,7 +18576,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "a31f093053bd12c1f5c3c6efd498023fd2914d7758d05d698ce084b50626e0e5": [ "macos/10.10.0", @@ -15563,6 +18603,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -15618,7 +18661,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "a3cc68595dfe7e86d8ad1772a8b5284add54ace3b8a798df47bccafb1fdb84df": [ "windows/160414222039", @@ -15633,7 +18686,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "a3d7435a18c46b23b6a4f8929cd59050c9168b03a7fad532626f297cac5356e4": [ "windows/110919210309", @@ -15670,7 +18733,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "a4310d50af18a6447190372a86afaf8b951ffb431d837f1e5688b45971ed1557": [ "android/kitkat-cts-release", @@ -15686,6 +18759,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -15700,6 +18774,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -15712,6 +18789,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/090825180842", "windows/091013033632", @@ -15758,7 +18839,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "a45ede3bbbf09c8ae15c72efc07268d693a21c996fd51e67ca079460fd6d8873": [ "android/kitkat-cts-release", @@ -15774,6 +18865,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -15788,6 +18880,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -15800,6 +18895,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -15858,7 +18957,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "a4b6b3996fc2f306b3fd8681bd63413d8c5009cc4fa329c2ccf0e2fa1b140305": [ "android/kitkat-cts-release", @@ -15973,7 +19082,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "a6c51e0da5ca0a9309d2e4c0e40c2af9107aae8203857fe198e3e769e343085c": [ "android/kitkat-cts-release", @@ -16119,7 +19238,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "a798a1c70e9b6d50eaa5724a26fac7991848edc61bf48d79816bcafb66972128": [ "windows/070109202240", @@ -16224,7 +19353,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "aad9ceed5aa6b1cea28596a8e4e1abed9386d6ebc9d4aad9acde0fa36ba069d0": [ "macos/10.10.0", @@ -16287,7 +19426,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "ab7036365c7154aa29c2c29f5d4191163b162a2225011357d56d07ffa7bc1f72": [ "macos/10.10.0", @@ -16352,7 +19501,24 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" + ], + "ac7f7862e685c7a7d9826a58ea32d183d4893fcc8f8fd6d900c9769a987e77f0": [ + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "ad016f958050e0e7e46fae7dcc50197ed8e3ff0a4b262e5ddcdb3edddc7d6578": [ "windows/100503224537", @@ -16397,7 +19563,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "ad7539e5cdc985fa95244055a9202d63460ec921467d034cfdbe87ec6d00fedc": [ "windows/130626232015", @@ -16452,6 +19628,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -16512,7 +19691,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "ae92e90000541a9ebc101b70b6c33a62f5a53a55ba815e81d31abddf03507f5d": [ "windows/070109202240", @@ -16572,7 +19761,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "af6d08eef3cac4e1584abc63c8a9472ac529af99f3f791319a43776063f58dca": [ "windows/070109202240", @@ -16632,7 +19831,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "af71a3bca322e5224df546895696ce449a8bd2bd130f7a7ae457767f5c23d8f8": [ "windows/070109202240", @@ -16801,7 +20010,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "b04d708f1ae0456265dd1b66907a2691a28680b853e031df3df9083af71614d7": [ "windows/070109202240", @@ -16856,6 +20075,7 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -16917,7 +20137,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "b0b1730ecbc7ff4505142c49f1295e6eda6bcaed7e2c68c5be91b5a11001f024": [ "macos/10.10.0", @@ -16934,6 +20164,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -16952,6 +20185,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -16966,6 +20200,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -16977,6 +20214,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/131003230417", "windows/140312052931", @@ -17003,7 +20244,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "b2259996fff735ab35014ef63f3d413190079dd03a0962432635a8695f995305": [ "windows/100927165108", @@ -17067,7 +20318,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "b32396746453442f353e616292bb20bbaa5d23b546450fdb9c54b8386167d529": [ "macos/10.10.0", @@ -17084,6 +20345,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -17113,7 +20377,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "b3c962d34019fb38ab9fe9c62399742ab26c43c2d18ce3f2b13c14321e52964b": [ "windows/070109202240", @@ -17272,7 +20546,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "b478b812250df878635c2aa7ec7d155eaa625ee82916e2cd294361886cd1fbd4": [ "android/kitkat-cts-release", @@ -17288,6 +20572,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -17302,6 +20587,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -17313,6 +20601,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/090825180842", "windows/091013033632", @@ -17359,7 +20651,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "b5bd2cb79cbd1907298d6bdf4842e516d8c78fa6fc96d25f71af814e16cc245e": [ "windows/080828200829", @@ -17411,7 +20713,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "b6191a50d0c3977f7da99bcdaac86a227daeb9679ec70ba3b0c9d92271c170d3": [ "android/kitkat-cts-release", @@ -17427,6 +20739,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -17441,6 +20754,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -17453,6 +20769,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -17511,7 +20831,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "b644d955fff29b74e3b5687e908ee7c3c9197ba3336cc6328531f6c057d677fd": [ "windows/100927165108", @@ -17554,13 +20884,24 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "b676f2eddae8775cd36cb0f63cd1d4603961f49e6265ba013a2f0307b6d0b804": [ "android/nougat-cts-release", "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.12.0", "macos/10.12.1", "macos/10.12.2", @@ -17568,6 +20909,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -17576,6 +20920,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/160916174005", "windows/161112005943", @@ -17588,7 +20936,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "b7a7ec419454411761225ecf30d99585f851356077bf83274b11588fd05521b8": [ "macos/10.9.0" @@ -17652,9 +21010,13 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -17683,7 +21045,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "b8bbe523bfca3b11d50f73f7f10b3ec8ec958aa1dc86f66d9541907ff1a110ef": [ "windows/090203164005", @@ -17783,7 +21155,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "ba7f1136389075b8e86c53c095fa14f5c83b6b017a0244ed7637114620d3a3b1": [ "macos/10.9.0", @@ -17805,6 +21187,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -17819,6 +21202,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -17830,6 +21216,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/130420010442", "windows/130626232015", @@ -17858,7 +21248,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "bc23f98a313cb92de3bbfc3a5a9f4461ac39494c4ae15a9e9df131e99b73019a": [ "android/kitkat-cts-release", @@ -17911,6 +21311,17 @@ "windows/140912180251", "windows/150122021939" ], + "bc4d809b15189d78db3e1d8cf4f9726a795da1643ca5f1358e1ddb0edc0d7eb3": [ + "mozilla/2.32", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" + ], "bcdd8df4276366d7ff4b688dc81500d8e98252c049c8ff1e8c82f2baec9d5c16": [ "windows/070109202240", "windows/070201011524", @@ -17972,6 +21383,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -17986,6 +21398,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -17998,6 +21413,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/100719231554", "windows/100927165108", @@ -18040,7 +21459,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "bd81ce3b4f6591d11a67b5fc7a47fdef25521bf9aa4e18b9e3df2e34a7803be8": [ "android/kitkat-cts-release", @@ -18084,6 +21513,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -18098,6 +21528,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -18110,6 +21543,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070201011524", "windows/070522004642", @@ -18167,7 +21604,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "bebce57dcb85f60a93bfa5019edb1a294bf6d81f82d9b4e71f502f0b15a1fc08": [ "windows/160916174005", @@ -18181,7 +21628,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "bec94911c2955676db6c0a550986d76e3ba005667c442c9762b4fbb773de228c": [ "android/lollipop-mr1-cts-release", @@ -18193,6 +21650,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -18207,6 +21665,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -18218,6 +21679,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/130626232015", "windows/131003230417", @@ -18245,7 +21710,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "bf0feefb9e3a581ad5f9e9db7589985743d261085c4d314f6f5d7259aa421612": [ "android/kitkat-cts-release", @@ -18261,6 +21736,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -18273,6 +21749,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/090501224247", "windows/090825180842", @@ -18320,6 +21800,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -18334,6 +21815,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -18346,6 +21830,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/090825180842", "windows/091013033632", @@ -18392,13 +21880,28 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "bfff8fd04433487d6a8aa60c1a29767a9fc2bbb05e420f713a13b992891d3893": [ + "android/pie-cts-release", "mozilla/2.18", "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "windows/150618202535", "windows/150723231635", "windows/150820181119", @@ -18418,7 +21921,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "c0a6f4dc63a24bfdcf54ef2a6a082a0a72de35803e2ff5ff527ae5d87206dfd5": [ "android/kitkat-cts-release", @@ -18434,6 +21947,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -18448,6 +21962,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -18460,6 +21977,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/080328202117", "windows/080612204220", @@ -18511,7 +22032,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "c0c05a8d8da55eaf27aa9b910b0a6ef0d8bbded346928db872e182c2073e9802": [ "macos/10.10.0", @@ -18528,6 +22059,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -18596,7 +22130,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "c1b12f480020336e5b04f520bc19c2e2e10ab42c9d9235f05cbec33ffa4d4dea": [ "windows/070109202240", @@ -18656,7 +22200,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "c1b48299aba5208fe9630ace55ca68a03eda5a519c8802a0d3a673be8f8e557d": [ "android/kitkat-cts-release", @@ -18671,6 +22225,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -18685,6 +22240,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -18697,6 +22255,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -18755,7 +22317,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "c1cf0b52096435e3f1b71daaec455a2311c8404f5583a9e213c69d857d943305": [ "android/kitkat-mr1-release", @@ -18806,7 +22378,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "c2157309d9aee17bf34f4df5e88dbaeba57e0361eb814cbc239f4d54d329a38d": [ "windows/140912180251", @@ -18832,7 +22414,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "c2959db8339e8dbcf6409ca92a66c49fd2e32494940a901143bd7eb72827dec2": [ "windows/070109202240", @@ -18887,6 +22479,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.4", "macos/10.9.5" ], @@ -18914,7 +22509,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "c34c5df53080078ffe45b21a7f600469917204f4f0293f1d7209393e5265c04f": [ "windows/150723231635", @@ -18935,7 +22540,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "c3846bf24b9e93ca64274c0ec67c1ecc5e024ffcacd2d74019350e81fe546ae4": [ "android/kitkat-cts-release", @@ -18951,6 +22566,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -18965,6 +22581,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -18977,6 +22596,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -19035,7 +22658,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "c38dcb38959393358691ea4d4f3ce495ce748996e64ed1891d897a0fc4dd55c6": [ "android/kitkat-mr1-release", @@ -19102,13 +22735,25 @@ "windows/160916174005" ], "c45d7bb08e6d67e62e4235110b564e5f78fd92ef058c840aea4e6455d7585c60": [ + "mozilla/2.30", + "mozilla/2.32", "windows/170922155710", "windows/171121202507", "windows/180122185731", "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "c470cf547e2302b977fb29dd71a89a7b6c1f60777b0329f56017f328bf4f6be6": [ "android/kitkat-cts-release", @@ -19229,6 +22874,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -19287,7 +22935,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "c57bacf238f9336c3dfba62d12bcf5823603e5842c44e62f5448cc7e5f4cad59": [ "macos/10.9.0" @@ -19319,6 +22977,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -19373,7 +23034,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "c795ff8ff20c966688f064a1e091421d3110a3456c17ec2404b998738741f622": [ "windows/150618202535", @@ -19395,7 +23066,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "c7ba6567de93a798ae1faa791e712d378fae1f93c4397fea441bb7cbe6fd5995": [ "android/kitkat-cts-release", @@ -19424,6 +23105,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -19458,7 +23142,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "ca2d82a08677072f8ab6764ff035676cfe3e5e325e012172df3f92096db79b85": [ "android/kitkat-cts-release", @@ -19534,7 +23228,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "ca42dd41745fd0b81eb902362cf9d8bf719da1bd1b1efc946f5b4c99f42c1b9e": [ "android/kitkat-cts-release", @@ -19550,6 +23254,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -19564,6 +23269,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -19576,6 +23284,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070201011524", "windows/070522004642", @@ -19633,7 +23345,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "ca7a5e68c53d2c51f72f6b465d3ed753f5903ec7901c8d0f55d868337c81975a": [ "windows/110125205412", @@ -19675,7 +23397,29 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" + ], + "caca93b9d23d2b6fa76e8b8471931e0df3ec6f63af3cdbb936c41954a1872326": [ + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "cb3ccbb76031e5e0138f8dd39a23f9de47ffc35e43c1144cea27d46a5ab1cb5f": [ "android/lollipop-cts-release", @@ -19688,6 +23432,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -19702,6 +23447,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -19713,6 +23461,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/131003230417", "windows/140312052931", @@ -19739,7 +23491,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "cb627d18b58ad56dde331a30456bc65c601a4e9b18dedcea08e7daaa07815ff0": [ "macos/10.10.0", @@ -19756,6 +23518,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5" @@ -19783,6 +23548,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -19797,6 +23563,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -19809,6 +23578,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/100503224537", "windows/100719231554", @@ -19852,7 +23625,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "cbb5af185e942a2402f9eacbc0ed5bb876eea3c1223623d00447e4f3ba554b65": [ "macos/10.10.0", @@ -19869,6 +23652,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -19918,7 +23704,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "ccc89489371bad111c90619bea240a2e6dadd99f9f6e1d4d41e58ed6de3d0285": [ "windows/070109202240", @@ -19978,7 +23774,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "cd0b3b2aa174b55f18c7502f3c3a76f2198175ce45637370cf4f48b9c2ce4fbf": [ "windows/090825180842", @@ -20026,7 +23832,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "cd201256fe5ced0bfff8df595fff36b1416d5313a999f532ef4a9915df96dee0": [ "windows/090825180842", @@ -20074,7 +23890,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "cd808284cf746ff2fd6eb58aa1d59c4ad4b3ca56fdc6274a8926a7835f32313d": [ "macos/10.10.0", @@ -20150,7 +23976,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "cecddc905099d8dadfc5b1d209b737cbe2c18cfb2c10c0ff0bcf0d3286fc1aa2": [ "android/kitkat-cts-release", @@ -20166,6 +24002,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -20180,6 +24017,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -20192,6 +24032,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -20250,7 +24094,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "cf56ff46a4a186109dd96584b5eeb58a510c4275b0e5f94f40bbae865e19f673": [ "android/kitkat-cts-release", @@ -20319,7 +24173,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "d1c339ea2784eb870f934fc5634e4aa9ad5505016401f26465d37a574663359f": [ "macos/10.10.0", @@ -20336,6 +24200,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -20373,13 +24240,28 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "d40e9c86cd8fe468c1776959f49ea774fa548684b6c406f3909261f4dce2575c": [ + "android/pie-cts-release", "mozilla/2.18", "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "windows/160414222039", "windows/160916174005", "windows/170228174808", @@ -20391,7 +24273,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "d41d829e8c1659822af93fce62bffcde264fc84e8b950c5ff275d052354695a3": [ "android/kitkat-cts-release", @@ -20470,9 +24362,21 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "d43af9b35473755c9684fc06d7d8cb70ee5c28e773fb294eb41ee71722924d24": [ + "mozilla/2.30", + "mozilla/2.32", "windows/161112005943", "windows/170228174808", "windows/170419224008", @@ -20483,7 +24387,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "d487a56f83b07482e85e963394c1ecc2c9e51d0903ee946b02c301581ed99e16": [ "android/nougat-cts-release", @@ -20513,9 +24427,21 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "d48d3d23eedb50a459e55197601c27774b9d7b18c94d5a059511a10250b93168": [ + "mozilla/2.30", + "mozilla/2.32", "windows/160414222039", "windows/160916174005", "windows/161112005943", @@ -20528,7 +24454,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "d68f7730b1ec2b3fb698c96d76540c9997415a25737dcd61d44960db77d2723d": [ "macos/10.9.0" @@ -20571,7 +24507,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "d7a7a0fb5d7e2731d771e9484ebcdef71d5f0c3e0a2948782bc83ee0ea699ef4": [ "android/kitkat-cts-release", @@ -20587,6 +24533,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -20601,6 +24548,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -20613,6 +24563,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -20671,7 +24625,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "d7ba3f4ff8ad05633451470dda3378a3491b90005e5c687d2b68d53647cfdd66": [ "windows/170922155710", @@ -20680,7 +24644,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "d80fef910ae3f104723b045cec2d019f441ce6213adf156791e70c1790110a31": [ "windows/150618202535", @@ -20701,7 +24675,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "d8e0febc1db2e38d00940f37d27d41344d993e734b99d5656d9778d4d8143624": [ "android/kitkat-cts-release", @@ -20731,6 +24715,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -20797,7 +24784,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "d95fea3ca4eedce74cd76e75fc6d1ff62c441f0fa8bc77f034b19e5db258015d": [ "android/kitkat-cts-release", @@ -20825,6 +24822,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -20858,7 +24858,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "da98f640194df128c7888bc8e3479a9dd31795ff087c649052fbafb02eaef184": [ "macos/10.10.0", @@ -20869,6 +24879,16 @@ "macos/10.9.4", "macos/10.9.5" ], + "db3517d1f6732a2d5ab97c533ec70779ee3270a62fb4ac4238372460e6f01e88": [ + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" + ], "dd6936fe21f8f077c123a1a521c12224f72255b73e03a7260693e8a24b0fa389": [ "android/kitkat-cts-release", "android/kitkat-mr2-release", @@ -20882,6 +24902,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -20896,6 +24917,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -20907,6 +24931,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/100503224537", "windows/100719231554", @@ -20950,7 +24978,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "ddbf149733bc2bf8a09d7f012b01a6dea11d7bae26713783ef6407a2495bf189": [ "windows/170228174808", @@ -20962,7 +25000,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "ddff53ecd7743b60bb7b2795ff5732fa785f9a14df1120fb40a38cf84ca2a566": [ "windows/070201011524", @@ -21021,7 +25069,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "df545bf919a2439c36983b54cdfc903dfa4f37d3996d8d84b4c31eec6f3c163e": [ "windows/100719231554", @@ -21065,7 +25123,24 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" + ], + "dfb3c314740596ad5fb97960ef62ad7c1fcceead16e74054652d1032e6f140ef": [ + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "e0e17aea06cf9ce12aae8190345a2c59720130a7d8ff72f3745ad75dbaa365b6": [ "windows/140912180251", @@ -21091,7 +25166,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "e17890ee09a3fbf4f48b9c414a17d637b7a50647e9bc752322727fcc1742a911": [ "android/kitkat-cts-release", @@ -21119,6 +25204,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -21142,6 +25230,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -21156,6 +25245,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -21167,6 +25259,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/131003230417", "windows/140312052931", @@ -21193,7 +25289,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "e28393773da845a679f2080cc7fb44a3b7a1c3792cb7eb7729fdcb6a8d99aea7": [ "android/kitkat-cts-release", @@ -21262,7 +25368,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "e3268f6106ba8b665a1a962ddea1459d2a46972f1f2440329b390b895749ad45": [ "macos/10.10.3", @@ -21277,14 +25393,21 @@ "macos/10.13.0", "macos/10.13.1", "macos/10.13.2", - "macos/10.13.3" + "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0" ], "e35d28419ed02025cfa69038cd623962458da5c695fbdea3c22b0bfb25897092": [ "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "mozilla/2.11", "mozilla/2.14", "mozilla/2.16", @@ -21292,6 +25415,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "windows/160113232859", "windows/160123000836", "windows/160128175153", @@ -21307,7 +25434,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "e389360d0fdbaeb3d250584b4730314e222f39c156a020144e8d960561791506": [ "android/kitkat-cts-release", @@ -21389,6 +25526,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -21403,6 +25541,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -21415,6 +25556,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/080328202117", "windows/080612204220", @@ -21467,7 +25612,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "e3efb6118a92e3b858fd806f690e31d46b95ca1bd756da2b3037fe2f87cc9137": [ "macos/10.9.0", @@ -21503,6 +25658,7 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -21564,7 +25720,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "e57210ab812c8df308267cb4291b98e956597ca36ec2b95189ef1723396bcac8": [ "windows/070109202240", @@ -21725,7 +25891,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "e6b8f8766485f807ae7f8dac1670461f07c0a13eef3a1ff717538d7abad391b4": [ "android/kitkat-cts-release", @@ -21840,7 +26016,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "e74fbda55bd564c473a36b441aa799c8a68e077440e8288b9fa1e50e4bbaca11": [ "windows/170228174808", @@ -21852,7 +26038,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "e75e72ed9f560eec6eb4800073a43fc3ad19195a392282017895974a99026b6c": [ "android/kitkat-cts-release", @@ -21868,6 +26064,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -21882,6 +26079,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -21894,6 +26094,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -21952,7 +26156,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "e7685634efacf69ace939a6b255b7b4fabef42935b50a265acb5cb6027e44e70": [ "macos/10.10.0", @@ -22017,7 +26231,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "e793c9b02fd8aa13e21c31228accb08119643b749c898964b1746d46c3d4cbd2": [ "android/lollipop-mr1-cts-release", @@ -22029,12 +26253,16 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.12.1", "macos/10.12.2", "macos/10.13.0", "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -22043,6 +26271,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/100927165108", "windows/110125205412", @@ -22084,7 +26316,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "e873d4082a7b4632934f48a5cc1ee500932f661e56c3467c5c84d31447476b0c": [ "windows/070109202240", @@ -22290,6 +26532,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -22304,6 +26547,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -22315,6 +26561,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/090203164005", "windows/090501224247", @@ -22363,7 +26613,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "eac0220c5c9fecc5121d3720872d06707b5266be25d4ebb56ab804bbbf85fe03": [ "macos/10.10.0", @@ -22428,7 +26688,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "eb04cf5eb1f39afa762f2bb120f296cba520c1b97db1589565b81cb9a17b7244": [ "android/kitkat-cts-release", @@ -22444,6 +26714,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -22458,6 +26729,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -22470,6 +26744,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -22528,7 +26806,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "eb7e05aa58e7bd328a282bf8867033f3c035342b516ee85c01673dffffbbfe58": [ "windows/090203164005", @@ -22578,11 +26866,23 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "ebc5570c29018c4d67b1aa127baf12f703b4611ebc17b7dab5573894179b93fa": [ "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", + "macos/10.14.0", "mozilla/2.11", "mozilla/2.14", "mozilla/2.16", @@ -22590,13 +26890,27 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "windows/170922155710", "windows/171121202507", "windows/180122185731", "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "ebd41040e4bb3ec742c9e381d31ef2a41a48b6685c96e7cef3c1df6cd4331c99": [ "android/kitkat-cts-release", @@ -22612,6 +26926,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -22626,6 +26941,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -22638,6 +26956,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/080328202117", "windows/080612204220", @@ -22690,7 +27012,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "ebf3c02a8789b1fb7d511995d663b72906d913ce0d5e10568a8a77e2586167e7": [ "android/kitkat-cts-release", @@ -22831,7 +27163,24 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" + ], + "ecdd47b5acbfa328211e1bff54adeac95e6991e3c1d50e27b527e903208040a1": [ + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "edf7ebbca27a2a384d387b7d4010c666e2edb4843e4c29b4ae1d5b9332e6b24d": [ "android/kitkat-cts-release", @@ -22847,6 +27196,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -22861,6 +27211,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -22872,6 +27225,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/111018233154", "windows/120125230451", @@ -22906,7 +27263,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "eec5496b988ce98625b934092eec2908bed0b0f316c2d4730c84eaf1f3d34881": [ "android/kitkat-cts-release", @@ -22922,6 +27289,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -22936,6 +27304,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -22947,6 +27318,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/120223022238", "windows/120406192127", @@ -22979,7 +27354,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "eefca888db442cea1f03fac5de5b1af210ae03f5e1658ddb880c645e78624546": [ "windows/091013033632", @@ -23021,6 +27406,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -23035,6 +27421,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -23101,7 +27490,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "efb5157e9c66caa1dcc63c9fac0127cde83b7a426c4579b7b43a41ba46a56deb": [ "windows/111018233154", @@ -23137,7 +27536,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "f00355eef101c7df4e46cce6417dffce3db82dbb1369c3b439c4e33bee445c42": [ "windows/070201011524", @@ -23196,7 +27605,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "f008733ec500dc498763cc9264c6fcea40ec22000e927d053ce9c90bfa046cb2": [ "macos/10.10.0", @@ -23213,6 +27632,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -23272,7 +27694,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "f09b122c7114f4a09bd4ea4f4a99d558b46e4c25cd81140d29c05613914c3841": [ "android/kitkat-cts-release", @@ -23301,6 +27733,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -23339,7 +27774,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "f1b13f5c9a326403b0f31bbe7699cd17c7d1c0b981586dd1a7b219c52508fe99": [ "windows/070702210503", @@ -23396,7 +27841,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "f1c1b50ae5a20dd8030ec9f6bc24823dd367b5255759b4e71b61fce9f7375d73": [ "android/kitkat-cts-release", @@ -23412,6 +27867,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -23426,6 +27882,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -23438,6 +27897,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -23496,7 +27959,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "f1f3cc207a6d47947b8cb9c30422229de0d71fb867e0b9a3eda08e0e1736bc28": [ "windows/070109202240", @@ -23558,7 +28031,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "f356bea244b7a91eb35d53ca9ad7864ace018e2d35d5f8f96ddf68a6f41aa474": [ "android/kitkat-cts-release", @@ -23573,12 +28056,16 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.12.1", "macos/10.12.2", "macos/10.13.0", "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "mozilla/2.10", "mozilla/2.11", "mozilla/2.14", @@ -23587,6 +28074,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/110919210309", "windows/111018233154", @@ -23622,7 +28113,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "f375e2f77a108bacc4234894a9af308edeca1acd8fbde0e7aaa9634e9daf7e1c": [ "windows/091029013045", @@ -23709,7 +28210,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "f4336bc2ac75950beccf1c1f2f9da6dddafd1f41161ca71f59c76889bd474033": [ "windows/110919210309", @@ -23746,7 +28257,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "f4c149551a3013a35bc7bffe17a7f3449bc1ab5b5a0ae74b06c23b90004c0104": [ "android/kitkat-cts-release", @@ -23907,6 +28428,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -23921,6 +28443,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -23955,7 +28480,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "f9e67d336c51002ac054c632022d66dda2e7e3fff10ad061ed31d8bbb410cfb2": [ "android/kitkat-cts-release", @@ -23971,6 +28506,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -23985,6 +28521,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -23997,6 +28536,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -24055,7 +28598,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "fabcf5197cdd7f458ac33832d3284021db2425fd6bea7a2e69b7486e8f51f9cc": [ "macos/10.10.0", @@ -24072,6 +28625,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -24100,7 +28656,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "fad540811afae0dc767cdf6572a088fa3ce8493dd82b3b869a67d10aab4e8124": [ "windows/170419224008", @@ -24111,7 +28677,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "fb47d92a9909fd4fa9bec02737543e1f3514ced747407a8d9cfa397b0915067c": [ "windows/120223022238", @@ -24145,7 +28721,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "fc0a0fe27c9dc13c81238a5913a1daf8184168beb7e5a4512a771fd4f453651d": [ "windows/070109202240", @@ -24191,7 +28777,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "fcbfe2886206f72b27593c8b070297e12d769ed10ed7930705a8098effc14d17": [ "android/kitkat-cts-release", @@ -24221,6 +28817,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -24269,7 +28868,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "fd73dad31c644ff1b43bef0ccdda96710b9cd9875eca7e31707af3e96d522bbd": [ "android/kitkat-cts-release", @@ -24285,6 +28894,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -24299,6 +28909,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5", @@ -24310,6 +28923,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/110919210309", "windows/111018233154", @@ -24345,7 +28962,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "fe7114d07a147759891ff37b4f53eb43568296bc3bf89bc12cafb186985ef28d": [ "windows/071219233937", @@ -24400,7 +29027,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "fe863d0822fe7a2353fa484d5924e875656d3dc9fb58771f6f616f9d571bc592": [ "macos/10.10.0", @@ -24417,10 +29054,20 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.2", "macos/10.9.4", "macos/10.9.5" ], + "fea1884ab3aea6d0dbedbe4b9cd9fec8655116300a86a856488fc488bb4b44d2": [ + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" + ], "ff856a2d251dcd88d36656f450126798cfabaade40799c722de4d2b5db36a73a": [ "android/kitkat-cts-release", "android/kitkat-mr1-release", @@ -24435,6 +29082,7 @@ "android/nougat-mr1-cts-release", "android/oreo-cts-release", "android/oreo-mr1-cts-release", + "android/pie-cts-release", "macos/10.10.0", "macos/10.10.3", "macos/10.10.4", @@ -24449,6 +29097,9 @@ "macos/10.13.1", "macos/10.13.2", "macos/10.13.3", + "macos/10.13.4", + "macos/10.13.5", + "macos/10.14.0", "macos/10.9.0", "macos/10.9.2", "macos/10.9.4", @@ -24461,6 +29112,10 @@ "mozilla/2.20", "mozilla/2.22", "mozilla/2.24", + "mozilla/2.26", + "mozilla/2.28", + "mozilla/2.30", + "mozilla/2.32", "mozilla/2.9", "windows/070109202240", "windows/070201011524", @@ -24518,7 +29173,17 @@ "windows/180326181210", "windows/180418163033", "windows/180427182935", - "windows/180518182443" + "windows/180518182443", + "windows/180619172254", + "windows/180718210913", + "windows/180821001257", + "windows/180926205955", + "windows/181012165448", + "windows/181124234732", + "windows/190115181058", + "windows/190222164938", + "windows/190315181653", + "windows/190416222336" ], "ffcef2224e29b0b36ec8314e686822f3ac0f1c5e0c2d5c0eb2484ce7e2540fd0": [ "windows/070109202240", @@ -24565,7 +29230,7 @@ "windows/151119231843" ] }, - "last_spki_id": 493, + "last_spki_id": 514, "spkis": { "004124ad6037fd5f3319e7a23d4d9c811f5598d66c4754155b0aaa9e8f00621f": { "fingerprints": [ @@ -24772,12 +29437,18 @@ "id": 388, "legacy": true }, + "122312c081949106b7049f3febf199c010ada13e3281cd358a41e7bd09c829d7": { + "fingerprints": [ + "34ff2a4409dc1383e9f8966e8adfe5719eba373fd0ad5e2f49f90ee07cf5d4c1" + ], + "id": 514, + "legacy": true + }, "1255cabe8152fa64df942f7a47417e29f96c1ce11bf8c84ecbe2815cc1280810": { "fingerprints": [ "9bea11c976fe014764c1be56a6f914b5a560317abd9988393382e5161aa0493c" ], - "id": 469, - "legacy": true + "id": 469 }, "1462009b2de65d6d4d39be892bd2c186490531ce6590e48fe196070d317b60b0": { "fingerprints": [ @@ -24810,7 +29481,8 @@ "fingerprints": [ "e4c73430d7a5b50925df43370a0d216e9a79b9d6db8373a0c69eb1cc31c7c52a" ], - "id": 40 + "id": 40, + "legacy": true }, "15eed339594b304f8cf847b477371d8d6fec61f4db2b01af589e7c53b35cae4c": { "fingerprints": [ @@ -24974,6 +29646,13 @@ "id": 226, "legacy": true }, + "22a36994f28f2fa3b16ae872a79dbb12a982da5b824d7ae434f96178ac540351": { + "fingerprints": [ + "016e1dcd5f78841bbebbae9ddea08c8d7ec54e698e95bb778ecdd1e10d8bf4f9" + ], + "id": 503, + "legacy": true + }, "232cbe2d9e6994c1ceb7fbee23ab1657defb6b3564726f1e78951cef3a2b095d": { "fingerprints": [ "fc0a0fe27c9dc13c81238a5913a1daf8184168beb7e5a4512a771fd4f453651d" @@ -25008,6 +29687,12 @@ "id": 460, "legacy": true }, + "2541e53ba5b3b07acbe7097ac4a03e040c11cf7a6d4a67cb213d558b50167a06": { + "fingerprints": [ + "5a2fc03f0c83b090bbfa40604b0988446c7636183df9846e17101a447fb8efd6" + ], + "id": 498 + }, "2596904dc4d699ae20c2cef4dce47f285937d77464ac370746f52dea76ba0c28": { "fingerprints": [ "4200f5043ac8590ebb527d209ed1503029fbcbd41ca1b506ec27f15ade7dac69" @@ -25165,6 +29850,13 @@ "id": 272, "legacy": true }, + "2e06cae1fc20b200e6fb748557a4444bec9317dfff2e4151669e0f7944f0a9e0": { + "fingerprints": [ + "97552015f5ddfc3c8788c006944555408894450084f100867086bc1a2bb58dc8" + ], + "id": 513, + "legacy": true + }, "2fc5667a4b9a2678ed6ac6ad25465fcbf6094bfcd9504097c7a8fa47ade5e888": { "fingerprints": [ "ebc5570c29018c4d67b1aa127baf12f703b4611ebc17b7dab5573894179b93fa", @@ -25281,6 +29973,13 @@ "id": 150, "legacy": true }, + "35f53ce1264611e03340fe37e1ec7d4cc986c5613dca70fd04aa44545f2daf28": { + "fingerprints": [ + "fea1884ab3aea6d0dbedbe4b9cd9fec8655116300a86a856488fc488bb4b44d2" + ], + "id": 508, + "legacy": true + }, "36abc32656acfc645c61b71613c4bf21c787f5cabbee48348d58597803d7abc9": { "fingerprints": [ "18ce6cfe7bf14e60b2e347b8dfe868cb31d02ebb3ada271569f50343b46db3a4" @@ -25293,11 +29992,25 @@ ], "id": 94 }, + "36d7c79f3d089a0ff79972d90923dea5ca76b4ccbaf7c2751cb152e9494f52d0": { + "fingerprints": [ + "db3517d1f6732a2d5ab97c533ec70779ee3270a62fb4ac4238372460e6f01e88" + ], + "id": 500, + "legacy": true + }, "36ecc61fc7e5f1923d167e67dfde34608549b34a63c7c6e60ffd5c1840381f5c": { "fingerprints": [ "fcbfe2886206f72b27593c8b070297e12d769ed10ed7930705a8098effc14d17" ], - "id": 74 + "id": 74, + "legacy": true + }, + "376a1a7082a593dccc20d561d119e9ab8d30f11cc321d0a37fa41f0df284e01c": { + "fingerprints": [ + "40f6af0346a99aa1cd1d555a4e9cce62c7f9634603ee406615833dc8c8d00367" + ], + "id": 494 }, "380739620e13335805eada8f9f8b81554d3bd3c0017f3632c2677669cac7a2bf": { "fingerprints": [ @@ -25372,7 +30085,8 @@ "fingerprints": [ "767c955a76412c89af688e90a1c70f556cfd6b6025dbea10416d7eb6831f8c40" ], - "id": 13 + "id": 13, + "legacy": true }, "3c84d996722b3c1872f53ddd7717bb2fa50ebfa07b3f3b4a395335c56712fd69": { "fingerprints": [ @@ -25440,8 +30154,7 @@ "fingerprints": [ "15d5b8774619ea7d54ce1ca6d0b0c403e037a917f131e8a04e1e6b7a71babce5" ], - "id": 485, - "legacy": true + "id": 485 }, "4223894003a881c5df6bab163db235c221a18d54bf759945820e670da82e3f39": { "fingerprints": [ @@ -25574,6 +30287,13 @@ ], "id": 79 }, + "497128fc90656b87290482b223efb72240fe9c421e79938de5f8110cb0be9056": { + "fingerprints": [ + "945bbc825ea554f489d1fd51a73ddf2ea624ac7019a05205225c22a78ccfa8b4" + ], + "id": 512, + "legacy": true + }, "498bc0cd5a49b714071ec76a41661ce2f27fc39fe4168bc7b7799a0ae25f6528": { "fingerprints": [ "9db930a7bced5a599da673d0bb12c4c6c7ab5b3f88f39c24ee20a24716b379df" @@ -25745,8 +30465,7 @@ "fingerprints": [ "c45d7bb08e6d67e62e4235110b564e5f78fd92ef058c840aea4e6455d7585c60" ], - "id": 484, - "legacy": true + "id": 484 }, "56174d3ad971a8944964b189811f3008493a6a90422e3c5804ec838d4f94f622": { "fingerprints": [ @@ -25836,8 +30555,7 @@ "fingerprints": [ "d43af9b35473755c9684fc06d7d8cb70ee5c28e773fb294eb41ee71722924d24" ], - "id": 468, - "legacy": true + "id": 468 }, "5dee74cc343db93f8deaf9e41fbc65b334254b5b23b568fa2814db8b7321ac85": { "fingerprints": [ @@ -25992,8 +30710,7 @@ "fingerprints": [ "2cabeafe37d06ca22aba7391c0033d25982952c453647349763a3ab5ad6ccf69" ], - "id": 487, - "legacy": true + "id": 487 }, "689bf45b3083fdead55f147fd105e3cf218ad58edf3e4b301c0c5eeea6cf210d": { "fingerprints": [ @@ -26002,6 +30719,13 @@ "id": 429, "legacy": true }, + "68aa635451d83962167e88fb08f8678d73aec66fc559462137cff9d1bc3d3871": { + "fingerprints": [ + "dfb3c314740596ad5fb97960ef62ad7c1fcceead16e74054652d1032e6f140ef" + ], + "id": 506, + "legacy": true + }, "68c3692214724d4b55a760f470b4fca8b5e0fe1d729cff22feb4ca88acd39809": { "fingerprints": [ "ae4457b40d9eda96677b0d3c92d57b5177abd7ac1037958356d1e094518be5f2" @@ -26009,6 +30733,13 @@ "id": 231, "legacy": true }, + "68ded9a203ff6e367e12aa49977cd200f7127a800faa6f859f0bafed8286a4fb": { + "fingerprints": [ + "caca93b9d23d2b6fa76e8b8471931e0df3ec6f63af3cdbb936c41954a1872326" + ], + "id": 499, + "legacy": true + }, "6a436b58d9d830e8d5b8a642505ad6b41406adcd6894d9414f7be0a1467badb7": { "fingerprints": [ "05d38c2a70bfc500ccb0cb509159b46b065c6ac9cb42d2e6f16167841434572a" @@ -26167,6 +30898,13 @@ "id": 435, "legacy": true }, + "786ffa578618c3b9a311175e50816f4dda0605c3869f296ebc5943bf09f4e904": { + "fingerprints": [ + "88f438dcf8ffd1fa8f429115ffe5f82ae1e06e0c70c375faad717b34a49e7265" + ], + "id": 510, + "legacy": true + }, "78cf3d3c72daf91cc51b871357a551cf95b837d074c270b08facd463a8d39bb3": { "fingerprints": [ "82d42db3d657f1944e65c192b1dd58db8df8417b89165b045f5c6a70c5f8939e" @@ -26301,6 +31039,13 @@ "id": 166, "legacy": true }, + "828b0eeff24654e8ff5841a29dd5d4e3ed30952ca43425a79283407208d39d16": { + "fingerprints": [ + "55903859c8c0c3ebb8759ece4e2557225ff5758bbd38ebd48276601e1bd58097" + ], + "id": 511, + "legacy": true + }, "82b5f84daf47a59c7ab521e4982aefa40a53406a3aec26039efa6b2e0e7244c1": { "fingerprints": [ "52f0e1c4e58ec629291b60317f074671b85d7ea80d5b07273463534b32b40234" @@ -26368,8 +31113,7 @@ "fingerprints": [ "2a575471e31340bc21581cbd2cf13e158463203ece94bcf9d3cc196bf09a5472" ], - "id": 483, - "legacy": true + "id": 483 }, "87af34d66fb3f2fdf36e09111e9aba2f6f44b207f3863f3d0b54b25023909aa5": { "fingerprints": [ @@ -26457,6 +31201,12 @@ "id": 418, "legacy": true }, + "8d417db2dd8bf5e3084d1e3f196d583849d81bdd4c00c70b9d39369e96b8c782": { + "fingerprints": [ + "86a1ecba089c4a8d3bbe2734c612ba341d813e043cf9e8a862cd5c57a36bbe6b" + ], + "id": 495 + }, "8d767764b3cbda08929d072a22a561f4dcdd1bc57d3cbddc948c47d2b47f9122": { "fingerprints": [ "fd73dad31c644ff1b43bef0ccdda96710b9cd9875eca7e31707af3e96d522bbd" @@ -26481,8 +31231,7 @@ "fingerprints": [ "d48d3d23eedb50a459e55197601c27774b9d7b18c94d5a059511a10250b93168" ], - "id": 463, - "legacy": true + "id": 463 }, "8e8b56f5918a25bd85dce76663fd94cc23690f10ea9586613171c6f8378890d5": { "fingerprints": [ @@ -26504,6 +31253,13 @@ ], "id": 77 }, + "9091e31fe92546a5f5e1b3ed4071f4440b840c1e80dbfcba7a7ec6d5825f0b24": { + "fingerprints": [ + "7707bb2be9f7ce057060b8308c3bc087b56529b3638eaf5b2a8049c8e15ed720" + ], + "id": 509, + "legacy": true + }, "9119e2f413579777954991703eee23a04523a312b5c65f7f9374aa3100ebd8e7": { "fingerprints": [ "ce7dd096c8fde2bf5c438edb574bd6454385334ee8ff106c0f93d5051be6bac3" @@ -26655,7 +31411,8 @@ "fingerprints": [ "d8e0febc1db2e38d00940f37d27d41344d993e734b99d5656d9778d4d8143624" ], - "id": 66 + "id": 66, + "legacy": true }, "979f6f6a8a41c421cc673473d58a6379817be73d2e524698c80ffb66a149d089": { "fingerprints": [ @@ -26682,8 +31439,7 @@ "fingerprints": [ "71cca5391f9e794b04802530b363e121da8a3043bb26662fea4dca7fc951a4bd" ], - "id": 486, - "legacy": true + "id": 486 }, "98b3f10a025041910f197cf17ca0fcdfed75fb2c8c14a843e04d5656c9ebac1a": { "fingerprints": [ @@ -27082,7 +31838,8 @@ "fingerprints": [ "03950fb49a531f3e1991942398dfa9e0ea32d7ba1cdd9bc85db57ed9400b434a" ], - "id": 142 + "id": 142, + "legacy": true }, "b1124142a5a1a5a28819c735340eff8c9e2f8168fee3ba187f253bc1a392d7e2": { "fingerprints": [ @@ -27127,6 +31884,13 @@ "id": 48, "legacy": true }, + "b2f7298b52bf2c3cac4ddfe72de4d682ac58957595982f2b62301af597c699c5": { + "fingerprints": [ + "ecdd47b5acbfa328211e1bff54adeac95e6991e3c1d50e27b527e903208040a1" + ], + "id": 507, + "legacy": true + }, "b3182e289ae34ddf2be643ab79c244301605fa0f1eaae6d10fb929600af84df0": { "fingerprints": [ "f00355eef101c7df4e46cce6417dffce3db82dbb1369c3b439c4e33bee445c42" @@ -27183,6 +31947,12 @@ ], "id": 207 }, + "b7408b4d2be0238ba37004dd34e276c6019bd2f24c9db7d4980f5f6c359a4bcc": { + "fingerprints": [ + "125609aa301da0a249b97a8239cb6a34216f44dcac9f3954b14292f2e8c8608f" + ], + "id": 496 + }, "b89bcbb8acd474c1bea7dad65037f48dcecc9dfaa0612c3c2445956419df32fe": { "fingerprints": [ "04f1bec36951bc1454a904ce32890c5da3cde1356b7900f6e62dfa2041ebad51" @@ -27234,6 +32004,13 @@ ], "id": 71 }, + "be3280c6863c770a33c9040bd97d5540b216d1d91db8b088ceac1197dae1d660": { + "fingerprints": [ + "5ab4fcdb180b5b6af0d262a2375a2c77d25602015d96648756611e2e78c53ad3" + ], + "id": 501, + "legacy": true + }, "be3db7b79bfe579dcf9b07ca4cad75aff16975568e5b45cfcae4d61fb63175a8": { "fingerprints": [ "a45ede3bbbf09c8ae15c72efc07268d693a21c996fd51e67ca079460fd6d8873" @@ -27282,6 +32059,13 @@ ], "id": 124 }, + "c372f6d18ebee5aa23d9e919f3e6be98488ec01607df3162fc192e4b1346afb3": { + "fingerprints": [ + "ac7f7862e685c7a7d9826a58ea32d183d4893fcc8f8fd6d900c9769a987e77f0" + ], + "id": 505, + "legacy": true + }, "c3bc6100f57e320d8659f22584677e56860aab1014e0084a496fff8c880b6ba3": { "fingerprints": [ "8fdd298d1c93b22bfc42aab1c3a15f0d01832ca0a1aef28d5680f06e6c7fd4ef" @@ -27316,6 +32100,13 @@ "id": 213, "legacy": true }, + "c5750bf85f459fb70e2b6cd1898d375e92d7938e47a6e034cce0c12d30372ccd": { + "fingerprints": [ + "3fd4be8baad2f26e1bde06c7584bb720dd1a972d111f5a4999bc44b08fb4960d" + ], + "id": 502, + "legacy": true + }, "c5ea259c629803508649f02177f63c32fa85cc4ad5c35f0d541c45df10a49fd7": { "fingerprints": [ "3cfc3c14d1f684ff17e38c43ca440c00b967ec933e8bfe064ca1d72c90f2adb0" @@ -27441,7 +32232,8 @@ "fingerprints": [ "978cd966f2faa07ba7aa9500d9c02e9d77f2cdada6ad6ba74af4b91c66593c50" ], - "id": 132 + "id": 132, + "legacy": true }, "d1c45377ebdcd618cd1651dc2e02c21d751e5aa9fcd1b3431ff6ecf6a31348fa": { "fingerprints": [ @@ -27597,7 +32389,8 @@ "fingerprints": [ "416b1f9e84e74c1d19b23d8d7191c6ad81246e641601f599132729f507beb3cc" ], - "id": 493 + "id": 493, + "legacy": true }, "e0ef882da48ab0b7efb0d9ba15b2717dd08f043c25ac09b56b8b57fceeb5a35d": { "fingerprints": [ @@ -27682,6 +32475,12 @@ ], "id": 289 }, + "eabc185c4e82d942b1a5978ba3c0181487d6b3b9974e5c49f72f6d0bd9637150": { + "fingerprints": [ + "bc4d809b15189d78db3e1d8cf4f9726a795da1643ca5f1358e1ddb0edc0d7eb3" + ], + "id": 497 + }, "eb4993efa9b089e593418aa893f8e93a7374d810e52fcbe01e7f1d7e92a6d024": { "fingerprints": [ "b0b1730ecbc7ff4505142c49f1295e6eda6bcaed7e2c68c5be91b5a11001f024", @@ -27744,6 +32543,13 @@ ], "id": 171 }, + "f26cdaa1c48e2d369eaf24993a424f8290983af7094a5bde9c7d44341f2e2428": { + "fingerprints": [ + "6aea30bc02ca85afcfec2f65f60881893c926925fd0704bd8ada3f0f6eddb699" + ], + "id": 504, + "legacy": true + }, "f2a4e6b263d0a552adff5d85dc96b5820fd66aa0b18228f48fdb087c8db34133": { "fingerprints": [ "ddbf149733bc2bf8a09d7f012b01a6dea11d7bae26713783ef6407a2495bf189" @@ -27879,8 +32685,7 @@ "fingerprints": [ "8560f91c3624daba9570b5fea0dbe36ff11a8323be9486854fb3f34a5571198d" ], - "id": 490, - "legacy": true + "id": 490 }, "fd872d176617e50c266119d0fdb047b0732da2048b121af7b9860ca3e2f2f2be": { "fingerprints": [ @@ -27909,4 +32714,4 @@ "legacy": true } } -} +} \ No newline at end of file
diff --git a/net/disk_cache/disk_cache.h b/net/disk_cache/disk_cache.h index 0ea3cee3..1abeb68 100644 --- a/net/disk_cache/disk_cache.h +++ b/net/disk_cache/disk_cache.h
@@ -480,6 +480,9 @@ }; // Automatically closes an entry when it goes out of scope. +// Warning: Be careful. Automatically closing may not be the desired behavior +// when writing to an entry. You may wish to doom first (e.g., in case writing +// hasn't yet completed but the browser is shutting down). typedef std::unique_ptr<Entry, EntryDeleter> ScopedEntryPtr; } // namespace disk_cache
diff --git a/net/dns/dns_config_service_win.cc b/net/dns/dns_config_service_win.cc index ebb5044..73bac0c 100644 --- a/net/dns/dns_config_service_win.cc +++ b/net/dns/dns_config_service_win.cc
@@ -18,14 +18,14 @@ #include "base/macros.h" #include "base/memory/free_deleter.h" #include "base/metrics/histogram_macros.h" +#include "base/sequence_checker.h" #include "base/single_thread_task_runner.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/synchronization/lock.h" #include "base/threading/scoped_blocking_call.h" -#include "base/threading/thread_checker.h" -#include "base/threading/thread_task_runner_handle.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "base/time/time.h" #include "base/win/registry.h" #include "base/win/scoped_handle.h" @@ -76,11 +76,11 @@ key_.Open(HKEY_LOCAL_MACHINE, key, KEY_QUERY_VALUE); } - ~RegistryReader() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); } + ~RegistryReader() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); } bool ReadString(const base::char16* name, DnsSystemSettings::RegString* out) const { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); out->set = false; if (!key_.Valid()) { // Assume that if the |key_| is invalid then the key is missing. @@ -96,7 +96,7 @@ bool ReadDword(const base::char16* name, DnsSystemSettings::RegDword* out) const { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); out->set = false; if (!key_.Valid()) { // Assume that if the |key_| is invalid then the key is missing. @@ -113,7 +113,7 @@ private: base::win::RegKey key_; - THREAD_CHECKER(thread_checker_); + SEQUENCE_CHECKER(sequence_checker_); DISALLOW_COPY_AND_ASSIGN(RegistryReader); }; @@ -275,10 +275,10 @@ typedef base::Callback<void(bool succeeded)> CallbackType; RegistryWatcher() {} - ~RegistryWatcher() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); } + ~RegistryWatcher() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); } bool Watch(const base::char16* key, const CallbackType& callback) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!callback.is_null()); DCHECK(callback_.is_null()); callback_ = callback; @@ -290,7 +290,7 @@ } void OnObjectSignaled() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!callback_.is_null()); if (key_.StartWatching(base::Bind(&RegistryWatcher::OnObjectSignaled, base::Unretained(this)))) { @@ -305,7 +305,7 @@ CallbackType callback_; base::win::RegKey key_; - THREAD_CHECKER(thread_checker_); + SEQUENCE_CHECKER(sequence_checker_); DISALLOW_COPY_AND_ASSIGN(RegistryWatcher); }; @@ -564,7 +564,7 @@ return result; } -// Watches registry and HOSTS file for changes. Must live on a thread which +// Watches registry and HOSTS file for changes. Must live on a sequence which // allows IO. class DnsConfigServiceWin::Watcher : public NetworkChangeNotifier::IPAddressObserver { @@ -671,7 +671,7 @@ } else { LOG(WARNING) << "Failed to read DnsConfig."; // Try again in a while in case DnsConfigWatcher missed the signal. - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, base::BindOnce(&ConfigReader::WorkNow, this), base::TimeDelta::FromSeconds(kRetryIntervalSeconds)); } @@ -729,13 +729,16 @@ DISALLOW_COPY_AND_ASSIGN(HostsReader); }; -DnsConfigServiceWin::DnsConfigServiceWin() - : config_reader_(new ConfigReader(this)), - hosts_reader_(new HostsReader(this)) {} +DnsConfigServiceWin::DnsConfigServiceWin() { + // Allow constructing on one sequence and living on another. + DETACH_FROM_SEQUENCE(sequence_checker_); +} DnsConfigServiceWin::~DnsConfigServiceWin() { - config_reader_->Cancel(); - hosts_reader_->Cancel(); + if (config_reader_) + config_reader_->Cancel(); + if (hosts_reader_) + hosts_reader_->Cancel(); } void DnsConfigServiceWin::ReadNow() { @@ -744,6 +747,10 @@ } bool DnsConfigServiceWin::StartWatching() { + if (!config_reader_) + config_reader_ = base::MakeRefCounted<ConfigReader>(this); + if (!hosts_reader_) + hosts_reader_ = base::MakeRefCounted<HostsReader>(this); // TODO(szym): re-start watcher if that makes sense. http://crbug.com/116139 watcher_.reset(new Watcher(this)); UMA_HISTOGRAM_ENUMERATION("AsyncDNS.WatchStatus", DNS_CONFIG_WATCH_STARTED,
diff --git a/net/dns/dns_config_service_win.h b/net/dns/dns_config_service_win.h index a1224068..098d476 100644 --- a/net/dns/dns_config_service_win.h +++ b/net/dns/dns_config_service_win.h
@@ -124,6 +124,11 @@ const DnsSystemSettings& settings, DnsConfig* dns_config); +// Service for reading and watching Windows system DNS settings. This object is +// not thread-safe and methods may perform blocking I/O so methods must be +// called on a sequence that allows blocking (i.e. base::MayBlock). It may be +// constructed on a different sequence than which it's later called on. +// WatchConfig() must be called prior to ReadConfig(). // Use DnsConfigService::CreateSystemService to use it outside of tests. class NET_EXPORT_PRIVATE DnsConfigServiceWin : public DnsConfigService { public:
diff --git a/net/http/http_response_info.cc b/net/http/http_response_info.cc index 64e0e38..1debeba 100644 --- a/net/http/http_response_info.cc +++ b/net/http/http_response_info.cc
@@ -420,6 +420,7 @@ case CONNECTION_INFO_QUIC_46: case CONNECTION_INFO_QUIC_47: case CONNECTION_INFO_QUIC_99: + case CONNECTION_INFO_QUIC_999: return true; case NUM_OF_CONNECTION_INFOS: NOTREACHED(); @@ -490,6 +491,8 @@ return "http/0.9"; case CONNECTION_INFO_HTTP1_0: return "http/1.0"; + case CONNECTION_INFO_QUIC_999: + return "http2+quic/999"; case NUM_OF_CONNECTION_INFOS: break; }
diff --git a/net/http/http_response_info.h b/net/http/http_response_info.h index 4638527..742cf23 100644 --- a/net/http/http_response_info.h +++ b/net/http/http_response_info.h
@@ -62,6 +62,7 @@ CONNECTION_INFO_QUIC_45 = 24, CONNECTION_INFO_QUIC_46 = 25, CONNECTION_INFO_QUIC_47 = 26, + CONNECTION_INFO_QUIC_999 = 27, NUM_OF_CONNECTION_INFOS, };
diff --git a/net/nqe/network_quality_estimator.cc b/net/nqe/network_quality_estimator.cc index 339d1db..4559de2 100644 --- a/net/nqe/network_quality_estimator.cc +++ b/net/nqe/network_quality_estimator.cc
@@ -965,6 +965,53 @@ transport_rtt_observation_count, end_to_end_rtt_observation_count); } +void NetworkQualityEstimator::UpdateHttpRttUsingAllRttValues( + base::TimeDelta* http_rtt, + const base::TimeDelta transport_rtt, + const base::TimeDelta end_to_end_rtt) const { + DCHECK(http_rtt); + + // Use transport RTT to clamp the lower bound on HTTP RTT. + // To improve accuracy, the transport RTT estimate is used only when the + // transport RTT estimate was computed using at least + // |params_->http_rtt_transport_rtt_min_count()| observations. + if (*http_rtt != nqe::internal::InvalidRTT() && + transport_rtt != nqe::internal::InvalidRTT() && + transport_rtt_observation_count_last_ect_computation_ >= + params_->http_rtt_transport_rtt_min_count() && + params_->lower_bound_http_rtt_transport_rtt_multiplier() > 0) { + *http_rtt = + std::max(*http_rtt, + transport_rtt * + params_->lower_bound_http_rtt_transport_rtt_multiplier()); + } + + // Put lower bound on |http_rtt| using |end_to_end_rtt|. + if (*http_rtt != nqe::internal::InvalidRTT() && + params_->use_end_to_end_rtt() && + end_to_end_rtt != nqe::internal::InvalidRTT() && + end_to_end_rtt_observation_count_at_last_ect_computation_ >= + params_->http_rtt_transport_rtt_min_count() && + params_->lower_bound_http_rtt_transport_rtt_multiplier() > 0) { + *http_rtt = + std::max(*http_rtt, + end_to_end_rtt * + params_->lower_bound_http_rtt_transport_rtt_multiplier()); + } + + // Put upper bound on |http_rtt| using |end_to_end_rtt|. + if (*http_rtt != nqe::internal::InvalidRTT() && + params_->use_end_to_end_rtt() && + end_to_end_rtt != nqe::internal::InvalidRTT() && + end_to_end_rtt_observation_count_at_last_ect_computation_ >= + params_->http_rtt_transport_rtt_min_count() && + params_->upper_bound_http_rtt_endtoend_rtt_multiplier() > 0) { + *http_rtt = std::min( + *http_rtt, end_to_end_rtt * + params_->upper_bound_http_rtt_endtoend_rtt_multiplier()); + } +} + EffectiveConnectionType NetworkQualityEstimator::GetRecentEffectiveConnectionTypeUsingMetrics( const base::TimeTicks& start_time, @@ -1015,45 +1062,7 @@ *end_to_end_rtt = nqe::internal::InvalidRTT(); } - // Use transport RTT to clamp the lower bound on HTTP RTT. - // To improve accuracy, the transport RTT estimate is used only when the - // transport RTT estimate was computed using at least - // |params_->http_rtt_transport_rtt_min_count()| observations. - if (*http_rtt != nqe::internal::InvalidRTT() && - *transport_rtt != nqe::internal::InvalidRTT() && - transport_rtt_observation_count_last_ect_computation_ >= - params_->http_rtt_transport_rtt_min_count() && - params_->lower_bound_http_rtt_transport_rtt_multiplier() > 0) { - *http_rtt = - std::max(*http_rtt, - *transport_rtt * - params_->lower_bound_http_rtt_transport_rtt_multiplier()); - } - - // Put lower bound on |http_rtt| using |end_to_end_rtt|. - if (*http_rtt != nqe::internal::InvalidRTT() && - params_->use_end_to_end_rtt() && - *end_to_end_rtt != nqe::internal::InvalidRTT() && - end_to_end_rtt_observation_count_at_last_ect_computation_ >= - params_->http_rtt_transport_rtt_min_count() && - params_->lower_bound_http_rtt_transport_rtt_multiplier() > 0) { - *http_rtt = - std::max(*http_rtt, - *end_to_end_rtt * - params_->lower_bound_http_rtt_transport_rtt_multiplier()); - } - - // Put upper bound on |http_rtt| using |end_to_end_rtt|. - if (*http_rtt != nqe::internal::InvalidRTT() && - params_->use_end_to_end_rtt() && - *end_to_end_rtt != nqe::internal::InvalidRTT() && - end_to_end_rtt_observation_count_at_last_ect_computation_ >= - params_->http_rtt_transport_rtt_min_count() && - params_->upper_bound_http_rtt_endtoend_rtt_multiplier() > 0) { - *http_rtt = std::min( - *http_rtt, *end_to_end_rtt * - params_->upper_bound_http_rtt_endtoend_rtt_multiplier()); - } + UpdateHttpRttUsingAllRttValues(http_rtt, *transport_rtt, *end_to_end_rtt); if (!GetRecentDownlinkThroughputKbps(start_time, downstream_throughput_kbps)) *downstream_throughput_kbps = nqe::internal::INVALID_RTT_THROUGHPUT;
diff --git a/net/nqe/network_quality_estimator.h b/net/nqe/network_quality_estimator.h index 556ad977..bb2ca133 100644 --- a/net/nqe/network_quality_estimator.h +++ b/net/nqe/network_quality_estimator.h
@@ -488,6 +488,12 @@ size_t* transport_rtt_observation_count, size_t* end_to_end_rtt_observation_count) const; + // Updates the provided |http_rtt| based on all provided RTT values. + void UpdateHttpRttUsingAllRttValues( + base::TimeDelta* http_rtt, + const base::TimeDelta transport_rtt, + const base::TimeDelta end_to_end_rtt) const; + // Returns true if the cached network quality estimate was successfully read. bool ReadCachedNetworkQualityEstimate();
diff --git a/net/quic/quic_flags_list.h b/net/quic/quic_flags_list.h index 188edde8..aee8b81 100644 --- a/net/quic/quic_flags_list.h +++ b/net/quic/quic_flags_list.h
@@ -67,7 +67,7 @@ // If true, adjust congestion window when doing bandwidth resumption in BBR. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_fix_bbr_cwnd_in_bandwidth_resumption, - false) + true) // When true, defaults to BBR congestion control instead of Cubic. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_default_to_bbr, false) @@ -154,7 +154,7 @@ // Add 3 connection options to decrease the pacing and CWND gain in QUIC BBR // STARTUP. -QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_bbr_slower_startup3, false) +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_bbr_slower_startup3, true) // When true, the LOSS connection option allows for 1/8 RTT of reording instead // of the current 1/8th threshold which has been found to be too large for fast @@ -230,7 +230,7 @@ // reconnection. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_no_client_conn_ver_negotiation, - true) + false) // If true, public reset packets sent from GFE will include a kEPID tag. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_fix_spurious_ack_alarm, false) @@ -336,7 +336,7 @@ // If true, terminate Google QUIC connections similary as IETF QUIC. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_terminate_gquic_connection_as_ietf, - false) + true) // If true, disable QUIC trial decryption in V44 and above. QUIC_FLAG(bool, @@ -364,3 +364,11 @@ QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_send_version_negotiation_fixed_bit, false) + +// When true, allow variable length QUIC connection IDs for unsupported +// versions. This allows performing version negotiation when the client-chosen +// server connection ID length is not 8. +QUIC_FLAG( + bool, + FLAGS_quic_restart_flag_quic_allow_variable_length_connection_id_for_negotiation, + false)
diff --git a/net/quic/quic_http_stream.cc b/net/quic/quic_http_stream.cc index 3908021..740f229 100644 --- a/net/quic/quic_http_stream.cc +++ b/net/quic/quic_http_stream.cc
@@ -92,6 +92,8 @@ return HttpResponseInfo::CONNECTION_INFO_QUIC_47; case quic::QUIC_VERSION_99: return HttpResponseInfo::CONNECTION_INFO_QUIC_99; + case quic::QUIC_VERSION_RESERVED_FOR_NEGOTIATION: + return HttpResponseInfo::CONNECTION_INFO_QUIC_999; } NOTREACHED(); return HttpResponseInfo::CONNECTION_INFO_QUIC_UNKNOWN_VERSION;
diff --git a/services/OWNERS b/services/OWNERS index a703c63..305da08 100644 --- a/services/OWNERS +++ b/services/OWNERS
@@ -1,4 +1,3 @@ -ben@chromium.org blundell@chromium.org jam@chromium.org rockot@google.com
diff --git a/services/service_manager/OWNERS b/services/service_manager/OWNERS index 48d8bc6..65373b29 100644 --- a/services/service_manager/OWNERS +++ b/services/service_manager/OWNERS
@@ -1,4 +1,3 @@ -ben@chromium.org jam@chromium.org rockot@google.com sky@chromium.org
diff --git a/services/tracing/public/cpp/tracing_features.cc b/services/tracing/public/cpp/tracing_features.cc index 43a19ec..7b446da 100644 --- a/services/tracing/public/cpp/tracing_features.cc +++ b/services/tracing/public/cpp/tracing_features.cc
@@ -19,11 +19,6 @@ const base::Feature kTracingPerfettoBackend{"TracingPerfettoBackend", base::FEATURE_ENABLED_BY_DEFAULT}; -// Causes the BackgroundTracingManager to upload proto messages via UMA, -// rather than JSON via the crash frontend. -const base::Feature kBackgroundTracingProtoOutput{ - "BackgroundTracingProtoOutput", base::FEATURE_DISABLED_BY_DEFAULT}; - // Runs the tracing service as an in-process browser service. const base::Feature kTracingServiceInProcess { "TracingServiceInProcess",
diff --git a/services/tracing/public/cpp/tracing_features.h b/services/tracing/public/cpp/tracing_features.h index 4d282d6e..fca060e 100644 --- a/services/tracing/public/cpp/tracing_features.h +++ b/services/tracing/public/cpp/tracing_features.h
@@ -21,9 +21,6 @@ extern const COMPONENT_EXPORT(TRACING_CPP) base::Feature kTracingServiceInProcess; -extern const COMPONENT_EXPORT(TRACING_CPP) base::Feature - kBackgroundTracingProtoOutput; - } // namespace features namespace tracing {
diff --git a/skia/BUILD.gn b/skia/BUILD.gn index f7bd4d9..fc1fd0b 100644 --- a/skia/BUILD.gn +++ b/skia/BUILD.gn
@@ -832,7 +832,11 @@ "ext/test_fonts_fuchsia.cc", "ext/test_fonts_fuchsia.h", ] - deps += [ "//third_party/fuchsia-sdk/sdk:sys" ] + deps += [ + "//third_party/fuchsia-sdk/sdk:fonts", + "//third_party/fuchsia-sdk/sdk:io", + "//third_party/fuchsia-sdk/sdk:sys", + ] } if (is_linux) { sources += [ "ext/test_fonts_linux.cc" ]
diff --git a/sql/BUILD.gn b/sql/BUILD.gn index 489ebf2..0d39932 100644 --- a/sql/BUILD.gn +++ b/sql/BUILD.gn
@@ -94,6 +94,7 @@ sources = [ "database_unittest.cc", "meta_table_unittest.cc", + "recover_module_unittest.cc", "recovery_unittest.cc", "sql_memory_dump_provider_unittest.cc", "sqlite_features_unittest.cc",
diff --git a/sql/internal_api_token.h b/sql/internal_api_token.h index 2f93e59d..4d6b24a 100644 --- a/sql/internal_api_token.h +++ b/sql/internal_api_token.h
@@ -7,6 +7,10 @@ namespace sql { +namespace test { +struct ColumnInfo; +} // namespace test + // Restricts access to APIs internal to the //sql package. // // This implements Java's package-private via the passkey idiom. @@ -18,6 +22,7 @@ friend class DatabaseTestPeer; friend class Recovery; + friend struct test::ColumnInfo; }; } // namespace sql
diff --git a/sql/recover_module_unittest.cc b/sql/recover_module_unittest.cc new file mode 100644 index 0000000..05a6527 --- /dev/null +++ b/sql/recover_module_unittest.cc
@@ -0,0 +1,1143 @@ +// 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 <random> +#include <string> +#include <tuple> +#include <vector> + +#include "base/strings/stringprintf.h" +#include "build/build_config.h" // For OS_ANDROID used to disable a test. +#include "sql/database.h" +#include "sql/statement.h" +#include "sql/test/database_test_peer.h" +#include "sql/test/scoped_error_expecter.h" +#include "sql/test/sql_test_base.h" +#include "sql/test/test_helpers.h" +#include "sql/transaction.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/sqlite/sqlite3.h" + +namespace sql { +namespace recover { + +class RecoverModuleTest : public sql::SQLTestBase { + public: + void SetUp() override { + SQLTestBase::SetUp(); + ASSERT_TRUE(DatabaseTestPeer::EnableRecoveryExtension(&db())); + } +}; + +TEST_F(RecoverModuleTest, CreateVtable) { + ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)")); + EXPECT_TRUE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_backing " + "USING recover(backing, t TEXT)")); +} +TEST_F(RecoverModuleTest, CreateVtableWithDatabaseSpecifier) { + ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)")); + EXPECT_TRUE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_backing " + "USING recover(main.backing, t TEXT)")); +} +TEST_F(RecoverModuleTest, CreateVtableOnSqliteMaster) { + ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)")); + EXPECT_TRUE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_backing USING recover(" + "sqlite_master, type TEXT, name TEXT, tbl_name TEXT, " + "rootpage INTEGER, sql TEXT)")); +} + +TEST_F(RecoverModuleTest, CreateVtableFailsOnNonTempTable) { + ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)")); + { + sql::test::ScopedErrorExpecter error_expecter; + error_expecter.ExpectError(SQLITE_MISUSE); + EXPECT_FALSE(db().Execute( + "CREATE VIRTUAL TABLE recover_backing USING recover(backing, t TEXT)")); + EXPECT_TRUE(error_expecter.SawExpectedErrors()); + } +} +TEST_F(RecoverModuleTest, CreateVtableFailsOnMissingTable) { + ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)")); + { + sql::test::ScopedErrorExpecter error_expecter; + error_expecter.ExpectError(SQLITE_CORRUPT); + EXPECT_FALSE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_missing " + "USING recover(missing, t TEXT)")); + EXPECT_TRUE(error_expecter.SawExpectedErrors()); + } +} +TEST_F(RecoverModuleTest, DISABLED_CreateVtableFailsOnMissingDatabase) { + // TODO(pwnall): Enable test after removing incorrect DLOG(FATAL) from + // sql::Statement::Execute(). + ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)")); + { + sql::test::ScopedErrorExpecter error_expecter; + error_expecter.ExpectError(SQLITE_ERROR); + EXPECT_FALSE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_backing " + "USING recover(db.backing, t TEXT)")); + EXPECT_TRUE(error_expecter.SawExpectedErrors()); + } +} +TEST_F(RecoverModuleTest, CreateVtableFailsOnTableWithInvalidQualifier) { + ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)")); + { + sql::test::ScopedErrorExpecter error_expecter; + error_expecter.ExpectError(SQLITE_CORRUPT); + EXPECT_FALSE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_backing " + "USING recover(backing invalid, t TEXT)")); + EXPECT_TRUE(error_expecter.SawExpectedErrors()); + } +} +TEST_F(RecoverModuleTest, DISABLED_CreateVtableFailsOnMissingTableName) { + // TODO(pwnall): Enable test after removing incorrect DLOG(FATAL) from + // sql::Statement::Execute(). + ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)")); + { + sql::test::ScopedErrorExpecter error_expecter; + error_expecter.ExpectError(SQLITE_ERROR); + EXPECT_FALSE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_backing " + "USING recover(main., t TEXT)")); + EXPECT_TRUE(error_expecter.SawExpectedErrors()); + } +} +TEST_F(RecoverModuleTest, CreateVtableFailsOnMissingSchemaSpec) { + ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)")); + { + sql::test::ScopedErrorExpecter error_expecter; + error_expecter.ExpectError(SQLITE_MISUSE); + EXPECT_FALSE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_backing " + "USING recover(backing)")); + EXPECT_TRUE(error_expecter.SawExpectedErrors()); + } +} +TEST_F(RecoverModuleTest, CreateVtableFailsOnMissingDbName) { + ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)")); + { + sql::test::ScopedErrorExpecter error_expecter; + error_expecter.ExpectError(SQLITE_MISUSE); + EXPECT_FALSE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_backing " + "USING recover(.backing)")); + EXPECT_TRUE(error_expecter.SawExpectedErrors()); + } +} + +TEST_F(RecoverModuleTest, ColumnTypeMappingAny) { + ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)")); + EXPECT_TRUE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_backing " + "USING recover(backing, t ANY)")); + + sql::test::ColumnInfo column_info = + sql::test::ColumnInfo::Create(&db(), "temp", "recover_backing", "t"); + EXPECT_EQ("(nullptr)", column_info.data_type); + EXPECT_EQ("BINARY", column_info.collation_sequence); + EXPECT_FALSE(column_info.has_non_null_constraint); + EXPECT_FALSE(column_info.is_in_primary_key); + EXPECT_FALSE(column_info.is_auto_incremented); +} +TEST_F(RecoverModuleTest, ColumnTypeMappingAnyNotNull) { + ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)")); + EXPECT_TRUE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_backing " + "USING recover(backing, t ANY NOT NULL)")); + + sql::test::ColumnInfo column_info = + sql::test::ColumnInfo::Create(&db(), "temp", "recover_backing", "t"); + EXPECT_EQ("(nullptr)", column_info.data_type); + EXPECT_EQ("BINARY", column_info.collation_sequence); + EXPECT_TRUE(column_info.has_non_null_constraint); + EXPECT_FALSE(column_info.is_in_primary_key); + EXPECT_FALSE(column_info.is_auto_incremented); +} +TEST_F(RecoverModuleTest, ColumnTypeMappingAnyStrict) { + ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)")); + { + sql::test::ScopedErrorExpecter error_expecter; + error_expecter.ExpectError(SQLITE_MISUSE); + EXPECT_FALSE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_backing " + "USING recover(backing, t ANY STRICT)")); + EXPECT_TRUE(error_expecter.SawExpectedErrors()); + } +} + +TEST_F(RecoverModuleTest, ColumnTypeExtraKeyword) { + ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)")); + { + sql::test::ScopedErrorExpecter error_expecter; + error_expecter.ExpectError(SQLITE_MISUSE); + EXPECT_FALSE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_backing " + "USING recover(backing, t INTEGER SOMETHING)")); + EXPECT_TRUE(error_expecter.SawExpectedErrors()); + } +} +TEST_F(RecoverModuleTest, ColumnTypeNotNullExtraKeyword) { + ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)")); + { + sql::test::ScopedErrorExpecter error_expecter; + error_expecter.ExpectError(SQLITE_MISUSE); + EXPECT_FALSE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_backing " + "USING recover(backing, t INTEGER NOT NULL SOMETHING)")); + EXPECT_TRUE(error_expecter.SawExpectedErrors()); + } +} +TEST_F(RecoverModuleTest, ColumnTypeDoubleTypes) { + ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)")); + { + sql::test::ScopedErrorExpecter error_expecter; + error_expecter.ExpectError(SQLITE_MISUSE); + EXPECT_FALSE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_backing " + "USING recover(backing, t INTEGER FLOAT)")); + EXPECT_TRUE(error_expecter.SawExpectedErrors()); + } +} +TEST_F(RecoverModuleTest, ColumnTypeNotNullDoubleTypes) { + ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)")); + { + sql::test::ScopedErrorExpecter error_expecter; + error_expecter.ExpectError(SQLITE_MISUSE); + EXPECT_FALSE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_backing USING recover(" + "backing, t INTEGER NOT NULL TEXT)")); + EXPECT_TRUE(error_expecter.SawExpectedErrors()); + } +} + +class RecoverModuleColumnTypeMappingTest + : public RecoverModuleTest, + public ::testing::WithParamInterface< + std::tuple<const char*, const char*, bool>> { + public: + void SetUp() override { + RecoverModuleTest::SetUp(); + std::string sql = + base::StringPrintf("CREATE TABLE backing(data %s)", SchemaType()); + ASSERT_TRUE(db().Execute(sql.c_str())); + } + + protected: + void CreateRecoveryTable(const char* suffix) { + std::string sql = base::StringPrintf( + "CREATE VIRTUAL TABLE temp.recover_backing " + "USING recover(backing, data %s%s)", + SchemaType(), suffix); + ASSERT_TRUE(db().Execute(sql.c_str())); + } + + const char* SchemaType() const { return std::get<0>(GetParam()); } + const char* ExpectedType() const { return std::get<1>(GetParam()); } + bool IsAlwaysNonNull() const { return std::get<2>(GetParam()); } +}; +TEST_P(RecoverModuleColumnTypeMappingTest, Unqualified) { + CreateRecoveryTable(""); + sql::test::ColumnInfo column_info = + sql::test::ColumnInfo::Create(&db(), "temp", "recover_backing", "data"); + EXPECT_EQ(ExpectedType(), column_info.data_type); + EXPECT_EQ("BINARY", column_info.collation_sequence); + EXPECT_EQ(IsAlwaysNonNull(), column_info.has_non_null_constraint); + EXPECT_FALSE(column_info.is_in_primary_key); + EXPECT_FALSE(column_info.is_auto_incremented); +} +TEST_P(RecoverModuleColumnTypeMappingTest, NotNull) { + CreateRecoveryTable(" NOT NULL"); + sql::test::ColumnInfo column_info = + sql::test::ColumnInfo::Create(&db(), "temp", "recover_backing", "data"); + EXPECT_EQ(ExpectedType(), column_info.data_type); + EXPECT_EQ("BINARY", column_info.collation_sequence); + EXPECT_TRUE(column_info.has_non_null_constraint); + EXPECT_FALSE(column_info.is_in_primary_key); + EXPECT_FALSE(column_info.is_auto_incremented); +} +TEST_P(RecoverModuleColumnTypeMappingTest, Strict) { + CreateRecoveryTable(" STRICT"); + sql::test::ColumnInfo column_info = + sql::test::ColumnInfo::Create(&db(), "temp", "recover_backing", "data"); + EXPECT_EQ(ExpectedType(), column_info.data_type); + EXPECT_EQ("BINARY", column_info.collation_sequence); + EXPECT_EQ(IsAlwaysNonNull(), column_info.has_non_null_constraint); + EXPECT_FALSE(column_info.is_in_primary_key); + EXPECT_FALSE(column_info.is_auto_incremented); +} +TEST_P(RecoverModuleColumnTypeMappingTest, StrictNotNull) { + CreateRecoveryTable(" STRICT NOT NULL"); + sql::test::ColumnInfo column_info = + sql::test::ColumnInfo::Create(&db(), "temp", "recover_backing", "data"); + EXPECT_EQ(ExpectedType(), column_info.data_type); + EXPECT_EQ("BINARY", column_info.collation_sequence); + EXPECT_TRUE(column_info.has_non_null_constraint); + EXPECT_FALSE(column_info.is_in_primary_key); + EXPECT_FALSE(column_info.is_auto_incremented); +} +INSTANTIATE_TEST_SUITE_P( + , + RecoverModuleColumnTypeMappingTest, + ::testing::Values(std::make_tuple("TEXT", "TEXT", false), + std::make_tuple("INTEGER", "INTEGER", false), + std::make_tuple("FLOAT", "FLOAT", false), + std::make_tuple("BLOB", "BLOB", false), + std::make_tuple("NUMERIC", "NUMERIC", false), + std::make_tuple("ROWID", "INTEGER", true))); + +namespace { + +void GenerateAlteredTable(sql::Database* db) { + ASSERT_TRUE(db->Execute("CREATE TABLE altered(t TEXT)")); + ASSERT_TRUE(db->Execute("INSERT INTO altered VALUES('a')")); + ASSERT_TRUE(db->Execute("INSERT INTO altered VALUES('b')")); + ASSERT_TRUE(db->Execute("INSERT INTO altered VALUES('c')")); + ASSERT_TRUE(db->Execute( + "ALTER TABLE altered ADD COLUMN i INTEGER NOT NULL DEFAULT 10")); + ASSERT_TRUE(db->Execute("INSERT INTO altered VALUES('d', 5)")); +} + +} // namespace + +TEST_F(RecoverModuleTest, ReadFromAlteredTableNullDefaults) { + GenerateAlteredTable(&db()); + ASSERT_TRUE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_altered " + "USING recover(altered, t TEXT, i INTEGER)")); + + sql::Statement statement(db().GetUniqueStatement( + "SELECT t, i FROM recover_altered ORDER BY rowid")); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ("a", statement.ColumnString(0)); + EXPECT_EQ(sql::ColumnType::kNull, statement.GetColumnType(1)); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ("b", statement.ColumnString(0)); + EXPECT_EQ(sql::ColumnType::kNull, statement.GetColumnType(1)); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ("c", statement.ColumnString(0)); + EXPECT_EQ(sql::ColumnType::kNull, statement.GetColumnType(1)); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ("d", statement.ColumnString(0)); + EXPECT_EQ(5, statement.ColumnInt(1)); + + EXPECT_FALSE(statement.Step()); +} + +TEST_F(RecoverModuleTest, ReadFromAlteredTableSkipsNulls) { + GenerateAlteredTable(&db()); + ASSERT_TRUE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_altered " + "USING recover(altered, t TEXT, i INTEGER NOT NULL)")); + + sql::Statement statement(db().GetUniqueStatement( + "SELECT t, i FROM recover_altered ORDER BY rowid")); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ("d", statement.ColumnString(0)); + EXPECT_EQ(5, statement.ColumnInt(1)); + EXPECT_FALSE(statement.Step()); +} + +namespace { + +void GenerateSizedTable(sql::Database* db, + int row_count, + const std::string& prefix) { + ASSERT_TRUE(db->Execute("CREATE TABLE sized(t TEXT, i INTEGER)")); + + sql::Transaction transaction(db); + ASSERT_TRUE(transaction.Begin()); + sql::Statement statement( + db->GetUniqueStatement("INSERT INTO sized VALUES(?, ?)")); + + for (int i = 0; i < row_count; ++i) { + statement.BindString(0, base::StringPrintf("%s%d", prefix.c_str(), i)); + statement.BindInt(1, i); + ASSERT_TRUE(statement.Run()); + statement.Reset(/* clear_bound_vars= */ true); + } + ASSERT_TRUE(transaction.Commit()); +} + +} // namespace + +TEST_F(RecoverModuleTest, LeafNodes) { + GenerateSizedTable(&db(), 10, "Leaf-node-generating line "); + ASSERT_TRUE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_sized " + "USING recover(sized, t TEXT, i INTEGER NOT NULL)")); + + sql::Statement statement( + db().GetUniqueStatement("SELECT t, i FROM recover_sized ORDER BY rowid")); + for (int i = 0; i < 10; ++i) { + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(base::StringPrintf("Leaf-node-generating line %d", i), + statement.ColumnString(0)); + EXPECT_EQ(i, statement.ColumnInt(1)); + } + EXPECT_FALSE(statement.Step()); +} + +TEST_F(RecoverModuleTest, EmptyTable) { + GenerateSizedTable(&db(), 0, ""); + ASSERT_TRUE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_sized " + "USING recover(sized, t TEXT, i INTEGER NOT NULL)")); + sql::Statement statement(db().GetUniqueStatement( + "SELECT rowid, t, i FROM recover_sized ORDER BY rowid")); + EXPECT_FALSE(statement.Step()); +} + +TEST_F(RecoverModuleTest, SingleLevelInteriorNodes) { + GenerateSizedTable(&db(), 100, "Interior-node-generating line "); + ASSERT_TRUE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_sized " + "USING recover(sized, t TEXT, i INTEGER NOT NULL)")); + + sql::Statement statement(db().GetUniqueStatement( + "SELECT rowid, t, i FROM recover_sized ORDER BY rowid")); + for (int i = 0; i < 100; ++i) { + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(i + 1, statement.ColumnInt(0)); + EXPECT_EQ(base::StringPrintf("Interior-node-generating line %d", i), + statement.ColumnString(1)); + EXPECT_EQ(i, statement.ColumnInt(2)); + } + EXPECT_FALSE(statement.Step()); +} + +TEST_F(RecoverModuleTest, MultiLevelInteriorNodes) { + GenerateSizedTable(&db(), 5000, "Interior-node-generating line "); + ASSERT_TRUE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_sized " + "USING recover(sized, t TEXT, i INTEGER NOT NULL)")); + + sql::Statement statement(db().GetUniqueStatement( + "SELECT rowid, t, i FROM recover_sized ORDER BY rowid")); + for (int i = 0; i < 5000; ++i) { + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(i + 1, statement.ColumnInt(0)); + EXPECT_EQ(base::StringPrintf("Interior-node-generating line %d", i), + statement.ColumnString(1)); + EXPECT_EQ(i, statement.ColumnInt(2)); + } + EXPECT_FALSE(statement.Step()); +} + +namespace { + +void GenerateTypesTable(sql::Database* db) { + ASSERT_TRUE(db->Execute("CREATE TABLE types(rowtype TEXT, value)")); + + ASSERT_TRUE(db->Execute("INSERT INTO types VALUES('NULL', NULL)")); + ASSERT_TRUE(db->Execute("INSERT INTO types VALUES('INTEGER', 17)")); + ASSERT_TRUE(db->Execute("INSERT INTO types VALUES('FLOAT', 3.1415927)")); + ASSERT_TRUE(db->Execute("INSERT INTO types VALUES('TEXT', 'This is text')")); + ASSERT_TRUE(db->Execute( + "INSERT INTO types VALUES('BLOB', CAST('This is a blob' AS BLOB))")); +} + +} // namespace + +TEST_F(RecoverModuleTest, Any) { + GenerateTypesTable(&db()); + ASSERT_TRUE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_types " + "USING recover(types, rowtype TEXT, value ANY)")); + sql::Statement statement(db().GetUniqueStatement( + "SELECT rowid, rowtype, value FROM recover_types")); + + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(1, statement.ColumnInt(0)); + EXPECT_EQ("NULL", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kNull, statement.GetColumnType(2)); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(2, statement.ColumnInt(0)); + EXPECT_EQ("INTEGER", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kInteger, statement.GetColumnType(2)); + EXPECT_EQ(17, statement.ColumnInt(2)); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(3, statement.ColumnInt(0)); + EXPECT_EQ("FLOAT", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kFloat, statement.GetColumnType(2)); + EXPECT_DOUBLE_EQ(3.1415927, statement.ColumnDouble(2)); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(4, statement.ColumnInt(0)); + EXPECT_EQ("TEXT", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kText, statement.GetColumnType(2)); + EXPECT_EQ("This is text", statement.ColumnString(2)); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(5, statement.ColumnInt(0)); + EXPECT_EQ("BLOB", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kBlob, statement.GetColumnType(2)); + std::string blob_text; + ASSERT_TRUE(statement.ColumnBlobAsString(2, &blob_text)); + EXPECT_EQ("This is a blob", blob_text); + + EXPECT_FALSE(statement.Step()); +} + +TEST_F(RecoverModuleTest, Integers) { + GenerateTypesTable(&db()); + ASSERT_TRUE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_types " + "USING recover(types, rowtype TEXT, value INTEGER)")); + sql::Statement statement(db().GetUniqueStatement( + "SELECT rowid, rowtype, value FROM recover_types")); + + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(1, statement.ColumnInt(0)); + EXPECT_EQ("NULL", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kNull, statement.GetColumnType(2)); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(2, statement.ColumnInt(0)); + EXPECT_EQ("INTEGER", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kInteger, statement.GetColumnType(2)); + EXPECT_EQ(17, statement.ColumnInt(2)); + + EXPECT_FALSE(statement.Step()); +} + +TEST_F(RecoverModuleTest, NonNullIntegers) { + GenerateTypesTable(&db()); + ASSERT_TRUE(db().Execute( + "CREATE VIRTUAL TABLE temp.recover_types " + "USING recover(types, rowtype TEXT, value INTEGER NOT NULL)")); + sql::Statement statement(db().GetUniqueStatement( + "SELECT rowid, rowtype, value FROM recover_types")); + + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(2, statement.ColumnInt(0)); + EXPECT_EQ("INTEGER", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kInteger, statement.GetColumnType(2)); + EXPECT_EQ(17, statement.ColumnInt(2)); + + EXPECT_FALSE(statement.Step()); +} + +TEST_F(RecoverModuleTest, Floats) { + GenerateTypesTable(&db()); + ASSERT_TRUE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_types " + "USING recover(types, rowtype TEXT, value FLOAT)")); + sql::Statement statement(db().GetUniqueStatement( + "SELECT rowid, rowtype, value FROM recover_types")); + + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(1, statement.ColumnInt(0)); + EXPECT_EQ("NULL", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kNull, statement.GetColumnType(2)); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(2, statement.ColumnInt(0)); + EXPECT_EQ("INTEGER", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kFloat, statement.GetColumnType(2)); + EXPECT_EQ(17, statement.ColumnInt(2)); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(3, statement.ColumnInt(0)); + EXPECT_EQ("FLOAT", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kFloat, statement.GetColumnType(2)); + EXPECT_DOUBLE_EQ(3.1415927, statement.ColumnDouble(2)); + + EXPECT_FALSE(statement.Step()); +} + +TEST_F(RecoverModuleTest, NonNullFloats) { + GenerateTypesTable(&db()); + ASSERT_TRUE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_types " + "USING recover(types, rowtype TEXT, value FLOAT NOT NULL)")); + sql::Statement statement(db().GetUniqueStatement( + "SELECT rowid, rowtype, value FROM recover_types")); + + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(2, statement.ColumnInt(0)); + EXPECT_EQ("INTEGER", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kFloat, statement.GetColumnType(2)); + EXPECT_EQ(17, statement.ColumnInt(2)); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(3, statement.ColumnInt(0)); + EXPECT_EQ("FLOAT", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kFloat, statement.GetColumnType(2)); + EXPECT_DOUBLE_EQ(3.1415927, statement.ColumnDouble(2)); + + EXPECT_FALSE(statement.Step()); +} + +TEST_F(RecoverModuleTest, FloatsStrict) { + GenerateTypesTable(&db()); + ASSERT_TRUE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_types " + "USING recover(types, rowtype TEXT, value FLOAT STRICT)")); + sql::Statement statement(db().GetUniqueStatement( + "SELECT rowid, rowtype, value FROM recover_types")); + + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(1, statement.ColumnInt(0)); + EXPECT_EQ("NULL", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kNull, statement.GetColumnType(2)); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(3, statement.ColumnInt(0)); + EXPECT_EQ("FLOAT", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kFloat, statement.GetColumnType(2)); + EXPECT_DOUBLE_EQ(3.1415927, statement.ColumnDouble(2)); + + EXPECT_FALSE(statement.Step()); +} + +TEST_F(RecoverModuleTest, NonNullFloatsStrict) { + GenerateTypesTable(&db()); + ASSERT_TRUE(db().Execute( + "CREATE VIRTUAL TABLE temp.recover_types " + "USING recover(types, rowtype TEXT, value FLOAT STRICT NOT NULL)")); + sql::Statement statement(db().GetUniqueStatement( + "SELECT rowid, rowtype, value FROM recover_types")); + + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(3, statement.ColumnInt(0)); + EXPECT_EQ("FLOAT", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kFloat, statement.GetColumnType(2)); + EXPECT_DOUBLE_EQ(3.1415927, statement.ColumnDouble(2)); + + EXPECT_FALSE(statement.Step()); +} + +TEST_F(RecoverModuleTest, Texts) { + GenerateTypesTable(&db()); + ASSERT_TRUE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_types " + "USING recover(types, rowtype TEXT, value TEXT)")); + sql::Statement statement(db().GetUniqueStatement( + "SELECT rowid, rowtype, value FROM recover_types")); + + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(1, statement.ColumnInt(0)); + EXPECT_EQ("NULL", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kNull, statement.GetColumnType(2)); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(4, statement.ColumnInt(0)); + EXPECT_EQ("TEXT", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kText, statement.GetColumnType(2)); + EXPECT_EQ("This is text", statement.ColumnString(2)); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(5, statement.ColumnInt(0)); + EXPECT_EQ("BLOB", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kBlob, statement.GetColumnType(2)); + std::string blob_text; + ASSERT_TRUE(statement.ColumnBlobAsString(2, &blob_text)); + EXPECT_EQ("This is a blob", blob_text); + + EXPECT_FALSE(statement.Step()); +} + +TEST_F(RecoverModuleTest, NonNullTexts) { + GenerateTypesTable(&db()); + ASSERT_TRUE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_types " + "USING recover(types, rowtype TEXT, value TEXT NOT NULL)")); + sql::Statement statement(db().GetUniqueStatement( + "SELECT rowid, rowtype, value FROM recover_types")); + + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(4, statement.ColumnInt(0)); + EXPECT_EQ("TEXT", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kText, statement.GetColumnType(2)); + EXPECT_EQ("This is text", statement.ColumnString(2)); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(5, statement.ColumnInt(0)); + EXPECT_EQ("BLOB", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kBlob, statement.GetColumnType(2)); + std::string blob_text; + ASSERT_TRUE(statement.ColumnBlobAsString(2, &blob_text)); + EXPECT_EQ("This is a blob", blob_text); + + EXPECT_FALSE(statement.Step()); +} + +TEST_F(RecoverModuleTest, TextsStrict) { + GenerateTypesTable(&db()); + ASSERT_TRUE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_types " + "USING recover(types, rowtype TEXT, value TEXT STRICT)")); + sql::Statement statement(db().GetUniqueStatement( + "SELECT rowid, rowtype, value FROM recover_types")); + + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(1, statement.ColumnInt(0)); + EXPECT_EQ("NULL", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kNull, statement.GetColumnType(2)); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(4, statement.ColumnInt(0)); + EXPECT_EQ("TEXT", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kText, statement.GetColumnType(2)); + EXPECT_EQ("This is text", statement.ColumnString(2)); + + EXPECT_FALSE(statement.Step()); +} + +TEST_F(RecoverModuleTest, NonNullTextsStrict) { + GenerateTypesTable(&db()); + ASSERT_TRUE(db().Execute( + "CREATE VIRTUAL TABLE temp.recover_types " + "USING recover(types, rowtype TEXT, value TEXT STRICT NOT NULL)")); + sql::Statement statement(db().GetUniqueStatement( + "SELECT rowid, rowtype, value FROM recover_types")); + + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(4, statement.ColumnInt(0)); + EXPECT_EQ("TEXT", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kText, statement.GetColumnType(2)); + EXPECT_EQ("This is text", statement.ColumnString(2)); + + EXPECT_FALSE(statement.Step()); +} + +TEST_F(RecoverModuleTest, Blobs) { + GenerateTypesTable(&db()); + ASSERT_TRUE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_types " + "USING recover(types, rowtype TEXT, value BLOB)")); + sql::Statement statement(db().GetUniqueStatement( + "SELECT rowid, rowtype, value FROM recover_types")); + + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(1, statement.ColumnInt(0)); + EXPECT_EQ("NULL", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kNull, statement.GetColumnType(2)); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(5, statement.ColumnInt(0)); + EXPECT_EQ("BLOB", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kBlob, statement.GetColumnType(2)); + std::string blob_text; + ASSERT_TRUE(statement.ColumnBlobAsString(2, &blob_text)); + EXPECT_EQ("This is a blob", blob_text); + + EXPECT_FALSE(statement.Step()); +} + +TEST_F(RecoverModuleTest, NonNullBlobs) { + GenerateTypesTable(&db()); + ASSERT_TRUE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_types " + "USING recover(types, rowtype TEXT, value BLOB NOT NULL)")); + sql::Statement statement(db().GetUniqueStatement( + "SELECT rowid, rowtype, value FROM recover_types")); + + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(5, statement.ColumnInt(0)); + EXPECT_EQ("BLOB", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kBlob, statement.GetColumnType(2)); + std::string blob_text; + ASSERT_TRUE(statement.ColumnBlobAsString(2, &blob_text)); + EXPECT_EQ("This is a blob", blob_text); + + EXPECT_FALSE(statement.Step()); +} + +TEST_F(RecoverModuleTest, AnyNonNull) { + GenerateTypesTable(&db()); + ASSERT_TRUE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_types " + "USING recover(types, rowtype TEXT, value ANY NOT NULL)")); + sql::Statement statement(db().GetUniqueStatement( + "SELECT rowid, rowtype, value FROM recover_types")); + + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(2, statement.ColumnInt(0)); + EXPECT_EQ("INTEGER", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kInteger, statement.GetColumnType(2)); + EXPECT_EQ(17, statement.ColumnInt(2)); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(3, statement.ColumnInt(0)); + EXPECT_EQ("FLOAT", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kFloat, statement.GetColumnType(2)); + EXPECT_DOUBLE_EQ(3.1415927, statement.ColumnDouble(2)); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(4, statement.ColumnInt(0)); + EXPECT_EQ("TEXT", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kText, statement.GetColumnType(2)); + EXPECT_EQ("This is text", statement.ColumnString(2)); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(5, statement.ColumnInt(0)); + EXPECT_EQ("BLOB", statement.ColumnString(1)); + EXPECT_EQ(sql::ColumnType::kBlob, statement.GetColumnType(2)); + std::string blob_text; + ASSERT_TRUE(statement.ColumnBlobAsString(2, &blob_text)); + EXPECT_EQ("This is a blob", blob_text); + + EXPECT_FALSE(statement.Step()); +} + +TEST_F(RecoverModuleTest, RowidAlias) { + GenerateTypesTable(&db()); + + // The id column is an alias for rowid, and its values get serialized as NULL. + ASSERT_TRUE(db().Execute( + "CREATE TABLE types2(id INTEGER PRIMARY KEY, rowtype TEXT, value)")); + ASSERT_TRUE( + db().Execute("INSERT INTO types2(id, rowtype, value) " + "SELECT rowid, rowtype, value FROM types WHERE true")); + ASSERT_TRUE(db().Execute( + "CREATE VIRTUAL TABLE temp.recover_types2 " + "USING recover(types2, id ROWID NOT NULL, rowtype TEXT, value ANY)")); + + sql::Statement statement( + db().GetUniqueStatement("SELECT id, rowid, rowtype, value FROM types2")); + + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(1, statement.ColumnInt(0)); + EXPECT_EQ(1, statement.ColumnInt(1)); + EXPECT_EQ("NULL", statement.ColumnString(2)); + EXPECT_EQ(sql::ColumnType::kNull, statement.GetColumnType(3)); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(2, statement.ColumnInt(0)); + EXPECT_EQ(2, statement.ColumnInt(1)); + EXPECT_EQ("INTEGER", statement.ColumnString(2)); + EXPECT_EQ(17, statement.ColumnInt(3)); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(3, statement.ColumnInt(0)); + EXPECT_EQ(3, statement.ColumnInt(1)); + EXPECT_EQ("FLOAT", statement.ColumnString(2)); + EXPECT_DOUBLE_EQ(3.1415927, statement.ColumnDouble(3)); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(4, statement.ColumnInt(0)); + EXPECT_EQ(4, statement.ColumnInt(1)); + EXPECT_EQ("TEXT", statement.ColumnString(2)); + EXPECT_EQ("This is text", statement.ColumnString(3)); + ASSERT_TRUE(statement.Step()); + EXPECT_EQ(5, statement.ColumnInt(0)); + EXPECT_EQ(5, statement.ColumnInt(1)); + EXPECT_EQ("BLOB", statement.ColumnString(2)); + std::string blob_text; + ASSERT_TRUE(statement.ColumnBlobAsString(3, &blob_text)); + EXPECT_EQ("This is a blob", blob_text); + + EXPECT_FALSE(statement.Step()); +} + +#if OS_ANDROID +// The SQLite patch fails this test on Android. The rewritten recovery code +// passes this test. So, the test will be unconditionally enabled when +// https://crrev.com/c/1546942 lands. +#define MAYBE_IntegerEncodings DISABLED_IntegerEncodings +#else +#define MAYBE_IntegerEncodings IntegerEncodings +#endif +TEST_F(RecoverModuleTest, MAYBE_IntegerEncodings) { + ASSERT_TRUE(db().Execute("CREATE TABLE integers(value)")); + + const std::vector<int64_t> values = { + // Encoded directly in type info. + 0, + 1, + // 8-bit signed. + 2, + -2, + 127, + -128, + // 16-bit signed. + 12345, + -12345, + 32767, + -32768, + // 24-bit signed. + 1234567, + -1234567, + 8388607, + -8388608, + // 32-bit signed. + 1234567890, + -1234567890, + 2147483647, + -2147483647, + // 48-bit signed. + 123456789012345, + -123456789012345, + 140737488355327, + -140737488355327, + // 64-bit signed. + 1234567890123456789, + -1234567890123456789, + 9223372036854775807, + -9223372036854775807, + }; + sql::Statement insert( + db().GetUniqueStatement("INSERT INTO integers VALUES(?)")); + for (int64_t value : values) { + insert.BindInt64(0, value); + ASSERT_TRUE(insert.Run()); + insert.Reset(/* clear_bound_vars= */ true); + } + + ASSERT_TRUE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_integers " + "USING recover(integers, value INTEGER)")); + sql::Statement select( + db().GetUniqueStatement("SELECT rowid, value FROM recover_integers")); + for (size_t i = 0; i < values.size(); ++i) { + ASSERT_TRUE(select.Step()) << "Was attemping to read " << values[i]; + EXPECT_EQ(static_cast<int>(i + 1), select.ColumnInt(0)); + EXPECT_EQ(values[i], select.ColumnInt64(1)); + } + EXPECT_FALSE(select.Step()); +} + +TEST_F(RecoverModuleTest, VarintEncodings) { + const std::vector<int64_t> values = { + // 1-byte varints. + 0x00, + 0x01, + 0x02, + 0x7e, + 0x7f, + // 2-byte varints + 0x80, + 0x81, + 0xff, + 0x0100, + 0x0101, + 0x1234, + 0x1ffe, + 0x1fff, + 0x3ffe, + 0x3fff, + // 3-byte varints + 0x4000, + 0x4001, + 0x0ffffe, + 0x0fffff, + 0x123456, + 0x1fedcb, + 0x1ffffe, + 0x1fffff, + // 4-byte varints + 0x200000, + 0x200001, + 0x123456, + 0xfedcba, + 0xfffffe, + 0xffffff, + 0x01234567, + 0x0fedcba9, + 0x0ffffffe, + 0x0fffffff, + // 5-byte varints + 0x10000000, + 0x10000001, + 0x12345678, + 0xfedcba98, + 0x0123456789, + 0x07fffffffe, + 0x07ffffffff, + // 6-byte varints + 0x0800000000, + 0x0800000001, + 0x123456789a, + 0xfedcba9876, + 0x0123456789ab, + 0x03fffffffffe, + 0x03ffffffffff, + // 7-byte varints + 0x040000000000, + 0x40000000001, + 0xfedcba987654, + 0x0123456789abcd, + 0x01fffffffffffe, + 0x01ffffffffffff, + // 8-byte varints + 0x02000000000000, + 0x2000000000001, + 0x0fedcba9876543, + 0x123456789abcde, + 0xfedcba98765432, + 0xfffffffffffffe, + 0xffffffffffffff, + // 9-byte positive varints + 0x0100000000000000, + 0x0100000000000001, + 0x123456789abcdef0, + 0xfedcba9876543210, + 0x7ffffffffffffffe, + 0x7fffffffffffffff, + // 9-byte negative varints + -0x01, + -0x02, + -0x7e, + -0x7f, + -0x80, + -0x81, + -0x123456789abcdef0, + -0xfedcba9876543210, + -0x7fffffffffffffff, + -0x8000000000000000, + }; + + ASSERT_TRUE(db().Execute("CREATE TABLE varints(value INTEGER PRIMARY KEY)")); + ASSERT_TRUE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_varints " + "USING recover(varints, value ROWID)")); + + for (int64_t value : values) { + sql::Statement insert( + db().GetUniqueStatement("INSERT INTO varints VALUES(?)")); + insert.BindInt64(0, value); + ASSERT_TRUE(insert.Run()); + + sql::Statement select( + db().GetUniqueStatement("SELECT rowid, value FROM recover_varints")); + ASSERT_TRUE(select.Step()) << "Was attemping to read " << value; + EXPECT_EQ(value, select.ColumnInt64(0)); + EXPECT_EQ(value, select.ColumnInt64(1)); + EXPECT_FALSE(select.Step()); + + ASSERT_TRUE(db().Execute("DELETE FROM varints")); + } +} + +TEST_F(RecoverModuleTest, TextEncodings) { + ASSERT_TRUE(db().Execute("CREATE TABLE encodings(t TEXT)")); + + const std::vector<std::string> values = { + u8"Mjollnir", u8"Mjölnir", u8"Mjǫlnir", + u8"Mjölner", u8"Mjølner", u8"ハンマー", + }; + + sql::Statement insert( + db().GetUniqueStatement("INSERT INTO encodings VALUES(?)")); + for (const std::string& value : values) { + insert.BindString(0, value); + ASSERT_TRUE(insert.Run()); + insert.Reset(/* clear_bound_vars= */ true); + } + + ASSERT_TRUE( + db().Execute("CREATE VIRTUAL TABLE temp.recover_encodings " + "USING recover(encodings, t TEXT)")); + sql::Statement select( + db().GetUniqueStatement("SELECT rowid, t FROM recover_encodings")); + for (size_t i = 0; i < values.size(); ++i) { + ASSERT_TRUE(select.Step()); + EXPECT_EQ(static_cast<int>(i + 1), select.ColumnInt(0)); + EXPECT_EQ(values[i], select.ColumnString(1)); + } + EXPECT_FALSE(select.Step()); +} + +namespace { + +std::string RandomString(int size) { + std::mt19937 rng; + std::uniform_int_distribution<int> random_char(32, 127); + std::string large_value; + large_value.reserve(size); + for (int i = 0; i < size; ++i) + large_value.push_back(random_char(rng)); + return large_value; +} + +void CheckLargeValueRecovery(sql::Database* db, int value_size) { + const std::string large_value = RandomString(value_size); + + ASSERT_TRUE(db->Execute("CREATE TABLE overflow(t TEXT)")); + sql::Statement insert( + db->GetUniqueStatement("INSERT INTO overflow VALUES(?)")); + insert.BindString(0, large_value); + ASSERT_TRUE(insert.Run()); + + ASSERT_TRUE(db->Execute("VACUUM")); + + ASSERT_TRUE( + db->Execute("CREATE VIRTUAL TABLE temp.recover_overflow " + "USING recover(overflow, t TEXT)")); + sql::Statement select( + db->GetUniqueStatement("SELECT rowid, t FROM recover_overflow")); + ASSERT_TRUE(select.Step()); + EXPECT_EQ(1, select.ColumnInt(0)); + EXPECT_EQ(large_value, select.ColumnString(1)); +} + +bool HasEnabledAutoVacuum(sql::Database* db) { + sql::Statement pragma(db->GetUniqueStatement("PRAGMA auto_vacuum")); + EXPECT_TRUE(pragma.Step()); + return pragma.ColumnInt(0) != 0; +} + +// The overhead in the table page is: +// * 35 bytes - the cell size cutoff that causes a cell's payload to overflow +// * 1 byte - record header size +// * 2-3 bytes - type ID for the text column +// - texts of 58-8185 bytes use 2 bytes +// - texts of 8186-1048569 bytes use 3 bytes +// +// The overhead below assumes a 2-byte string type ID. +constexpr int kRecordOverhead = 38; + +// Each overflow page uses 4 bytes to store the pointer to the next page. +constexpr int kOverflowOverhead = 4; + +} // namespace + +TEST_F(RecoverModuleTest, ValueWithoutOverflow) { + CheckLargeValueRecovery(&db(), db().page_size() - kRecordOverhead); + int auto_vacuum_pages = HasEnabledAutoVacuum(&db()) ? 1 : 0; + ASSERT_EQ(2 + auto_vacuum_pages, sql::test::GetPageCount(&db())) + << "Database should have a root page and a leaf page"; +} + +TEST_F(RecoverModuleTest, ValueWithOneByteOverflow) { + CheckLargeValueRecovery(&db(), db().page_size() - kRecordOverhead + 1); + int auto_vacuum_pages = HasEnabledAutoVacuum(&db()) ? 1 : 0; + ASSERT_EQ(3 + auto_vacuum_pages, sql::test::GetPageCount(&db())) + << "Database should have a root page, a leaf page, and 1 overflow page"; +} + +TEST_F(RecoverModuleTest, ValueWithOneOverflowPage) { + CheckLargeValueRecovery( + &db(), db().page_size() - kRecordOverhead + db().page_size() / 2); + int auto_vacuum_pages = HasEnabledAutoVacuum(&db()) ? 1 : 0; + ASSERT_EQ(3 + auto_vacuum_pages, sql::test::GetPageCount(&db())) + << "Database should have a root page, a leaf page, and 1 overflow page"; +} + +TEST_F(RecoverModuleTest, ValueWithOneFullOverflowPage) { + CheckLargeValueRecovery(&db(), db().page_size() - kRecordOverhead + + db().page_size() - kOverflowOverhead); + int auto_vacuum_pages = HasEnabledAutoVacuum(&db()) ? 1 : 0; + ASSERT_EQ(3 + auto_vacuum_pages, sql::test::GetPageCount(&db())) + << "Database should have a root page, a leaf page, and 1 overflow page"; +} + +TEST_F(RecoverModuleTest, ValueWithOneByteSecondOverflowPage) { + CheckLargeValueRecovery(&db(), db().page_size() - kRecordOverhead + + db().page_size() - kOverflowOverhead + 1); + int auto_vacuum_pages = HasEnabledAutoVacuum(&db()) ? 1 : 0; + ASSERT_EQ(4 + auto_vacuum_pages, sql::test::GetPageCount(&db())) + << "Database should have a root page, a leaf page, and 2 overflow pages"; +} + +TEST_F(RecoverModuleTest, ValueWithTwoOverflowPages) { + CheckLargeValueRecovery(&db(), db().page_size() - kRecordOverhead + + db().page_size() - kOverflowOverhead + + db().page_size() / 2); + int auto_vacuum_pages = HasEnabledAutoVacuum(&db()) ? 1 : 0; + ASSERT_EQ(4 + auto_vacuum_pages, sql::test::GetPageCount(&db())) + << "Database should have a root page, a leaf page, and 2 overflow pages"; +} + +TEST_F(RecoverModuleTest, ValueWithTwoFullOverflowPages) { + // This value is large enough that the varint encoding of its type ID takes up + // 3 bytes, instead of 2. + CheckLargeValueRecovery(&db(), + db().page_size() - kRecordOverhead + + (db().page_size() - kOverflowOverhead) * 2 - 1); + int auto_vacuum_pages = HasEnabledAutoVacuum(&db()) ? 1 : 0; + ASSERT_EQ(4 + auto_vacuum_pages, sql::test::GetPageCount(&db())) + << "Database should have a root page, a leaf page, and 2 overflow pages"; +} + +} // namespace recover +} // namespace sql
diff --git a/sql/recovery.cc b/sql/recovery.cc index 0d5000e..dfd80db 100644 --- a/sql/recovery.cc +++ b/sql/recovery.cc
@@ -239,7 +239,7 @@ } // Enable the recover virtual table for this connection. - int rc = chrome_sqlite3_recoverVtableInit(recover_db_.db(InternalApiToken())); + int rc = EnableRecoveryExtension(&recover_db_, InternalApiToken()); if (rc != SQLITE_OK) { RecordRecoveryEvent(RECOVERY_FAILED_VIRTUAL_TABLE_INIT); LOG(ERROR) << "Failed to initialize recover module: " @@ -798,4 +798,9 @@ } } +// static +int Recovery::EnableRecoveryExtension(Database* db, InternalApiToken) { + return chrome_sqlite3_recoverVtableInit(db->db(InternalApiToken())); +} + } // namespace sql
diff --git a/sql/recovery.h b/sql/recovery.h index aaaf780..bb44a78 100644 --- a/sql/recovery.h +++ b/sql/recovery.h
@@ -12,6 +12,7 @@ #include "base/component_export.h" #include "base/macros.h" #include "sql/database.h" +#include "sql/internal_api_token.h" namespace base { class FilePath; @@ -175,6 +176,11 @@ // the database. static bool ShouldRecover(int extended_error); + // Enables the "recover" SQLite extension for a database connection. + // + // Returns a SQLite error code. + static int EnableRecoveryExtension(Database* db, InternalApiToken); + private: explicit Recovery(Database* database);
diff --git a/sql/test/database_test_peer.cc b/sql/test/database_test_peer.cc index 957c1cd5..be0a8af 100644 --- a/sql/test/database_test_peer.cc +++ b/sql/test/database_test_peer.cc
@@ -7,6 +7,8 @@ #include "base/files/file_path.h" #include "sql/database.h" #include "sql/internal_api_token.h" +#include "sql/recovery.h" +#include "third_party/sqlite/sqlite3.h" namespace sql { @@ -24,4 +26,9 @@ return db->DetachDatabase(attachment_point, InternalApiToken()); } +// static +bool DatabaseTestPeer::EnableRecoveryExtension(Database* db) { + return Recovery::EnableRecoveryExtension(db, InternalApiToken()) == SQLITE_OK; +} + } // namespace sql
diff --git a/sql/test/database_test_peer.h b/sql/test/database_test_peer.h index 322727d..0a01b5a0 100644 --- a/sql/test/database_test_peer.h +++ b/sql/test/database_test_peer.h
@@ -19,6 +19,8 @@ const base::FilePath& other_db_path, const char* attachment_point); static bool DetachDatabase(Database* db, const char* attachment_point); + + static bool EnableRecoveryExtension(Database* db); }; } // namespace sql
diff --git a/sql/test/test_helpers.cc b/sql/test/test_helpers.cc index 244fab6c..0a149a2 100644 --- a/sql/test/test_helpers.cc +++ b/sql/test/test_helpers.cc
@@ -12,10 +12,12 @@ #include "base/files/file_util.h" #include "base/files/scoped_file.h" +#include "base/logging.h" #include "base/threading/thread_restrictions.h" #include "sql/database.h" #include "sql/statement.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/sqlite/sqlite3.h" namespace { @@ -143,7 +145,7 @@ if (!db.Open(db_path)) return false; - int page_size = 0; + int page_size = db.page_size(); if (!GetPageSize(&db, &page_size)) return false; @@ -297,5 +299,37 @@ return ret; } +int GetPageCount(sql::Database* db) { + sql::Statement statement(db->GetUniqueStatement("PRAGMA page_count")); + CHECK(statement.Step()); + return statement.ColumnInt(0); +} + +// static +ColumnInfo ColumnInfo::Create(sql::Database* db, + const std::string& db_name, + const std::string& table_name, + const std::string& column_name) { + sqlite3* const sqlite3_db = db->db(InternalApiToken()); + + const char* data_type; + const char* collation_sequence; + int not_null; + int primary_key; + int auto_increment; + int status = sqlite3_table_column_metadata( + sqlite3_db, db_name.c_str(), table_name.c_str(), column_name.c_str(), + &data_type, &collation_sequence, ¬_null, &primary_key, + &auto_increment); + CHECK_EQ(status, SQLITE_OK) << "SQLite error: " << sqlite3_errmsg(sqlite3_db); + + // This happens when virtual tables report no type information. + if (data_type == nullptr) + data_type = "(nullptr)"; + + return {std::string(data_type), std::string(collation_sequence), + not_null != 0, primary_key != 0, auto_increment != 0}; +} + } // namespace test } // namespace sql
diff --git a/sql/test/test_helpers.h b/sql/test/test_helpers.h index 07f901c11..39059e4 100644 --- a/sql/test/test_helpers.h +++ b/sql/test/test_helpers.h
@@ -119,6 +119,39 @@ const char* column_sep, const char* row_sep); +// Returns the database size, in pages. Crashes on SQLite errors. +int GetPageCount(sql::Database* db); + +// Column information returned by GetColumnInfo. +// +// C++ wrapper around the out-params of sqlite3_table_column_metadata(). +struct ColumnInfo { + // Retrieves schema information for a column in a table. + // + // Crashes on SQLite errors. + // + // |db_name| should be "main" for the connection's main (opened) database, and + // "temp" for the connection's temporary (in-memory) database. + // + // This is a static method rather than a function so it can be listed in the + // InternalApiToken access control list. + static ColumnInfo Create(sql::Database* db, + const std::string& db_name, + const std::string& table_name, + const std::string& column_name) WARN_UNUSED_RESULT; + + // The native data type. Example: "INTEGER". + std::string data_type; + // Default collation sequence for sorting. Example: "BINARY". + std::string collation_sequence; + // True if the column has a "NOT NULL" constraint. + bool has_non_null_constraint; + // True if the column is included in the table's PRIMARY KEY. + bool is_in_primary_key; + // True if the column is AUTOINCREMENT. + bool is_auto_incremented; +}; + } // namespace test } // namespace sql
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index fbd942cb..ee4419c 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -27532,6 +27532,35 @@ } ] }, + "Win10 FYI Release XR Perf (NVIDIA)": { + "isolated_scripts": [ + { + "args": [ + "--benchmarks=xr.webxr.static", + "-v", + "--upload-results", + "--output-format=histograms", + "--browser=release" + ], + "experiment_percentage": 100, + "isolate_name": "vr_perf_tests", + "merge": { + "script": "//tools/perf/process_perf_results.py" + }, + "name": "xr.webxr.static", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "nvidia-quadro-p400-win10-stable", + "os": "Windows-10", + "pool": "Chrome-GPU" + } + ] + } + } + ] + }, "Win10 FYI dEQP Release (Intel HD 630)": { "gtest_tests": [ {
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 6180fc8..888b695 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -4431,6 +4431,25 @@ }, }, }, + + 'win_specific_xr_perf_tests': { + 'xr.webxr.static': { + 'args': [ + '--benchmarks=xr.webxr.static', + '-v', + '--upload-results', + '--output-format=histograms', + '--browser=release', + ], + 'isolate_name': 'vr_perf_tests', + 'merge': { + 'script': '//tools/perf/process_perf_results.py', + }, + 'name': 'xr.webxr.static', + # Experimental until we're sure these are stable. + 'experiment_percentage': 100, + } + } }, ##############################################################################
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 1507f9d..1bf34e1 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -3190,6 +3190,16 @@ # We keep this value enabled to provide minimal regression testing. 'use_multi_dimension_trigger_script': True, }, + 'Win10 FYI Release XR Perf (NVIDIA)': { + 'os_type': 'win', + 'browser_config': 'release', + 'mixins': [ + 'win10_nvidia_quadro_p400_stable', + ], + 'test_suites': { + 'isolated_scripts': 'win_specific_xr_perf_tests', + }, + }, 'Win10 FYI dEQP Release (Intel HD 630)': { 'os_type': 'win', 'mixins': [
diff --git a/third_party/blink/OWNERS b/third_party/blink/OWNERS index 5b809e1..d398a3d 100644 --- a/third_party/blink/OWNERS +++ b/third_party/blink/OWNERS
@@ -2,7 +2,6 @@ # specific context bratell@opera.com chrishtr@chromium.org -darin@chromium.org foolip@chromium.org jochen@chromium.org mkwst@chromium.org
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index d7d28f1..85b81c5 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -184,7 +184,6 @@ "platform/scheduler/web_resource_loading_task_runner_handle.h", "platform/scheduler/web_scoped_virtual_time_pauser.h", "platform/scheduler/web_thread_scheduler.h", - "platform/scoped_web_callbacks.h", "platform/shape_properties.h", "platform/task_type.h", "platform/url_conversion.h",
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn index 7c1d59c..1737df87 100644 --- a/third_party/blink/public/mojom/BUILD.gn +++ b/third_party/blink/public/mojom/BUILD.gn
@@ -204,6 +204,7 @@ "payments/payment_request.mojom", "remote_objects/remote_objects.mojom", "webauthn/authenticator.mojom", + "webauthn/internal_authenticator.mojom", "webshare/webshare.mojom", ] if (is_android && notouch_build) {
diff --git a/third_party/blink/public/mojom/appcache/appcache.mojom b/third_party/blink/public/mojom/appcache/appcache.mojom index d900153f..549b339f 100644 --- a/third_party/blink/public/mojom/appcache/appcache.mojom +++ b/third_party/blink/public/mojom/appcache/appcache.mojom
@@ -66,10 +66,12 @@ // // Unregistering the host is accomplished by closing the AppCacheHost pipe. // - // TODO(mek): Move this method to DocumentInterfaceBroker to stop passing - // frame ID over mojo. + // Frames go through DocumentInterfaceBroker and this is now only used for + // workers. + // TODO(mek): Once it has 'WebContextInterfaceBroker' for workers, move this + // to the implementation of 'WebContextInterfaceBroker'. crbug.com/718652 RegisterHost(AppCacheHost& host_request, AppCacheFrontend frontend, - int32 host_id, int32 render_frame_id); + int32 host_id); }; interface AppCacheHost {
diff --git a/third_party/blink/public/mojom/frame/document_interface_broker.mojom b/third_party/blink/public/mojom/frame/document_interface_broker.mojom index 5ce5698..6563ea42 100644 --- a/third_party/blink/public/mojom/frame/document_interface_broker.mojom +++ b/third_party/blink/public/mojom/frame/document_interface_broker.mojom
@@ -4,6 +4,7 @@ module blink.mojom; +import "third_party/blink/public/mojom/appcache/appcache.mojom"; import "third_party/blink/public/mojom/credentialmanager/credential_manager.mojom"; import "third_party/blink/public/mojom/frame/frame_host_test_interface.mojom"; import "third_party/blink/public/mojom/webaudio/audio_context_manager.mojom"; @@ -18,4 +19,7 @@ GetCredentialManager(blink.mojom.CredentialManager& request); GetFrameHostTestInterface(blink.mojom.FrameHostTestInterface& request); GetVirtualAuthenticatorManager(blink.test.mojom.VirtualAuthenticatorManager& request); + RegisterAppCacheHost(blink.mojom.AppCacheHost& host_request, + AppCacheFrontend frontend, + int32 host_id); };
diff --git a/third_party/blink/public/mojom/picture_in_picture/picture_in_picture.mojom b/third_party/blink/public/mojom/picture_in_picture/picture_in_picture.mojom index 616ea648..45ecade 100644 --- a/third_party/blink/public/mojom/picture_in_picture/picture_in_picture.mojom +++ b/third_party/blink/public/mojom/picture_in_picture/picture_in_picture.mojom
@@ -7,11 +7,33 @@ import "services/viz/public/interfaces/compositing/surface_id.mojom"; import "ui/gfx/geometry/mojo/geometry.mojom"; -// PictureInPictureDelegate is associated to a PictureInPictureService. It will -// be notified by running its callbacks when a change happened to the running -// Picture-in-Picture session. -interface PictureInPictureDelegate { - PictureInPictureWindowSizeChanged(gfx.mojom.Size size); +// PictureInPictureSessionObserver is associated to a PictureInPictureSession at +// its creation. It receives all the events associated to the session lifetime. +interface PictureInPictureSessionObserver { + // Called when the size of the window associated to the session has changed. + OnWindowSizeChanged(gfx.mojom.Size size); + + // Called when the session is stopped, typically when the user closes the + // Picture-in-Picture window or when another session has started. This will + // not be called when `Stop()` is called on a PictureInPictureSession object. + OnStopped(); +}; + +// Representation of a Picture-in-Picture session. The caller receives this +// object back after a call to `StartSession()` on the main service. It can be +// used to interact with the session after its creation. +interface PictureInPictureSession { + // Update the information used to create the session when it was created. + // This call cannot happen after `Stop()`. + Update(uint32 player_id, + viz.mojom.SurfaceId? surface_id, + gfx.mojom.Size natural_size, + bool show_play_pause_button, + bool show_mute_button); + + // Request to stop the current session. It will close the Picture-in-Picture + // window and make other calls related to the session no-ops. + Stop() => (); }; // PictureInPictureService is a Document-associated interface that lives in @@ -21,7 +43,8 @@ // a Document to display a video in an always-on-top floating window with // basic playback functionality (e.g. play and pause). interface PictureInPictureService { - // Notify the service that it should start a Picture-in-Picture session. + // Notify the service that it should start a Picture-in-Picture session. If a + // Picture-in-Picture session is already running, it will be closed. // player_id: WebMediaPlayer id used to control playback via the // Picture-in-Picture window. // surface_id: SurfaceId to be shown in the Picture-in-Picture window. @@ -30,33 +53,13 @@ // the Picture-in-Picture window. // show_mute_button: Whether a mute control should be offered in the // Picture-in-Picture window. - // NOTE: this method shouldn't be called twice in a raw. An interleaved call - // to EndSession() would be expected. In case of some parameters have changed, - // UpdateSession() should be called. + // observer: Observer to be associated with the session. StartSession( uint32 player_id, viz.mojom.SurfaceId? surface_id, gfx.mojom.Size natural_size, bool show_play_pause_button, - bool show_mute_button) => (gfx.mojom.Size size); - - // Notify the service to end the Picture-in-Picture session. It will close - // the Picture-in-Picture window. - EndSession() => (); - - // Notify the service that some information about the client have change. All - // information associated with the Picture-in-Picture session are sent again. - // A Picture-in-Picture session must already be active from a previous call to - // StartSession(). - UpdateSession( - uint32 player_id, - viz.mojom.SurfaceId? surface_id, - gfx.mojom.Size natural_size, - bool show_play_pause_button, - bool show_mute_button); - - // Associate a PictureInPictureDelegate with the service. All changes in - // Picture-in-Picture states will be sent to the delegate. Only one delegate - // can be set at a time. - SetDelegate(PictureInPictureDelegate delegate); + bool show_mute_button, + PictureInPictureSessionObserver observer) + => (PictureInPictureSession session, gfx.mojom.Size size); };
diff --git a/third_party/blink/public/mojom/service_worker/service_worker.mojom b/third_party/blink/public/mojom/service_worker/service_worker.mojom index f6da6ec..31b3239 100644 --- a/third_party/blink/public/mojom/service_worker/service_worker.mojom +++ b/third_party/blink/public/mojom/service_worker/service_worker.mojom
@@ -229,10 +229,15 @@ // Arguments are passed to the event handler as parameters of SyncEvent. // Ref: https://wicg.github.io/BackgroundSync/spec/#sync-event // |timeout| is the amount of time to allow this event to finish. - DispatchSyncEvent(string id, + DispatchSyncEvent(string tag, bool last_chance, mojo_base.mojom.TimeDelta timeout) => (ServiceWorkerEventStatus status); + // |timeout| is the amount of time to allow this event to finish. + // TODO(crbug.com/925297): Link to spec. + DispatchPeriodicSyncEvent(string tag, + mojo_base.mojom.TimeDelta timeout) + => (ServiceWorkerEventStatus status); DispatchAbortPaymentEvent( payments.mojom.PaymentHandlerResponseCallback result_of_abort_payment) => (ServiceWorkerEventStatus status);
diff --git a/third_party/blink/public/mojom/webauthn/internal_authenticator.mojom b/third_party/blink/public/mojom/webauthn/internal_authenticator.mojom new file mode 100644 index 0000000..a1c3aee --- /dev/null +++ b/third_party/blink/public/mojom/webauthn/internal_authenticator.mojom
@@ -0,0 +1,31 @@ +// 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. + +module blink.mojom; + +import "third_party/blink/public/mojom/webauthn/authenticator.mojom"; + + +// Interface similar to blink::mojom::Authenticator meant only for internal +// components in Chrome to use in order to direct authenticators to create or +// use a public key credential. Unlike Authenticator, the caller will be +// allowed to set its own effective origin. +interface InternalAuthenticator { + // Gets the credential info for a new public key credential created by an + // authenticator for the given |PublicKeyCredentialCreationOptions| + // [MakeCredentialAuthenticatorResponse] will be set if and only if status == SUCCESS. + MakeCredential(PublicKeyCredentialCreationOptions options) + => (AuthenticatorStatus status, MakeCredentialAuthenticatorResponse? credential); + + // Uses an existing credential to produce an assertion for the given + // |PublicKeyCredentialRequestOptions|. + // |GetAssertionResponse| will be set if and only if status == SUCCESS. + GetAssertion(PublicKeyCredentialRequestOptions options) + => (AuthenticatorStatus status, GetAssertionAuthenticatorResponse? credential); + + // Returns true if the user platform provides an authenticator. Relying + // Parties use this method to determine whether they can create a new + // credential using a user-verifying platform authenticator. + IsUserVerifyingPlatformAuthenticatorAvailable() => (bool available); +};
diff --git a/third_party/blink/public/platform/scoped_web_callbacks.h b/third_party/blink/public/platform/scoped_web_callbacks.h deleted file mode 100644 index 3d45802..0000000 --- a/third_party/blink/public/platform/scoped_web_callbacks.h +++ /dev/null
@@ -1,111 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_SCOPED_WEB_CALLBACKS_H_ -#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_SCOPED_WEB_CALLBACKS_H_ - -#include <memory> -#include <utility> - -#include "base/callback.h" -#include "third_party/blink/public/platform/web_callbacks.h" - -namespace blink { - -// A ScopedWebCallbacks is a move-only scoper which helps manage the lifetime of -// a blink::WebCallbacks object. This is particularly useful when you're -// simultaneously dealing with the following two conditions: -// -// 1. Your WebCallbacks implementation requires either onSuccess or onError to -// be called before it's destroyed. This is the case with -// CallbackPromiseAdapter for example, because its underlying -// ScriptPromiseResolver must be resolved or rejected before destruction. -// -// 2. You are passing ownership of the WebCallbacks to code which may -// silenty drop it. A common way for this to happen is to bind the -// WebCallbacks as an argument to a base::Callback which gets destroyed -// before it can run. -// -// While it's possible to individually track the lifetime of pending -// WebCallbacks, this becomes cumbersome when dealing with many different -// callbacks types. ScopedWebCallbacks provides a generic and relatively -// lightweight solution to this problem. -// -// Example usage: -// -// using FooCallbacks = blink::WebCallbacks<const Foo&, const FooError&>; -// -// void RespondWithSuccess(ScopedWebCallbacks<FooCallbacks> callbacks) { -// callbacks.PassCallbacks()->onSuccess(Foo("everything is great")); -// } -// -// void OnCallbacksDropped(std::unique_ptr<FooCallbacks> callbacks) { -// // Ownership of the FooCallbacks is passed to this function if -// // ScopedWebCallbacks::PassCallbacks isn't called before the -// // ScopedWebCallbacks is destroyed. -// callbacks->onError(FooError("everything is terrible")); -// } -// -// // Blink client implementation -// void FooClientImpl::doMagic(std::unique_ptr<FooCallbacks> callbacks) { -// auto scoped_callbacks = make_scoped_web_callbacks( -// std::move(callbacks), base::BindOnce(&OnCallbacksDropped)); -// -// // Call to some lower-level service which may never run the callback we -// // give it. -// foo_service_->DoMagic(base::BindOnce(&RespondWithSuccess, -// std::move(scoped_callbacks))); -// } -// -// If the bound RespondWithSuccess callback actually runs, PassCallbacks() will -// reliquish ownership of the WebCallbacks object to a temporary scoped_ptr -// which will be destroyed immediately after onSuccess is called. -// -// If the bound RespondWithSuccess callback is instead destroyed first, -// the ScopedWebCallbacks destructor will invoke OnCallbacksDropped, executing -// our desired default behavior before deleting the WebCallbacks. -template <typename CallbacksType> -class ScopedWebCallbacks { - public: - using DestructionCallback = - base::OnceCallback<void(std::unique_ptr<CallbacksType> callbacks)>; - - ScopedWebCallbacks(std::unique_ptr<CallbacksType> callbacks, - DestructionCallback destruction_callback) - : callbacks_(std::move(callbacks)), - destruction_callback_(std::move(destruction_callback)) {} - - ~ScopedWebCallbacks() { - if (destruction_callback_) - std::move(destruction_callback_).Run(std::move(callbacks_)); - } - - ScopedWebCallbacks(ScopedWebCallbacks&& other) = default; - ScopedWebCallbacks(const ScopedWebCallbacks& other) = delete; - - ScopedWebCallbacks& operator=(ScopedWebCallbacks&& other) = default; - ScopedWebCallbacks& operator=(const ScopedWebCallbacks& other) = delete; - - std::unique_ptr<CallbacksType> PassCallbacks() { - destruction_callback_ = DestructionCallback(); - return std::move(callbacks_); - } - - private: - std::unique_ptr<CallbacksType> callbacks_; - DestructionCallback destruction_callback_; -}; - -template <typename CallbacksType> -ScopedWebCallbacks<CallbacksType> MakeScopedWebCallbacks( - std::unique_ptr<CallbacksType> callbacks, - typename ScopedWebCallbacks<CallbacksType>::DestructionCallback - destruction_callback) { - return ScopedWebCallbacks<CallbacksType>(std::move(callbacks), - std::move(destruction_callback)); -} - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_SCOPED_WEB_CALLBACKS_H_
diff --git a/third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h b/third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h index 9166e68..66d88e1 100644 --- a/third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h +++ b/third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h
@@ -251,6 +251,11 @@ virtual void DidHandleSyncEvent(int sync_event_id, mojom::ServiceWorkerEventStatus) {} + // Called after PeriodicSyncEvent (dispatched via + // WebServiceWorkerContextProxy) is handled by the service worker. + virtual void DidHandlePeriodicSyncEvent(int sync_event_id, + mojom::ServiceWorkerEventStatus) {} + // RespondToAbortPaymentEvent will be called after the service worker // returns a response to a AbortPaymentEvent, and DidHandleAbortPaymentEvent // will be called after the end of AbortPaymentEvent's lifecycle.
diff --git a/third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h b/third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h index 22a4dd3..f93891a 100644 --- a/third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h +++ b/third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h
@@ -117,12 +117,17 @@ virtual bool HasFetchEventHandler() = 0; - // Once the ServiceWorker has finished handling the sync event, - // didHandleSyncEvent is called on the context client. + // Once the ServiceWorker has finished handling the periodicSync event, + // DidHandleSyncEvent is called on the context client. virtual void DispatchSyncEvent(int sync_event_id, const WebString& tag, bool last_chance) = 0; + // Once the ServiceWorker has finished handling the sync event, + // DidHandlePeriodicSyncEvent is called on the context client. + virtual void DispatchPeriodicSyncEvent(int sync_event_id, + const WebString& tag) = 0; + virtual void DispatchAbortPaymentEvent(int event_id) = 0; virtual void DispatchCanMakePaymentEvent(
diff --git a/third_party/blink/public/web/web_ax_object.h b/third_party/blink/public/web/web_ax_object.h index 7a4be89..13ac49de6 100644 --- a/third_party/blink/public/web/web_ax_object.h +++ b/third_party/blink/public/web/web_ax_object.h
@@ -283,7 +283,6 @@ BLINK_EXPORT bool HasComputedStyle() const; BLINK_EXPORT WebString ComputedStyleDisplay() const; BLINK_EXPORT bool AccessibilityIsIgnored() const; - BLINK_EXPORT bool AccessibilityIsIncludedInTree() const; BLINK_EXPORT void Markers(WebVector<ax::mojom::MarkerType>& types, WebVector<int>& starts, WebVector<int>& ends) const;
diff --git a/third_party/blink/public/web/web_content_capture_client.h b/third_party/blink/public/web/web_content_capture_client.h index 332dbba..52f53a11 100644 --- a/third_party/blink/public/web/web_content_capture_client.h +++ b/third_party/blink/public/web/web_content_capture_client.h
@@ -31,6 +31,10 @@ const std::vector<scoped_refptr<WebContentHolder>>& content, bool first_data) = 0; + // Invoked when a list of |content| is updated. + virtual void DidUpdateContent( + const std::vector<scoped_refptr<WebContentHolder>>& content) = 0; + // Invoked when the previously captured content is removed, |content_ids| is a // list of removed content id. virtual void DidRemoveContent(const std::vector<int64_t>& content_ids) = 0;
diff --git a/third_party/blink/public/web/web_render_theme.h b/third_party/blink/public/web/web_render_theme.h index 7a1e0af..347b342d 100644 --- a/third_party/blink/public/web/web_render_theme.h +++ b/third_party/blink/public/web/web_render_theme.h
@@ -42,6 +42,11 @@ BLINK_EXPORT void SetFocusRingColor(SkColor); +BLINK_EXPORT void SetSelectionColors(unsigned active_background_color, + unsigned active_foreground_color, + unsigned inactive_background_color, + unsigned inactive_foreground_color); + } // namespace blink #endif
diff --git a/third_party/blink/public/web/web_view.h b/third_party/blink/public/web/web_view.h index f831c08..3b6b9a0 100644 --- a/third_party/blink/public/web/web_view.h +++ b/third_party/blink/public/web/web_view.h
@@ -385,11 +385,6 @@ // Custom colors ------------------------------------------------------- - virtual void SetSelectionColors(unsigned active_background_color, - unsigned active_foreground_color, - unsigned inactive_background_color, - unsigned inactive_foreground_color) = 0; - // Sets the default background color when the page has not loaded enough to // know a background colour. This can be overridden by the methods below as // well.
diff --git a/third_party/blink/renderer/bindings/modules/BUILD.gn b/third_party/blink/renderer/bindings/modules/BUILD.gn index 86baaa73..dbdc155 100644 --- a/third_party/blink/renderer/bindings/modules/BUILD.gn +++ b/third_party/blink/renderer/bindings/modules/BUILD.gn
@@ -21,6 +21,7 @@ "//third_party/blink/renderer/modules/app_banner/before_install_prompt_event.idl", "//third_party/blink/renderer/modules/background_fetch/background_fetch_event.idl", "//third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.idl", + "//third_party/blink/renderer/modules/background_sync/periodic_sync_event.idl", "//third_party/blink/renderer/modules/background_sync/sync_event.idl", "//third_party/blink/renderer/modules/cookie_store/cookie_change_event.idl", "//third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.idl",
diff --git a/third_party/blink/renderer/config.gni b/third_party/blink/renderer/config.gni index a90c2cdd..9b140cc 100644 --- a/third_party/blink/renderer/config.gni +++ b/third_party/blink/renderer/config.gni
@@ -74,13 +74,6 @@ feature_defines_list += [ "WTF_USE_WEBAUDIO_PFFFT=1" ] } -if (use_default_render_theme) { - # Mirrors the USE_DEFAULT_RENDER_THEME buildflag_header in WebKit/public. - # If/when Blink can use buildflag headers, this should be removed in - # preference to that. - feature_defines_list += [ "WTF_USE_DEFAULT_RENDER_THEME=1" ] -} - if (blink_symbol_level == 0 && is_win && symbol_level != 0) { # If we use no_symbols on Windows when symbol_level is not zero then no # PDB will be generated but ninja will be expecting one. This would mean
diff --git a/third_party/blink/renderer/core/animation/BUILD.gn b/third_party/blink/renderer/core/animation/BUILD.gn index 780dd18..1cd0b92 100644 --- a/third_party/blink/renderer/core/animation/BUILD.gn +++ b/third_party/blink/renderer/core/animation/BUILD.gn
@@ -264,6 +264,7 @@ "property_handle_test.cc", "scroll_timeline_test.cc", "scroll_timeline_util_test.cc", + "svg_number_interpolation_type_test.cc", "timing_calculations_test.cc", "timing_input_test.cc", ]
diff --git a/third_party/blink/renderer/core/animation/animation_input_helpers.cc b/third_party/blink/renderer/core/animation/animation_input_helpers.cc index b9ae4d13..f542174 100644 --- a/third_party/blink/renderer/core/animation/animation_input_helpers.cc +++ b/third_party/blink/renderer/core/animation/animation_input_helpers.cc
@@ -217,11 +217,11 @@ const QualifiedName* AnimationInputHelpers::KeyframeAttributeToSVGAttribute( const String& property, Element* element) { - if (!RuntimeEnabledFeatures::WebAnimationsSVGEnabled() || !element || - !element->IsSVGElement() || !IsSVGPrefixed(property)) + auto* svg_element = DynamicTo<SVGElement>(element); + if (!RuntimeEnabledFeatures::WebAnimationsSVGEnabled() || !svg_element || + !IsSVGPrefixed(property)) return nullptr; - SVGElement* svg_element = ToSVGElement(element); if (IsSVGSMILElement(svg_element)) return nullptr;
diff --git a/third_party/blink/renderer/core/animation/interpolation_type.h b/third_party/blink/renderer/core/animation/interpolation_type.h index 0606928..ff850c5 100644 --- a/third_party/blink/renderer/core/animation/interpolation_type.h +++ b/third_party/blink/renderer/core/animation/interpolation_type.h
@@ -14,6 +14,7 @@ #include "third_party/blink/renderer/core/animation/primitive_interpolation.h" #include "third_party/blink/renderer/core/animation/property_handle.h" #include "third_party/blink/renderer/core/animation/underlying_value_owner.h" +#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" @@ -28,7 +29,7 @@ // - Convert the target Element's property value to an InterpolationValue: // maybeConvertUnderlyingValue() // - Apply an InterpolationValue to a target Element's property: apply(). -class InterpolationType { +class CORE_EXPORT InterpolationType { USING_FAST_MALLOC(InterpolationType); public:
diff --git a/third_party/blink/renderer/core/animation/keyframe_effect.cc b/third_party/blink/renderer/core/animation/keyframe_effect.cc index 6894a5d..2370bbb6 100644 --- a/third_party/blink/renderer/core/animation/keyframe_effect.cc +++ b/third_party/blink/renderer/core/animation/keyframe_effect.cc
@@ -379,9 +379,9 @@ if (changed) { target_->SetNeedsAnimationStyleRecalc(); - if (RuntimeEnabledFeatures::WebAnimationsSVGEnabled() && - target_->IsSVGElement()) - ToSVGElement(*target_).SetWebAnimationsPending(); + auto* svg_element = DynamicTo<SVGElement>(target_.Get()); + if (RuntimeEnabledFeatures::WebAnimationsSVGEnabled() && svg_element) + svg_element->SetWebAnimationsPending(); } } @@ -393,9 +393,9 @@ if (GetAnimation()) GetAnimation()->RestartAnimationOnCompositor(); target_->SetNeedsAnimationStyleRecalc(); - if (RuntimeEnabledFeatures::WebAnimationsSVGEnabled() && - target_->IsSVGElement()) - ToSVGElement(*target_).ClearWebAnimatedAttributes(); + auto* svg_element = DynamicTo<SVGElement>(target_.Get()); + if (RuntimeEnabledFeatures::WebAnimationsSVGEnabled() && svg_element) + svg_element->ClearWebAnimatedAttributes(); Invalidate(); } @@ -424,9 +424,9 @@ return; target_->EnsureElementAnimations().Animations().insert(animation); target_->SetNeedsAnimationStyleRecalc(); - if (RuntimeEnabledFeatures::WebAnimationsSVGEnabled() && - target_->IsSVGElement()) - ToSVGElement(target_)->SetWebAnimationsPending(); + auto* svg_element = DynamicTo<SVGElement>(target_.Get()); + if (RuntimeEnabledFeatures::WebAnimationsSVGEnabled() && svg_element) + svg_element->SetWebAnimationsPending(); } void KeyframeEffect::DetachTarget(Animation* animation) {
diff --git a/third_party/blink/renderer/core/animation/svg_interpolation_type.h b/third_party/blink/renderer/core/animation/svg_interpolation_type.h index a7960db..573b2f9 100644 --- a/third_party/blink/renderer/core/animation/svg_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/svg_interpolation_type.h
@@ -7,11 +7,13 @@ #include "third_party/blink/renderer/core/animation/interpolation_type.h" +#include "third_party/blink/renderer/core/core_export.h" + namespace blink { class SVGPropertyBase; -class SVGInterpolationType : public InterpolationType { +class CORE_EXPORT SVGInterpolationType : public InterpolationType { protected: SVGInterpolationType(const QualifiedName& attribute) : InterpolationType(PropertyHandle(attribute)) {}
diff --git a/third_party/blink/renderer/core/animation/svg_number_interpolation_type.cc b/third_party/blink/renderer/core/animation/svg_number_interpolation_type.cc index 9a8dad7..bf2cf3a6 100644 --- a/third_party/blink/renderer/core/animation/svg_number_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/svg_number_interpolation_type.cc
@@ -11,9 +11,16 @@ #include "third_party/blink/renderer/core/svg/properties/svg_animated_property.h" #include "third_party/blink/renderer/core/svg/svg_number.h" #include "third_party/blink/renderer/platform/heap/heap.h" +#include "third_party/blink/renderer/platform/wtf/math_extras.h" namespace blink { +SVGPropertyBase* SVGNumberInterpolationType::AppliedSVGValueForTesting( + const InterpolableValue& interpolable_value, + const NonInterpolableValue* non_interpolable_value) const { + return AppliedSVGValue(interpolable_value, non_interpolable_value); +} + InterpolationValue SVGNumberInterpolationType::MaybeConvertNeutral( const InterpolationValue&, ConversionCheckers&) const { @@ -31,7 +38,8 @@ SVGPropertyBase* SVGNumberInterpolationType::AppliedSVGValue( const InterpolableValue& interpolable_value, const NonInterpolableValue*) const { - double value = ToInterpolableNumber(interpolable_value).Value(); + float value = + clampTo<float>(ToInterpolableNumber(interpolable_value).Value()); return MakeGarbageCollected<SVGNumber>(is_non_negative_ && value < 0 ? 0 : value); }
diff --git a/third_party/blink/renderer/core/animation/svg_number_interpolation_type.h b/third_party/blink/renderer/core/animation/svg_number_interpolation_type.h index 9afe9be..1c9798bb 100644 --- a/third_party/blink/renderer/core/animation/svg_number_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/svg_number_interpolation_type.h
@@ -6,16 +6,20 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_SVG_NUMBER_INTERPOLATION_TYPE_H_ #include "third_party/blink/renderer/core/animation/svg_interpolation_type.h" +#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/svg_names.h" namespace blink { -class SVGNumberInterpolationType : public SVGInterpolationType { +class CORE_EXPORT SVGNumberInterpolationType : public SVGInterpolationType { public: SVGNumberInterpolationType(const QualifiedName& attribute) : SVGInterpolationType(attribute), is_non_negative_(attribute == svg_names::kPathLengthAttr) {} + SVGPropertyBase* AppliedSVGValueForTesting(const InterpolableValue&, + const NonInterpolableValue*) const; + private: InterpolationValue MaybeConvertNeutral(const InterpolationValue& underlying, ConversionCheckers&) const final;
diff --git a/third_party/blink/renderer/core/animation/svg_number_interpolation_type_test.cc b/third_party/blink/renderer/core/animation/svg_number_interpolation_type_test.cc new file mode 100644 index 0000000..358de15 --- /dev/null +++ b/third_party/blink/renderer/core/animation/svg_number_interpolation_type_test.cc
@@ -0,0 +1,55 @@ +// 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 "third_party/blink/renderer/core/animation/svg_number_interpolation_type.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/core/svg/svg_number.h" + +namespace blink { + +TEST(SVGNumberInterpolationTypeTest, NonNegativeSVGNumber) { + // kPathLengthAttr implies non-negative. + SVGNumberInterpolationType interpolation_type(svg_names::kPathLengthAttr); + + SVGNumber* svg_number = + static_cast<SVGNumber*>(interpolation_type.AppliedSVGValueForTesting( + InterpolableNumber(5), nullptr)); + EXPECT_EQ(svg_number->Value(), 5); + + svg_number = + static_cast<SVGNumber*>(interpolation_type.AppliedSVGValueForTesting( + InterpolableNumber(-5), nullptr)); + EXPECT_EQ(svg_number->Value(), 0); +} + +TEST(SVGNumberInterpolationTypeTest, NegativeSVGNumber) { + // kOffsetAttr can be negative. + SVGNumberInterpolationType interpolation_type(svg_names::kOffsetAttr); + + SVGNumber* svg_number = + static_cast<SVGNumber*>(interpolation_type.AppliedSVGValueForTesting( + InterpolableNumber(5), nullptr)); + EXPECT_EQ(svg_number->Value(), 5); + + svg_number = + static_cast<SVGNumber*>(interpolation_type.AppliedSVGValueForTesting( + InterpolableNumber(-5), nullptr)); + EXPECT_EQ(svg_number->Value(), -5); +} + +// This is a regression test for https://crbug.com/961859. InterpolableNumber +// can represent a double, but SVGNumber is created from a float, so we must +// make sure to clamp it. +TEST(SVGNumberInterpolationTypeTest, InterpolableNumberOutOfRange) { + SVGNumberInterpolationType interpolation_type(svg_names::kOffsetAttr); + + double too_large = std::numeric_limits<float>::max() * 2; + SVGNumber* svg_number = + static_cast<SVGNumber*>(interpolation_type.AppliedSVGValueForTesting( + InterpolableNumber(too_large), nullptr)); + EXPECT_EQ(svg_number->Value(), std::numeric_limits<float>::max()); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/animation/timing_calculations.h b/third_party/blink/renderer/core/animation/timing_calculations.h index 9388744..cd43f25 100644 --- a/third_party/blink/renderer/core/animation/timing_calculations.h +++ b/third_party/blink/renderer/core/animation/timing_calculations.h
@@ -38,6 +38,18 @@ namespace blink { +namespace { +inline bool IsWithinEpsilon(double a, double b) { + // Permit 2-bits of quantization error. Threshold based on experimentation + // with accuracy of fmod. + return std::abs(a - b) <= 2.0 * std::numeric_limits<double>::epsilon(); +} + +inline bool LessThanOrEqualToWithinEpsilon(double a, double b) { + return a <= b || IsWithinEpsilon(a, b); +} +} // namespace + static inline double MultiplyZeroAlwaysGivesZero(double x, double y) { DCHECK(!IsNull(x)); DCHECK(!IsNull(y)); @@ -50,12 +62,6 @@ return x.is_zero() || y == 0 ? 0 : (x * y).InSecondsF(); } -static inline bool IsWithinEpsilon(double a, double b) { - // Permit 2-bits of quantization error. Threshold based on experimentation - // with accuracy of fmod. - return std::abs(a - b) <= 2.0 * std::numeric_limits<double>::epsilon(); -} - // https://drafts.csswg.org/web-animations-1/#animation-effect-phases-and-states static inline AnimationEffect::Phase CalculatePhase( double active_duration, @@ -124,7 +130,8 @@ if (IsNull(active_time)) return NullValue(); - DCHECK(active_time >= 0 && active_time <= active_duration); + DCHECK(active_time >= 0 && + LessThanOrEqualToWithinEpsilon(active_time, active_duration)); if (!std::isfinite(active_time)) return std::numeric_limits<double>::infinity(); @@ -155,7 +162,8 @@ return NullValue(); DCHECK_GE(offset_active_time, 0); - DCHECK_LE(offset_active_time, repeated_duration + start_offset); + DCHECK(LessThanOrEqualToWithinEpsilon(offset_active_time, + repeated_duration + start_offset)); if (!std::isfinite(offset_active_time) || (offset_active_time - start_offset == repeated_duration &&
diff --git a/third_party/blink/renderer/core/animation/timing_calculations_test.cc b/third_party/blink/renderer/core/animation/timing_calculations_test.cc index a8d961c..5785e6ac 100644 --- a/third_party/blink/renderer/core/animation/timing_calculations_test.cc +++ b/third_party/blink/renderer/core/animation/timing_calculations_test.cc
@@ -91,6 +91,13 @@ std::numeric_limits<double>::infinity(), CalculateOffsetActiveTime(std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity(), 0)); + + // Edge case for active_time being within epsilon of active_duration. + // https://crbug.com/962138 + const double active_time = 1.3435713716800004; + const double active_duration = 1.3435713716800002; + EXPECT_EQ(active_time, + CalculateOffsetActiveTime(active_duration, active_time, 0)); } TEST(AnimationTimingCalculationsTest, IterationTime) { @@ -117,6 +124,18 @@ timing.iteration_start = 1.1; EXPECT_EQ(8, CalculateIterationTime(12, 120, 20, 7, AnimationEffect::kPhaseActive, timing)); + + // Edge case for offset_active_time being within epsilon of (repeated_duration + // + start_offset). https://crbug.com/962138 + timing.iteration_count = 1; + const double offset_active_time = 1.3435713716800004; + const double iteration_duration = 1.3435713716800002; + const double repeated_duration = 1.3435713716800002; + EXPECT_NEAR(2.22045e-16, + CalculateIterationTime(iteration_duration, repeated_duration, + offset_active_time, 0, + AnimationEffect::kPhaseActive, timing), + std::numeric_limits<float>::epsilon()); } TEST(AnimationTimingCalculationsTest, OverallProgress) {
diff --git a/third_party/blink/renderer/core/content_capture/content_capture_manager.cc b/third_party/blink/renderer/core/content_capture/content_capture_manager.cc index 74e4e2c..830d92fe 100644 --- a/third_party/blink/renderer/core/content_capture/content_capture_manager.cc +++ b/third_party/blink/renderer/core/content_capture/content_capture_manager.cc
@@ -69,6 +69,11 @@ ScheduleTask(ContentCaptureTask::ScheduleReason::kScrolling); } +void ContentCaptureManager::OnNodeTextChanged(const NodeHolder& node_holder) { + task_session_->OnNodeChanged(node_holder); + ScheduleTask(ContentCaptureTask::ScheduleReason::kContentChange); +} + void ContentCaptureManager::Trace(Visitor* visitor) { visitor->Trace(local_frame_root_); visitor->Trace(task_session_);
diff --git a/third_party/blink/renderer/core/content_capture/content_capture_manager.h b/third_party/blink/renderer/core/content_capture/content_capture_manager.h index 5fc6bfa..fd8a0fea 100644 --- a/third_party/blink/renderer/core/content_capture/content_capture_manager.h +++ b/third_party/blink/renderer/core/content_capture/content_capture_manager.h
@@ -36,6 +36,9 @@ // Invokes when scroll position was changed. void OnScrollPositionChanged(); + // Invokes when text node content was changed. + void OnNodeTextChanged(const NodeHolder& node_holder); + // Invokes when the local_frame_root shutdown. void Shutdown();
diff --git a/third_party/blink/renderer/core/content_capture/content_capture_task.cc b/third_party/blink/renderer/core/content_capture/content_capture_task.cc index bf2637d..ce7e395 100644 --- a/third_party/blink/renderer/core/content_capture/content_capture_task.cc +++ b/third_party/blink/renderer/core/content_capture/content_capture_task.cc
@@ -77,23 +77,33 @@ TaskSession::DocumentSession& doc_session) { auto* document = doc_session.GetDocument(); DCHECK(document); + auto* client = GetWebContentCaptureClient(*document); + DCHECK(client); + if (histogram_reporter_) histogram_reporter_->OnSendContentStarted(); std::vector<scoped_refptr<WebContentHolder>> content_batch; content_batch.reserve(kBatchSize); + // Only send changed content after the new content was sent. + bool sending_changed_content = !doc_session.HasUnsentCapturedContent(); while (content_batch.size() < kBatchSize) { - scoped_refptr<ContentHolder> content_holder = - doc_session.GetNextUnsentContentHolder(); + scoped_refptr<ContentHolder> content_holder; + if (sending_changed_content) + content_holder = doc_session.GetNextChangedContentHolder(); + else + content_holder = doc_session.GetNextUnsentContentHolder(); if (!content_holder) break; content_batch.push_back( base::MakeRefCounted<WebContentHolder>(content_holder)); } if (!content_batch.empty()) { - DCHECK(GetWebContentCaptureClient(*document)); - GetWebContentCaptureClient(*document)->DidCaptureContent( - content_batch, !doc_session.FirstDataHasSent()); - doc_session.SetFirstDataHasSent(); + if (sending_changed_content) { + client->DidUpdateContent(content_batch); + } else { + client->DidCaptureContent(content_batch, !doc_session.FirstDataHasSent()); + doc_session.SetFirstDataHasSent(); + } } if (histogram_reporter_) histogram_reporter_->OnSendContentEnded(content_batch.size()); @@ -128,7 +138,8 @@ return true; } - while (doc_session.HasUnsentCapturedContent()) { + while (doc_session.HasUnsentCapturedContent() || + doc_session.HasUnsentChangedContent()) { SendContent(doc_session); if (ShouldPause()) { return !doc_session.HasUnsentData();
diff --git a/third_party/blink/renderer/core/content_capture/content_capture_test.cc b/third_party/blink/renderer/core/content_capture/content_capture_test.cc index 36cbf93..4f615d7 100644 --- a/third_party/blink/renderer/core/content_capture/content_capture_test.cc +++ b/third_party/blink/renderer/core/content_capture/content_capture_test.cc
@@ -55,6 +55,13 @@ all_text_.push_back(d->GetValue().Utf8()); } + void DidUpdateContent( + const std::vector<scoped_refptr<WebContentHolder>>& data) override { + updated_data_ = data; + for (auto d : data) + updated_text_.push_back(d->GetValue().Utf8()); + } + void DidRemoveContent(const std::vector<int64_t>& data) override { removed_data_ = data; } @@ -65,22 +72,31 @@ return data_; } + const std::vector<scoped_refptr<WebContentHolder>>& UpdatedData() const { + return updated_data_; + } + const std::vector<std::string>& AllText() const { return all_text_; } + const std::vector<std::string>& UpdatedText() const { return updated_text_; } + const std::vector<int64_t>& RemovedData() const { return removed_data_; } void ResetResults() { first_data_ = false; data_.clear(); + updated_data_.clear(); removed_data_.clear(); } private: bool first_data_ = false; std::vector<scoped_refptr<WebContentHolder>> data_; + std::vector<scoped_refptr<WebContentHolder>> updated_data_; std::vector<int64_t> removed_data_; NodeHolder::Type node_holder_type_; std::vector<std::string> all_text_; + std::vector<std::string> updated_text_; }; class ContentCaptureTaskTestHelper : public ContentCaptureTask { @@ -525,6 +541,8 @@ : public SimTest, public ::testing::WithParamInterface<NodeHolder::Type> { public: + static const char* kEditableContent; + ContentCaptureSimTest() : client_(GetParam()), child_client_(GetParam()) {} void SetUp() override { SimTest::SetUp(); @@ -570,6 +588,15 @@ child_frame_expected_text_.push_back("New Text"); } + void InsertMainFrameEditableContent(const std::string& content, + unsigned offset) { + InsertNodeContent(GetDocument(), "editable_id", content, offset); + } + + void DeleteMainFrameEditableContent(unsigned offset, unsigned length) { + DeleteNodeContent(GetDocument(), "editable_id", offset, length); + } + const std::vector<std::string>& MainFrameExpectedText() const { return main_frame_expected_text_; } @@ -578,6 +605,12 @@ return child_frame_expected_text_; } + void ReplaceMainFrameExpectedText(const std::string& old_text, + const std::string& new_text) { + std::replace(main_frame_expected_text_.begin(), + main_frame_expected_text_.end(), old_text, new_text); + } + private: void SetupPage() { SimRequest main_resource("https://example.com/test.html", "text/html"); @@ -595,6 +628,7 @@ <p id='p5'>Hello World5</p> <p id='p6'>Hello World6</p> <p id='p7'>Hello World7</p> + <div id='editable_id'>editable</div> <svg> <text id="s8">Hello World8</text> </svg> @@ -620,13 +654,14 @@ } void InitMainFrameNodeHolders() { - std::vector<std::string> ids = {"p1", "p2", "p3", "p4", - "p5", "p6", "p7", "s8"}; - main_frame_expected_text_ = {"Hello World1", "Hello World2", "Hello World3", - "Hello World4", "Hello World5", "Hello World6", - "Hello World7", "Hello World8"}; + std::vector<std::string> ids = {"p1", "p2", "p3", "p4", "p5", + "p6", "p7", "s8", "editable_id"}; + main_frame_expected_text_ = { + "Hello World1", "Hello World2", "Hello World3", + "Hello World4", "Hello World5", "Hello World6", + "Hello World7", "Hello World8", kEditableContent}; InitNodeHolders(main_frame_content_, ids, GetDocument()); - EXPECT_EQ(8u, main_frame_content_.size()); + EXPECT_EQ(9u, main_frame_content_.size()); } void InitChildFrameNodeHolders(const Document& doc) { @@ -659,6 +694,25 @@ buffer.insert(buffer.begin(), layout_text->EnsureNodeHolder()); } + void InsertNodeContent(Document& doc, + const std::string& id, + const std::string& content, + unsigned offset) { + To<Text>(doc.getElementById(id.c_str())->firstChild()) + ->insertData(offset, String(content.c_str()), + IGNORE_EXCEPTION_FOR_TESTING); + Compositor().BeginFrame(); + } + + void DeleteNodeContent(Document& doc, + const std::string& id, + unsigned offset, + unsigned length) { + To<Text>(doc.getElementById(id.c_str())->firstChild()) + ->deleteData(offset, length, IGNORE_EXCEPTION_FOR_TESTING); + Compositor().BeginFrame(); + } + void SetCapturedContent(const std::vector<NodeHolder>& captured_content) { GetDocument() .GetFrame() @@ -677,6 +731,8 @@ Persistent<Document> child_document_; }; +const char* ContentCaptureSimTest::kEditableContent = "editable"; + INSTANTIATE_TEST_SUITE_P(, ContentCaptureSimTest, testing::Values(NodeHolder::Type::kID, @@ -685,7 +741,7 @@ TEST_P(ContentCaptureSimTest, MultiFrame) { SetCapturedContent(ContentType::kAll); RunContentCaptureTaskUntil(ContentCaptureTask::TaskState::kStop); - EXPECT_EQ(3u, Client().Data().size()); + EXPECT_EQ(4u, Client().Data().size()); EXPECT_EQ(2u, ChildClient().Data().size()); EXPECT_THAT(Client().AllText(), testing::UnorderedElementsAreArray(MainFrameExpectedText())); @@ -710,7 +766,7 @@ // Sends the reset of data RunContentCaptureTaskUntil(ContentCaptureTask::TaskState::kProcessRetryTask); - EXPECT_EQ(3u, Client().Data().size()); + EXPECT_EQ(4u, Client().Data().size()); EXPECT_FALSE(Client().FirstData()); EXPECT_TRUE(ChildClient().Data().empty()); EXPECT_THAT(Client().AllText(), @@ -735,4 +791,104 @@ EXPECT_TRUE(ChildClient().FirstData()); } +TEST_P(ContentCaptureSimTest, ChangeNode) { + SetCapturedContent(ContentType::kMainFrame); + RunContentCaptureTaskUntil(ContentCaptureTask::TaskState::kStop); + EXPECT_EQ(4u, Client().Data().size()); + EXPECT_FALSE(Client().FirstData()); + EXPECT_TRUE(ChildClient().Data().empty()); + EXPECT_THAT(Client().AllText(), + testing::UnorderedElementsAreArray(MainFrameExpectedText())); + std::vector<std::string> expected_text_update; + std::string insert_text = "content "; + + // Changed content to 'content editable'. + InsertMainFrameEditableContent(insert_text, 0); + SetCapturedContent(ContentType::kMainFrame); + RunContentCaptureTaskUntil(ContentCaptureTask::TaskState::kStop); + EXPECT_EQ(1u, Client().UpdatedData().size()); + EXPECT_FALSE(Client().FirstData()); + EXPECT_TRUE(ChildClient().Data().empty()); + expected_text_update.push_back(insert_text + kEditableContent); + EXPECT_THAT(Client().UpdatedText(), + testing::UnorderedElementsAreArray(expected_text_update)); + + // Changing content multiple times before capturing. + std::string insert_text1 = "i"; + // Changed content to 'content ieditable'. + InsertMainFrameEditableContent(insert_text1, insert_text.size()); + std::string insert_text2 = "s "; + // Changed content to 'content is editable'. + InsertMainFrameEditableContent(insert_text2, + insert_text.size() + insert_text1.size()); + + SetCapturedContent(ContentType::kMainFrame); + RunContentCaptureTaskUntil(ContentCaptureTask::TaskState::kStop); + EXPECT_EQ(1u, Client().UpdatedData().size()); + EXPECT_FALSE(Client().FirstData()); + EXPECT_TRUE(ChildClient().Data().empty()); + expected_text_update.push_back(insert_text + insert_text1 + insert_text2 + + kEditableContent); + EXPECT_THAT(Client().UpdatedText(), + testing::UnorderedElementsAreArray(expected_text_update)); +} + +TEST_P(ContentCaptureSimTest, ChangeNodeBeforeCapture) { + // Changed content to 'content editable' before capture. + std::string insert_text = "content "; + InsertMainFrameEditableContent(insert_text, 0); + // Changing content multiple times before capturing. + std::string insert_text1 = "i"; + // Changed content to 'content ieditable'. + InsertMainFrameEditableContent(insert_text1, insert_text.size()); + std::string insert_text2 = "s "; + // Changed content to 'content is editable'. + InsertMainFrameEditableContent(insert_text2, + insert_text.size() + insert_text1.size()); + + // The changed content shall be captured as new content. + ReplaceMainFrameExpectedText( + kEditableContent, + insert_text + insert_text1 + insert_text2 + kEditableContent); + SetCapturedContent(ContentType::kMainFrame); + RunContentCaptureTaskUntil(ContentCaptureTask::TaskState::kStop); + EXPECT_EQ(4u, Client().Data().size()); + EXPECT_FALSE(Client().FirstData()); + EXPECT_TRUE(ChildClient().Data().empty()); + EXPECT_TRUE(ChildClient().UpdatedData().empty()); + EXPECT_THAT(Client().AllText(), + testing::UnorderedElementsAreArray(MainFrameExpectedText())); +} + +TEST_P(ContentCaptureSimTest, DeleteNodeContent) { + SetCapturedContent(ContentType::kMainFrame); + RunContentCaptureTaskUntil(ContentCaptureTask::TaskState::kStop); + EXPECT_EQ(4u, Client().Data().size()); + EXPECT_FALSE(Client().FirstData()); + EXPECT_TRUE(ChildClient().Data().empty()); + EXPECT_THAT(Client().AllText(), + testing::UnorderedElementsAreArray(MainFrameExpectedText())); + + // Deleted 4 char, changed content to 'edit'. + DeleteMainFrameEditableContent(4, 4); + SetCapturedContent(ContentType::kMainFrame); + RunContentCaptureTaskUntil(ContentCaptureTask::TaskState::kStop); + EXPECT_EQ(1u, Client().UpdatedData().size()); + EXPECT_FALSE(Client().FirstData()); + EXPECT_TRUE(ChildClient().Data().empty()); + std::vector<std::string> expected_text_update; + expected_text_update.push_back("edit"); + EXPECT_THAT(Client().UpdatedText(), + testing::UnorderedElementsAreArray(expected_text_update)); + + // Emptied content, the node shall be removed. + DeleteMainFrameEditableContent(0, 4); + SetCapturedContent(ContentType::kMainFrame); + RunContentCaptureTaskUntil(ContentCaptureTask::TaskState::kStop); + EXPECT_TRUE(Client().UpdatedData().empty()); + EXPECT_FALSE(Client().FirstData()); + EXPECT_TRUE(ChildClient().Data().empty()); + EXPECT_EQ(1u, Client().RemovedData().size()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/content_capture/task_session.cc b/third_party/blink/renderer/core/content_capture/task_session.cc index 1e3d35a2..5b14b14 100644 --- a/third_party/blink/renderer/core/content_capture/task_session.cc +++ b/third_party/blink/renderer/core/content_capture/task_session.cc
@@ -31,6 +31,11 @@ detached_nodes_.push_back(id); } +void TaskSession::DocumentSession::AddChangedNodeHolder( + cc::NodeHolder node_holder) { + changed_content_.push_back(node_holder); +} + std::vector<int64_t> TaskSession::DocumentSession::MoveDetachedNodes() { return std::move(detached_nodes_); } @@ -64,12 +69,36 @@ return content_holder; } +scoped_refptr<blink::ContentHolder> +TaskSession::DocumentSession::GetNextChangedContentHolder() { + scoped_refptr<ContentHolder> content_holder; + while (!changed_content_.empty() && !content_holder) { + auto node_holder = changed_content_.back(); + if (node_holder.type == cc::NodeHolder::Type::kID) { + Node* node = DOMNodeIds::NodeForId(node_holder.id); + if (node && node->GetLayoutObject()) + content_holder = base::MakeRefCounted<ContentHolder>(*node); + } else if (node_holder.type == cc::NodeHolder::Type::kTextHolder && + node_holder.text_holder) { + content_holder = scoped_refptr<ContentHolder>( + static_cast<ContentHolder*>(node_holder.text_holder.get())); + if (content_holder && !content_holder->IsValid()) + content_holder.reset(); + } + changed_content_.pop_back(); + } + if (content_holder) + total_sent_nodes_++; + return content_holder; +} + void TaskSession::DocumentSession::Trace(blink::Visitor* visitor) { visitor->Trace(sent_nodes_); visitor->Trace(document_); } void TaskSession::DocumentSession::Reset() { + changed_content_.clear(); captured_content_.clear(); detached_nodes_.clear(); } @@ -97,6 +126,19 @@ void TaskSession::GroupCapturedContentByDocument( const std::vector<cc::NodeHolder>& captured_content) { for (const cc::NodeHolder& node_holder : captured_content) { + if (const Node* node = GetNode(node_holder)) { + node = changed_nodes_.Take(node); + if (node) { + // The changed node might not be sent. + if (GetNodeIf(true, node_holder)) { + EnsureDocumentSession(node->GetDocument()) + .AddChangedNodeHolder(node_holder); + } else { + EnsureDocumentSession(node->GetDocument()).AddNodeHolder(node_holder); + } + continue; + } + } if (const Node* node = GetNodeIf(false /* sent */, node_holder)) { EnsureDocumentSession(node->GetDocument()).AddNodeHolder(node_holder); } @@ -111,6 +153,12 @@ } } +void TaskSession::OnNodeChanged(const cc::NodeHolder& node_holder) { + if (const Node* node = GetNode(node_holder)) { + changed_nodes_.insert(WeakMember<const Node>(node)); + } +} + const Node* TaskSession::GetNodeIf(bool sent, const cc::NodeHolder& node_holder) const { Node* node = nullptr; @@ -129,6 +177,19 @@ return nullptr; } +const Node* TaskSession::GetNode(const cc::NodeHolder& node_holder) const { + if (node_holder.type == cc::NodeHolder::Type::kID) + return DOMNodeIds::NodeForId(node_holder.id); + + if (node_holder.type == cc::NodeHolder::Type::kTextHolder) { + ContentHolder* content_holder = + static_cast<ContentHolder*>(node_holder.text_holder.get()); + if (content_holder) + return content_holder->GetNode(); + } + return nullptr; +} + TaskSession::DocumentSession& TaskSession::EnsureDocumentSession( const Document& doc) { DocumentSession* doc_session = GetDocumentSession(doc); @@ -150,6 +211,7 @@ void TaskSession::Trace(blink::Visitor* visitor) { visitor->Trace(sent_nodes_); + visitor->Trace(changed_nodes_); visitor->Trace(to_document_session_); }
diff --git a/third_party/blink/renderer/core/content_capture/task_session.h b/third_party/blink/renderer/core/content_capture/task_session.h index a148d7f..b91c1ac3 100644 --- a/third_party/blink/renderer/core/content_capture/task_session.h +++ b/third_party/blink/renderer/core/content_capture/task_session.h
@@ -54,10 +54,13 @@ ~DocumentSession(); void AddNodeHolder(cc::NodeHolder node_holder); void AddDetachedNode(int64_t id); + void AddChangedNodeHolder(cc::NodeHolder node); bool HasUnsentData() const { - return HasUnsentCapturedContent() || HasUnsentDetachedNodes(); + return HasUnsentCapturedContent() || HasUnsentChangedContent() || + HasUnsentDetachedNodes(); } bool HasUnsentCapturedContent() const { return !captured_content_.empty(); } + bool HasUnsentChangedContent() const { return !changed_content_.empty(); } bool HasUnsentDetachedNodes() const { return !detached_nodes_.empty(); } std::vector<int64_t> MoveDetachedNodes(); const Document* GetDocument() const { return document_; } @@ -68,6 +71,8 @@ // ContentHolder. scoped_refptr<ContentHolder> GetNextUnsentContentHolder(); + scoped_refptr<ContentHolder> GetNextChangedContentHolder(); + // Resets the |captured_content_| and the |detached_nodes_|, shall only be // used if those data doesn't need to be sent, e.g. there is no // WebContentCaptureClient for this document. @@ -83,6 +88,9 @@ std::vector<int64_t> detached_nodes_; WeakMember<const Document> document_; Member<SentNodes> sent_nodes_; + // The list of changed nodes that needs to be sent. + std::vector<cc::NodeHolder> changed_content_; + bool first_data_has_sent_ = false; // This is for the metrics to record the total node that has been sent. size_t total_sent_nodes_ = 0; @@ -102,6 +110,8 @@ void OnNodeDetached(const cc::NodeHolder& node_holder); + void OnNodeChanged(const cc::NodeHolder& node_holder); + bool HasUnsentData() const { return has_unsent_data_; } void SetSentNodeCountCallback( @@ -119,9 +129,13 @@ DocumentSession& EnsureDocumentSession(const Document& doc); DocumentSession* GetDocumentSession(const Document& document) const; const Node* GetNodeIf(bool sent, const cc::NodeHolder& node_holder) const; + const Node* GetNode(const cc::NodeHolder& node_holder) const; Member<SentNodes> sent_nodes_; + // The list of node whose value has changed. + HeapHashSet<WeakMember<const Node>> changed_nodes_; + // This owns the DocumentSession which is released along with Document. HeapHashMap<WeakMember<const Document>, Member<DocumentSession>> to_document_session_;
diff --git a/third_party/blink/renderer/core/css/css_default_style_sheets.cc b/third_party/blink/renderer/core/css/css_default_style_sheets.cc index f99a469..175651e5 100644 --- a/third_party/blink/renderer/core/css/css_default_style_sheets.cc +++ b/third_party/blink/renderer/core/css/css_default_style_sheets.cc
@@ -121,10 +121,6 @@ default_style_->AddRulesFromSheet(DefaultStyleSheet(), ScreenEval()); default_print_style_->AddRulesFromSheet(DefaultStyleSheet(), PrintEval()); default_quirks_style_->AddRulesFromSheet(QuirksStyleSheet(), ScreenEval()); - -#if defined(ENABLE_TOUCHLESS_UASTYLE_THEME) - EnsureDefaultStyleSheetForTouchless(); -#endif } RuleSet* CSSDefaultStyleSheets::DefaultViewSourceStyle() { @@ -218,20 +214,6 @@ ScreenEval()); } -void CSSDefaultStyleSheets::EnsureDefaultStyleSheetForTouchless() { - if (touchless_style_sheet_) - return; - - String touchless_rules = GetDataResourceAsASCIIString("touchless.css"); - if (touchless_rules.IsEmpty()) - return; - - touchless_style_sheet_ = ParseUASheet(touchless_rules); - default_style_->AddRulesFromSheet(touchless_style_sheet_.Get(), ScreenEval()); - default_quirks_style_->AddRulesFromSheet(touchless_style_sheet_.Get(), - ScreenEval()); -} - void CSSDefaultStyleSheets::Trace(blink::Visitor* visitor) { visitor->Trace(default_style_); visitor->Trace(default_quirks_style_); @@ -246,7 +228,6 @@ visitor->Trace(mathml_style_sheet_); visitor->Trace(media_controls_style_sheet_); visitor->Trace(fullscreen_style_sheet_); - visitor->Trace(touchless_style_sheet_); } } // namespace blink
diff --git a/third_party/blink/renderer/core/css/css_default_style_sheets.h b/third_party/blink/renderer/core/css/css_default_style_sheets.h index bcb7fc8..bc67b93 100644 --- a/third_party/blink/renderer/core/css/css_default_style_sheets.h +++ b/third_party/blink/renderer/core/css/css_default_style_sheets.h
@@ -46,7 +46,6 @@ bool EnsureDefaultStyleSheetsForElement(const Element&); void EnsureDefaultStyleSheetForFullscreen(); - void EnsureDefaultStyleSheetForTouchless(); RuleSet* DefaultStyle() { return default_style_.Get(); } RuleSet* DefaultQuirksStyle() { return default_quirks_style_.Get(); } @@ -105,7 +104,6 @@ Member<StyleSheetContents> mathml_style_sheet_; Member<StyleSheetContents> media_controls_style_sheet_; Member<StyleSheetContents> fullscreen_style_sheet_; - Member<StyleSheetContents> touchless_style_sheet_; std::unique_ptr<UAStyleSheetLoader> media_controls_style_sheet_loader_; DISALLOW_COPY_AND_ASSIGN(CSSDefaultStyleSheets);
diff --git a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc index ff1aea4..97be232 100644 --- a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc +++ b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
@@ -122,8 +122,8 @@ } static bool IsOutermostSVGElement(const Element* element) { - return element && element->IsSVGElement() && - ToSVGElement(*element).IsOutermostSVGSVGElement(); + auto* svg_element = DynamicTo<SVGElement>(element); + return svg_element && svg_element->IsOutermostSVGSVGElement(); } static bool IsAtUAShadowBoundary(const Element* element) { @@ -589,10 +589,10 @@ AdjustStyleForEditing(style); bool is_svg_root = false; - bool is_svg_element = element && element->IsSVGElement(); + auto* svg_element = DynamicTo<SVGElement>(element); - if (is_svg_element) { - is_svg_root = ToSVGElement(element)->IsOutermostSVGSVGElement(); + if (svg_element) { + is_svg_root = svg_element->IsOutermostSVGSVGElement(); if (!is_svg_root) { // Only the root <svg> element in an SVG document fragment tree honors css // position.
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/third_party/blink/renderer/core/css/resolver/style_resolver.cc index bb87656..930ad0d 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -595,10 +595,11 @@ } // Now check SMIL animation override style. - if (include_smil_properties && state.GetElement()->IsSVGElement()) + auto* svg_element = DynamicTo<SVGElement>(state.GetElement()); + if (include_smil_properties && svg_element) { collector.AddElementStyleProperties( - ToSVGElement(state.GetElement())->AnimatedSMILStyleProperties(), - false /* isCacheable */); + svg_element->AnimatedSMILStyleProperties(), false /* isCacheable */); + } } collector.FinishAddingAuthorRulesForTreeScope();
diff --git a/third_party/blink/renderer/core/css/touchless.css b/third_party/blink/renderer/core/css/touchless.css index 76cd8bc..a0013b0 100644 --- a/third_party/blink/renderer/core/css/touchless.css +++ b/third_party/blink/renderer/core/css/touchless.css
@@ -29,7 +29,3 @@ body { user-select: none !important; } - -* { - -webkit-user-drag: none !important; -}
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index 7590375..6bd9009 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -554,7 +554,7 @@ SynchronizeStyleAttributeInternal(); } if (GetElementData()->animated_svg_attributes_are_dirty_) - ToSVGElement(this)->SynchronizeAnimatedSVGAttribute(AnyQName()); + To<SVGElement>(this)->SynchronizeAnimatedSVGAttribute(AnyQName()); } inline void Element::SynchronizeAttribute(const QualifiedName& name) const { @@ -569,7 +569,7 @@ if (UNLIKELY(GetElementData()->animated_svg_attributes_are_dirty_)) { // See comment in the AtomicString version of SynchronizeAttribute() // also. - ToSVGElement(this)->SynchronizeAnimatedSVGAttribute(name); + To<SVGElement>(this)->SynchronizeAnimatedSVGAttribute(name); } } @@ -597,7 +597,7 @@ // AnyQName(). This means that even if Element::SynchronizeAttribute() // is called on all attributes, animated_svg_attributes_are_dirty_ remains // true. - ToSVGElement(this)->SynchronizeAnimatedSVGAttribute( + To<SVGElement>(this)->SynchronizeAnimatedSVGAttribute( QualifiedName(g_null_atom, local_name, g_null_atom)); } } @@ -1223,11 +1223,12 @@ // cannot use LocalToAbsoluteQuad directly with ObjectBoundingBox which is // SVG coordinates and not HTML coordinates. Instead, use the AbsoluteQuads // codepath below. - if (IsSVGElement() && GetLayoutObject() && + auto* svg_element = DynamicTo<SVGElement>(this); + if (svg_element && GetLayoutObject() && !GetLayoutObject()->IsSVGForeignObject()) { // Get the bounding rectangle from the SVG model. // TODO(pdr): This should include stroke. - if (ToSVGElement(this)->IsSVGGraphicsElement()) + if (svg_element->IsSVGGraphicsElement()) quads.push_back(GetLayoutObject()->LocalToAbsoluteQuad( GetLayoutObject()->ObjectBoundingBox())); } else { @@ -1293,13 +1294,14 @@ // cannot use LocalToAbsoluteQuad directly with ObjectBoundingBox which is // SVG coordinates and not HTML coordinates. Instead, use the AbsoluteQuads // codepath below. - if (IsSVGElement() && !element_layout_object->IsSVGRoot() && + auto* svg_element = DynamicTo<SVGElement>(this); + if (svg_element && !element_layout_object->IsSVGRoot() && !element_layout_object->IsSVGForeignObject()) { // Get the bounding rectangle from the SVG model. // TODO(pdr): ObjectBoundingBox does not include stroke and the spec is not // clear (see: https://github.com/w3c/svgwg/issues/339, crbug.com/529734). // If stroke is desired, we can update this to use AbsoluteQuads, below. - if (ToSVGElement(this)->IsSVGGraphicsElement()) + if (svg_element->IsSVGGraphicsElement()) quads.push_back(element_layout_object->LocalToAbsoluteQuad( element_layout_object->ObjectBoundingBox())); return; @@ -4148,8 +4150,8 @@ bool Element::ShouldStoreComputedStyle(const ComputedStyle& style) const { if (LayoutObjectIsNeeded(style)) return true; - if (IsSVGElement()) { - if (!ToSVGElement(*this).HasSVGParent()) + if (auto* svg_element = DynamicTo<SVGElement>(this)) { + if (!svg_element->HasSVGParent()) return false; if (IsSVGStopElement(*this)) return true; @@ -4677,8 +4679,8 @@ if (name == html_names::kStyleAttr) return false; - if (IsSVGElement()) - return !ToSVGElement(this)->IsAnimatableAttribute(name); + if (auto* svg_element = DynamicTo<SVGElement>(this)) + return !svg_element->IsAnimatableAttribute(name); return true; }
diff --git a/third_party/blink/renderer/core/dom/events/event.cc b/third_party/blink/renderer/core/dom/events/event.cc index 21f83b3..9d9d41c7 100644 --- a/third_party/blink/renderer/core/dom/events/event.cc +++ b/third_party/blink/renderer/core/dom/events/event.cc
@@ -359,9 +359,9 @@ EventTarget* Event::currentTarget() const { if (!current_target_) return nullptr; - Node* node = current_target_->ToNode(); - if (node && node->IsSVGElement()) { - if (SVGElement* svg_element = ToSVGElement(node)->CorrespondingElement()) + if (auto* curr_svg_element = + DynamicTo<SVGElement>(current_target_->ToNode())) { + if (SVGElement* svg_element = curr_svg_element->CorrespondingElement()) return svg_element; } return current_target_.Get();
diff --git a/third_party/blink/renderer/core/dom/node.cc b/third_party/blink/renderer/core/dom/node.cc index 07f69ee..751eaf1 100644 --- a/third_party/blink/renderer/core/dom/node.cc +++ b/third_party/blink/renderer/core/dom/node.cc
@@ -1213,8 +1213,8 @@ if (IsElementNode() && HasRareData()) ToElement(*this).SetAnimationStyleChange(false); - if (IsSVGElement()) - ToSVGElement(this)->SetNeedsStyleRecalcForInstances(change_type, reason); + if (auto* svg_element = DynamicTo<SVGElement>(this)) + svg_element->SetNeedsStyleRecalcForInstances(change_type, reason); } void Node::ClearNeedsStyleRecalc() {
diff --git a/third_party/blink/renderer/core/dom/visited_link_state.cc b/third_party/blink/renderer/core/dom/visited_link_state.cc index 211ab8a..9436255 100644 --- a/third_party/blink/renderer/core/dom/visited_link_state.cc +++ b/third_party/blink/renderer/core/dom/visited_link_state.cc
@@ -45,7 +45,7 @@ if (element.IsHTMLElement()) return element.FastGetAttribute(html_names::kHrefAttr); DCHECK(element.IsSVGElement()); - return SVGURIReference::LegacyHrefString(ToSVGElement(element)); + return SVGURIReference::LegacyHrefString(To<SVGElement>(element)); } static inline LinkHash LinkHashForElement(
diff --git a/third_party/blink/renderer/core/editing/editing_utilities.cc b/third_party/blink/renderer/core/editing/editing_utilities.cc index bdb50218..5e72d44 100644 --- a/third_party/blink/renderer/core/editing/editing_utilities.cc +++ b/third_party/blink/renderer/core/editing/editing_utilities.cc
@@ -1698,7 +1698,7 @@ if (IsHTMLImageElement(node) || IsHTMLInputElement(node)) return To<HTMLElement>(node).getAttribute(kSrcAttr); if (IsSVGImageElement(node)) - return ToSVGElement(node).ImageSourceURL(); + return To<SVGElement>(node).ImageSourceURL(); if (IsHTMLEmbedElement(node) || IsHTMLObjectElement(node) || IsHTMLCanvasElement(node)) return To<HTMLElement>(node).ImageSourceURL();
diff --git a/third_party/blink/renderer/core/events/mouse_event.cc b/third_party/blink/renderer/core/events/mouse_event.cc index 77253a8..a074002e5 100644 --- a/third_party/blink/renderer/core/events/mouse_event.cc +++ b/third_party/blink/renderer/core/events/mouse_event.cc
@@ -81,9 +81,9 @@ layout_object = layout_object->Parent(); // Update the target node to point to the SVG root. target_node = layout_object->GetNode(); + auto* svg_element = DynamicTo<SVGElement>(target_node); DCHECK(!target_node || - (target_node->IsSVGElement() && - ToSVGElement(*target_node).IsOutermostSVGSVGElement())); + (svg_element && svg_element->IsOutermostSVGSVGElement())); return layout_object; }
diff --git a/third_party/blink/renderer/core/exported/web_document_loader_impl.cc b/third_party/blink/renderer/core/exported/web_document_loader_impl.cc index ba5416f..9f45470 100644 --- a/third_party/blink/renderer/core/exported/web_document_loader_impl.cc +++ b/third_party/blink/renderer/core/exported/web_document_loader_impl.cc
@@ -137,11 +137,6 @@ extra_data_.reset(); } -void WebDocumentLoaderImpl::CleanupWithoutStart() { - DocumentLoader::CleanupWithoutStart(); - extra_data_.reset(); -} - void WebDocumentLoaderImpl::SetSubresourceFilter( WebDocumentSubresourceFilter* subresource_filter) { DocumentLoader::SetSubresourceFilter(SubresourceFilter::Create(
diff --git a/third_party/blink/renderer/core/exported/web_document_loader_impl.h b/third_party/blink/renderer/core/exported/web_document_loader_impl.h index 5404642..17a17c7a 100644 --- a/third_party/blink/renderer/core/exported/web_document_loader_impl.h +++ b/third_party/blink/renderer/core/exported/web_document_loader_impl.h
@@ -90,7 +90,6 @@ private: ~WebDocumentLoaderImpl() override; void DetachFromFrame(bool flush_microtask_queue) override; - void CleanupWithoutStart() override; // Mutable because the const getters will magically sync these to the // latest version from WebKit.
diff --git a/third_party/blink/renderer/core/exported/web_render_theme.cc b/third_party/blink/renderer/core/exported/web_render_theme.cc index 4213986..997727d 100644 --- a/third_party/blink/renderer/core/exported/web_render_theme.cc +++ b/third_party/blink/renderer/core/exported/web_render_theme.cc
@@ -44,4 +44,13 @@ LayoutTheme::GetTheme().SetCustomFocusRingColor(color); } +void SetSelectionColors(unsigned active_background_color, + unsigned active_foreground_color, + unsigned inactive_background_color, + unsigned inactive_foreground_color) { + LayoutTheme::GetTheme().SetSelectionColors( + active_background_color, active_foreground_color, + inactive_background_color, inactive_foreground_color); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc index 65f3f4b..d4abf56 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.cc +++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -165,10 +165,6 @@ #include "third_party/blink/renderer/platform/wtf/time.h" #include "ui/gfx/skia_util.h" -#if defined(WTF_USE_DEFAULT_RENDER_THEME) -#include "third_party/blink/renderer/core/layout/layout_theme_default.h" -#endif - // Get rid of WTF's pow define so we can use std::pow. #undef pow #include <cmath> // for std::pow @@ -3016,18 +3012,6 @@ AsView().page->SetOpenedByDOM(); } -void WebViewImpl::SetSelectionColors(unsigned active_background_color, - unsigned active_foreground_color, - unsigned inactive_background_color, - unsigned inactive_foreground_color) { -#if defined(WTF_USE_DEFAULT_RENDER_THEME) - LayoutThemeDefault::SetSelectionColors( - active_background_color, active_foreground_color, - inactive_background_color, inactive_foreground_color); - LayoutTheme::GetTheme().PlatformColorsDidChange(); -#endif -} - void WebViewImpl::DidCommitLoad(bool is_new_navigation, bool is_navigation_within_page) { if (!is_navigation_within_page) {
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.h b/third_party/blink/renderer/core/exported/web_view_impl.h index aaa1746..f7234c6 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.h +++ b/third_party/blink/renderer/core/exported/web_view_impl.h
@@ -181,10 +181,6 @@ uint64_t CreateUniqueIdentifierForRequest() override; void EnableDeviceEmulation(const WebDeviceEmulationParams&) override; void DisableDeviceEmulation() override; - void SetSelectionColors(unsigned active_background_color, - unsigned active_foreground_color, - unsigned inactive_background_color, - unsigned inactive_foreground_color) override; void PerformCustomContextMenuAction(unsigned action) override; void DidCloseContextMenu() override; void CancelPagePopup() override;
diff --git a/third_party/blink/renderer/core/html/media/video_wake_lock_test.cc b/third_party/blink/renderer/core/html/media/video_wake_lock_test.cc index a0563ea..ca56c94 100644 --- a/third_party/blink/renderer/core/html/media/video_wake_lock_test.cc +++ b/third_party/blink/renderer/core/html/media/video_wake_lock_test.cc
@@ -17,10 +17,32 @@ namespace blink { +// The VideoWakeLockPictureInPictureSession implements a PictureInPicture +// session in the same process as the test and guarantees that the callbacks are +// called in order for the events to be fired. +class VideoWakeLockPictureInPictureSession + : public mojom::blink::PictureInPictureSession { + public: + explicit VideoWakeLockPictureInPictureSession( + mojo::InterfaceRequest<mojom::blink::PictureInPictureSession> request) + : binding_(this, std::move(request)) {} + ~VideoWakeLockPictureInPictureSession() override = default; + + void Stop(StopCallback callback) final { std::move(callback).Run(); } + + void Update(uint32_t player_id, + const base::Optional<viz::SurfaceId>&, + const blink::WebSize&, + bool show_play_pause_button, + bool show_mute_button) final {} + + private: + mojo::Binding<mojom::blink::PictureInPictureSession> binding_; +}; + // The VideoWakeLockPictureInPictureService implements the PictureInPicture // service in the same process as the test and guarantees that the callbacks are -// called in order for the events to be fired. set_run_loop() MUST be called -// before each attempt to enter/leave Picture-in-Picture. +// called in order for the events to be fired. class VideoWakeLockPictureInPictureService : public mojom::blink::PictureInPictureService { public: @@ -37,23 +59,18 @@ const blink::WebSize&, bool, bool, + mojom::blink::PictureInPictureSessionObserverPtr, StartSessionCallback callback) final { - std::move(callback).Run(WebSize()); - } + mojom::blink::PictureInPictureSessionPtr session_ptr; + session_.reset(new VideoWakeLockPictureInPictureSession( + mojo::MakeRequest(&session_ptr))); - void EndSession(EndSessionCallback callback) final { - std::move(callback).Run(); + std::move(callback).Run(std::move(session_ptr), WebSize()); } - void UpdateSession(uint32_t, - const base::Optional<viz::SurfaceId>&, - const blink::WebSize&, - bool, - bool) final {} - void SetDelegate(mojom::blink::PictureInPictureDelegatePtr) final {} - private: mojo::Binding<mojom::blink::PictureInPictureService> binding_; + std::unique_ptr<VideoWakeLockPictureInPictureSession> session_; }; class VideoWakeLockMediaPlayer final : public EmptyWebMediaPlayer {
diff --git a/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc b/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc index fa842b5..c93bb13 100644 --- a/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc
@@ -759,8 +759,8 @@ kAllowScriptingContent); } else { Element* contextElement = nullptr; - if (element->IsSVGElement()) - contextElement = ToSVGElement(element)->ownerSVGElement(); + if (auto* svg_element = DynamicTo<SVGElement>(element)) + contextElement = svg_element->ownerSVGElement(); fragment->ParseXML(markup, contextElement, kAllowScriptingContent); }
diff --git a/third_party/blink/renderer/core/layout/layout_text.cc b/third_party/blink/renderer/core/layout/layout_text.cc index 6d3fac4a..b9cc67b 100644 --- a/third_party/blink/renderer/core/layout/layout_text.cc +++ b/third_party/blink/renderer/core/layout/layout_text.cc
@@ -1873,6 +1873,11 @@ if (text_autosizer) text_autosizer->Record(this); + if (HasNodeHolder()) { + if (auto* content_capture_manager = GetContentCaptureManager()) + content_capture_manager->OnNodeTextChanged(node_holder_); + } + valid_ng_items_ = false; SetNeedsCollectInlines(); }
diff --git a/third_party/blink/renderer/core/layout/layout_theme.h b/third_party/blink/renderer/core/layout/layout_theme.h index 50827fd..7a20c4d8 100644 --- a/third_party/blink/renderer/core/layout/layout_theme.h +++ b/third_party/blink/renderer/core/layout/layout_theme.h
@@ -142,6 +142,10 @@ Color InactiveSelectionBackgroundColor() const; Color ActiveSelectionForegroundColor() const; Color InactiveSelectionForegroundColor() const; + virtual void SetSelectionColors(unsigned active_background_color, + unsigned active_foreground_color, + unsigned inactive_background_color, + unsigned inactive_foreground_color) {} // List box selection colors Color ActiveListBoxSelectionBackgroundColor() const;
diff --git a/third_party/blink/renderer/core/layout/layout_theme_default.cc b/third_party/blink/renderer/core/layout/layout_theme_default.cc index 8c7e31d..c29363d6 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_default.cc +++ b/third_party/blink/renderer/core/layout/layout_theme_default.cc
@@ -187,6 +187,7 @@ active_selection_foreground_color_ = active_foreground_color; inactive_selection_background_color_ = inactive_background_color; inactive_selection_foreground_color_ = inactive_foreground_color; + PlatformColorsDidChange(); } void LayoutThemeDefault::SetCheckboxSize(ComputedStyle& style) const {
diff --git a/third_party/blink/renderer/core/layout/layout_theme_default.h b/third_party/blink/renderer/core/layout/layout_theme_default.h index fcbd053..10150906 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_default.h +++ b/third_party/blink/renderer/core/layout/layout_theme_default.h
@@ -81,6 +81,10 @@ // when hovered. bool SupportsHover(const ComputedStyle&) const final; + void SetSelectionColors(unsigned active_background_color, + unsigned active_foreground_color, + unsigned inactive_background_color, + unsigned inactive_foreground_color) override; Color PlatformFocusRingColor() const override; // System fonts. @@ -124,11 +128,6 @@ float ClampedMenuListArrowPaddingSize(const ChromeClient*, const ComputedStyle&) const; - static void SetSelectionColors(unsigned active_background_color, - unsigned active_foreground_color, - unsigned inactive_background_color, - unsigned inactive_foreground_color); - protected: LayoutThemeDefault(); ~LayoutThemeDefault() override;
diff --git a/third_party/blink/renderer/core/layout/layout_theme_touchless.cc b/third_party/blink/renderer/core/layout/layout_theme_touchless.cc index 9be8371..27f1f67 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_touchless.cc +++ b/third_party/blink/renderer/core/layout/layout_theme_touchless.cc
@@ -4,6 +4,8 @@ #include "third_party/blink/renderer/core/layout/layout_theme_touchless.h" +#include "third_party/blink/renderer/platform/data_resource_helper.h" + namespace blink { scoped_refptr<LayoutTheme> LayoutThemeTouchless::Create() { @@ -18,6 +20,11 @@ LayoutThemeTouchless::~LayoutThemeTouchless() {} +String LayoutThemeTouchless::ExtraDefaultStyleSheet() { + return LayoutThemeMobile::ExtraDefaultStyleSheet() + + GetDataResourceAsASCIIString("touchless.css"); +} + bool LayoutThemeTouchless::IsFocusRingOutset() const { return true; }
diff --git a/third_party/blink/renderer/core/layout/layout_theme_touchless.h b/third_party/blink/renderer/core/layout/layout_theme_touchless.h index ff63ccc..8342879 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_touchless.h +++ b/third_party/blink/renderer/core/layout/layout_theme_touchless.h
@@ -14,6 +14,7 @@ static scoped_refptr<LayoutTheme> Create(); bool DelegatesMenuListRendering() const override { return true; } + String ExtraDefaultStyleSheet() override; bool IsFocusRingOutset() const override; private:
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc index 1f11d8d9..9a1a2112 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc
@@ -435,7 +435,8 @@ box_data_list_[box_data_index - 1].fragmented_box_data_index = box_data_list_.size(); // Do not use `emplace_back()` here because adding to |box_data_list_| may - // reallocate the buffer. Create a new instance and |push_back()| instead. + // reallocate the buffer, but the `BoxData` ctor must run before the + // reallocation. Create a new instance and |push_back()| instead. BoxData fragmented_box_data(box_data_list_[box_data_index - 1], start_index, index); box_data_list_.push_back(fragmented_box_data);
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_block.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_block.cc index 6e203c1..f8917ff5 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_block.cc +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_block.cc
@@ -37,7 +37,7 @@ : LayoutBlockFlow(element) {} SVGElement* LayoutSVGBlock::GetElement() const { - return ToSVGElement(LayoutObject::GetNode()); + return To<SVGElement>(LayoutObject::GetNode()); } void LayoutSVGBlock::AbsoluteRects(Vector<IntRect>&, const LayoutPoint&) const {
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc index 1addc04..d00b198 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc
@@ -120,8 +120,8 @@ void LayoutSVGInline::WillBeDestroyed() { SVGResourcesCache::ClientDestroyed(*this); - SVGResources::ClearClipPathFilterMask(ToSVGElement(*GetNode()), Style()); - SVGResources::ClearPaints(ToSVGElement(*GetNode()), Style()); + SVGResources::ClearClipPathFilterMask(To<SVGElement>(*GetNode()), Style()); + SVGResources::ClearPaints(To<SVGElement>(*GetNode()), Style()); LayoutInline::WillBeDestroyed(); } @@ -136,9 +136,9 @@ SetNeedsBoundariesUpdate(); LayoutInline::StyleDidChange(diff, old_style); - SVGResources::UpdateClipPathFilterMask(ToSVGElement(*GetNode()), old_style, + SVGResources::UpdateClipPathFilterMask(To<SVGElement>(*GetNode()), old_style, StyleRef()); - SVGResources::UpdatePaints(ToSVGElement(*GetNode()), old_style, StyleRef()); + SVGResources::UpdatePaints(To<SVGElement>(*GetNode()), old_style, StyleRef()); SVGResourcesCache::ClientStyleChanged(*this, diff, StyleRef()); }
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.h b/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.h index 3656cd2c..8cbd42e1 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.h +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.h
@@ -74,7 +74,7 @@ void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override; SVGElement* GetElement() const { - return ToSVGElement(LayoutObject::GetNode()); + return To<SVGElement>(LayoutObject::GetNode()); } bool IsOfType(LayoutObjectType type) const override {
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.cc index 2fc5cec..ce06ebc 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.cc +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.cc
@@ -148,13 +148,13 @@ static inline void RemoveFromCacheAndInvalidateDependencies( LayoutObject& object, bool needs_layout) { - if (!object.GetNode() || !object.GetNode()->IsSVGElement()) + auto* element = DynamicTo<SVGElement>(object.GetNode()); + if (!element) return; - SVGElement& element = ToSVGElement(*object.GetNode()); if (SVGResources* resources = SVGResourcesCache::CachedResourcesForLayoutObject(object)) { - SVGResourceClient* client = element.GetSVGResourceClient(); + SVGResourceClient* client = element->GetSVGResourceClient(); if (InvalidationModeMask invalidation_mask = resources->RemoveClientFromCacheAffectingObjectBounds(*client)) { LayoutSVGResourceContainer::MarkClientForInvalidation(object, @@ -162,7 +162,7 @@ } } - element.NotifyIncomingReferences([needs_layout](SVGElement& element) { + element->NotifyIncomingReferences([needs_layout](SVGElement& element) { DCHECK(element.GetLayoutObject()); LayoutSVGResourceContainer::MarkForLayoutAndParentResourceInvalidation( *element.GetLayoutObject(), needs_layout);
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_transformable_container.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_transformable_container.cc index 9859027..92f8d55 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_transformable_container.cc +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_transformable_container.cc
@@ -35,7 +35,8 @@ static bool HasValidPredecessor(const Node* node) { DCHECK(node); for (node = node->previousSibling(); node; node = node->previousSibling()) { - if (node->IsSVGElement() && ToSVGElement(node)->IsValid()) + auto* svg_element = DynamicTo<SVGElement>(node); + if (svg_element && svg_element->IsValid()) return true; } return false; @@ -48,8 +49,8 @@ Node* child_node = child->GetNode(); if (IsSVGSwitchElement(*GetElement())) { // Reject non-SVG/non-valid elements. - if (!child_node || !child_node->IsSVGElement() || - !ToSVGElement(child_node)->IsValid()) { + auto* svg_element = DynamicTo<SVGElement>(child_node); + if (!svg_element || !svg_element->IsValid()) { return false; } // Reject this child if it isn't the first valid node.
diff --git a/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc b/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc index fce9b32..7e4034c 100644 --- a/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc +++ b/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc
@@ -328,9 +328,7 @@ if (layout_size_changed) { // When selfNeedsLayout is false and the layout size changed, we have to // check whether this child uses relative lengths - if (SVGElement* element = child->GetNode()->IsSVGElement() - ? ToSVGElement(child->GetNode()) - : nullptr) { + if (auto* element = DynamicTo<SVGElement>(child->GetNode())) { if (element->HasRelativeLengths()) { // FIXME: this should be done on invalidation, not during layout. // When the layout size changed and when using relative values tell @@ -477,7 +475,7 @@ const SVGComputedStyle& svg_style = style.SvgStyle(); - SVGLengthContext length_context(ToSVGElement(object.GetNode())); + SVGLengthContext length_context(To<SVGElement>(object.GetNode())); stroke_data.SetThickness( length_context.ValueForLength(svg_style.StrokeWidth())); stroke_data.SetLineCap(svg_style.CapStyle());
diff --git a/third_party/blink/renderer/core/layout/svg/svg_resources.cc b/third_party/blink/renderer/core/layout/svg/svg_resources.cc index 7a84760..49bb4a5 100644 --- a/third_party/blink/renderer/core/layout/svg/svg_resources.cc +++ b/third_party/blink/renderer/core/layout/svg/svg_resources.cc
@@ -48,7 +48,7 @@ SVGResources::SVGResources() : linked_resource_(nullptr) {} SVGResourceClient* SVGResources::GetClient(const LayoutObject& object) { - return ToSVGElement(object.GetNode())->GetSVGResourceClient(); + return To<SVGElement>(object.GetNode())->GetSVGResourceClient(); } static HashSet<AtomicString>& ClipperFilterMaskerTags() { @@ -159,7 +159,7 @@ DCHECK(node); SECURITY_DCHECK(node->IsSVGElement()); - SVGElement& element = ToSVGElement(*node); + auto& element = To<SVGElement>(*node); const AtomicString& tag_name = element.localName(); DCHECK(!tag_name.IsNull());
diff --git a/third_party/blink/renderer/core/layout/svg/svg_resources_cache.cc b/third_party/blink/renderer/core/layout/svg/svg_resources_cache.cc index 37932071f..30fc8f8 100644 --- a/third_party/blink/renderer/core/layout/svg/svg_resources_cache.cc +++ b/third_party/blink/renderer/core/layout/svg/svg_resources_cache.cc
@@ -217,7 +217,7 @@ if (styles_are_equal_) return; DCHECK(LayoutObjectCanHaveResources(layout_object_)); - SVGElement& element = ToSVGElement(*layout_object_.GetNode()); + auto& element = To<SVGElement>(*layout_object_.GetNode()); SVGResources::UpdatePaints(element, nullptr, temporary_style_); SwitchTo(temporary_style); } @@ -225,7 +225,7 @@ SVGResourcesCache::TemporaryStyleScope::~TemporaryStyleScope() { if (styles_are_equal_) return; - SVGElement& element = ToSVGElement(*layout_object_.GetNode()); + auto& element = To<SVGElement>(*layout_object_.GetNode()); SVGResources::ClearPaints(element, &temporary_style_); SwitchTo(original_style_); }
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc index 992bd56..2a84219 100644 --- a/third_party/blink/renderer/core/loader/document_loader.cc +++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -75,7 +75,6 @@ #include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h" #include "third_party/blink/renderer/core/page/frame_tree.h" #include "third_party/blink/renderer/core/page/page.h" -#include "third_party/blink/renderer/core/page/plugin_data.h" #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/core/timing/dom_window_performance.h" #include "third_party/blink/renderer/core/timing/window_performance.h" @@ -99,7 +98,6 @@ #include "third_party/blink/renderer/platform/network/encoded_form_data.h" #include "third_party/blink/renderer/platform/network/http_names.h" #include "third_party/blink/renderer/platform/network/http_parsers.h" -#include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h" #include "third_party/blink/renderer/platform/network/network_utils.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" @@ -168,45 +166,6 @@ error_code_ = params_->error_code; previews_state_ = params_->previews_state; - // See WebNavigationParams for special case explanations. - if (!params_->is_static_data && url_.IsAboutSrcdocURL()) { - loading_srcdoc_ = true; - // TODO(dgozman): instead of reaching to the owner here, we could instead: - // - grab the "srcdoc" value when starting a navigation right in the owner; - // - pass it around through BeginNavigation to CommitNavigation as |data|; - // - use it here instead of re-reading from the owner. - // This way we will get rid of extra dependency between starting and - // committing navigation. - CString encoded_srcdoc; - HTMLFrameOwnerElement* owner_element = frame_->DeprecatedLocalOwner(); - if (!IsHTMLIFrameElement(owner_element) || - !owner_element->FastHasAttribute(html_names::kSrcdocAttr)) { - // Cannot retrieve srcdoc content anymore (perhaps, the attribute was - // cleared) - load empty instead. - } else { - String srcdoc = owner_element->FastGetAttribute(html_names::kSrcdocAttr); - DCHECK(!srcdoc.IsNull()); - encoded_srcdoc = srcdoc.Utf8(); - } - WebNavigationParams::FillStaticResponse( - params_.get(), "text/html", "UTF-8", - base::make_span(encoded_srcdoc.data(), encoded_srcdoc.length())); - } else if (!params_->is_static_data && archive_) { - // If we have an archive loaded in some ancestor frame, we should - // retrieve document content from that archive. This is different from - // loading an archive into this frame, which will be handled separately - // once we load the body and parse it as an archive. - params_->body_loader.reset(); - ArchiveResource* archive_resource = archive_->SubresourceForURL(url_); - if (archive_resource) { - SharedBuffer* archive_data = archive_resource->Data(); - WebNavigationParams::FillStaticResponse( - params_.get(), archive_resource->MimeType(), - archive_resource->TextEncoding(), - base::make_span(archive_data->Data(), archive_data->size())); - } - } - WebNavigationTimings& timings = params_->navigation_timings; if (!timings.input_start.is_null()) document_load_timing_.SetInputStart(timings.input_start); @@ -246,6 +205,7 @@ loading_url_as_empty_document_ = !params_->is_static_data && WillLoadUrlAsEmpty(url_); + loading_srcdoc_ = url_.IsAboutSrcdocURL(); if (!loading_url_as_empty_document_) { content_security_policy_ = @@ -739,14 +699,6 @@ // in embedder to fix https://crbug.com/671276. } -static bool CanShowMIMEType(const String& mime_type, LocalFrame* frame) { - if (MIMETypeRegistry::IsSupportedMIMEType(mime_type)) - return true; - PluginData* plugin_data = frame->GetPluginData(); - return !mime_type.IsEmpty() && plugin_data && - plugin_data->SupportsMimeType(mime_type); -} - bool DocumentLoader::ShouldReportTimingInfoToParent() { DCHECK(frame_); // <iframe>s should report the initial navigation requested by the parent @@ -1128,13 +1080,6 @@ frame_ = nullptr; } -void DocumentLoader::CleanupWithoutStart() { - DCHECK(!application_cache_host_); - frame_ = nullptr; - params_ = nullptr; - state_ = kSentDidFinishLoad; -} - const KURL& DocumentLoader::UnreachableURL() const { return unreachable_url_; } @@ -1167,38 +1112,6 @@ FinishedLoading(CurrentTimeTicks()); } -bool DocumentLoader::PrepareForLoad() { - if (loading_url_as_empty_document_) - return true; - - if (!params_->body_loader) { - // TODO(dgozman): we should try to get rid of this case. - return false; - } - - if (params_->is_static_data) - return true; - - int status_code = response_.HttpStatusCode(); - if (status_code == 204 || status_code == 205) { - // The server does not want us to replace the page contents. - return false; - } - - if (IsContentDispositionAttachment( - response_.HttpHeaderField(http_names::kContentDisposition))) { - // The server wants us to download instead of replacing the page contents. - // Downloading is handled by the embedder, but we still get the initial - // response so that we can ignore it and clean up properly. - return false; - } - - if (!CanShowMIMEType(response_.MimeType(), frame_)) - return false; - - return true; -} - void DocumentLoader::StartLoading() { probe::LifecycleEvent(frame_, this, "init", CurrentTimeTicksInSeconds()); StartLoadingInternal();
diff --git a/third_party/blink/renderer/core/loader/document_loader.h b/third_party/blink/renderer/core/loader/document_loader.h index b6bf3825..d916a14f 100644 --- a/third_party/blink/renderer/core/loader/document_loader.h +++ b/third_party/blink/renderer/core/loader/document_loader.h
@@ -110,10 +110,6 @@ virtual void DetachFromFrame(bool flush_microtask_queue); - // Called when we did not start the load, before abandoning this - // DocumentLoader. - virtual void CleanupWithoutStart(); - uint64_t MainResourceIdentifier() const; void ReplaceDocumentWhileExecutingJavaScriptURL(const KURL&, @@ -181,10 +177,6 @@ void SetItemForHistoryNavigation(HistoryItem* item) { history_item_ = item; } HistoryItem* GetHistoryItem() const { return history_item_; } - // Returns whether the load can proceed. If not, the loader will be detached - // already. - bool PrepareForLoad(); - void StartLoading(); void StopLoading();
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc index 479a445..b209c2b4 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.cc +++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -80,6 +80,7 @@ #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/frame_tree.h" #include "third_party/blink/renderer/core/page/page.h" +#include "third_party/blink/renderer/core/page/plugin_data.h" #include "third_party/blink/renderer/core/page/plugin_script_forbidden_scope.h" #include "third_party/blink/renderer/core/page/scrolling/fragment_anchor.h" #include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h" @@ -99,7 +100,10 @@ #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_request.h" +#include "third_party/blink/renderer/platform/mhtml/archive_resource.h" +#include "third_party/blink/renderer/platform/mhtml/mhtml_archive.h" #include "third_party/blink/renderer/platform/network/http_parsers.h" +#include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h" #include "third_party/blink/renderer/platform/network/network_utils.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" @@ -197,8 +201,6 @@ provisional_document_loader_ = Client()->CreateDocumentLoader( frame_, kWebNavigationTypeOther, std::move(navigation_params), nullptr /* extra_data */); - bool success = provisional_document_loader_->PrepareForLoad(); - DCHECK(success); provisional_document_loader_->StartLoading(); frame_->GetDocument()->CancelParsing(); @@ -796,6 +798,84 @@ std::move(navigation_initiator)); } +static void FillStaticResponseIfNeeded(WebNavigationParams* params, + LocalFrame* frame) { + if (params->is_static_data) + return; + const KURL& url = params->url; + // See WebNavigationParams for special case explanations. + if (url.IsAboutSrcdocURL()) { + // TODO(dgozman): instead of reaching to the owner here, we could instead: + // - grab the "srcdoc" value when starting a navigation right in the owner; + // - pass it around through BeginNavigation to CommitNavigation as |data|; + // - use it here instead of re-reading from the owner. + // This way we will get rid of extra dependency between starting and + // committing navigation. + CString encoded_srcdoc; + HTMLFrameOwnerElement* owner_element = frame->DeprecatedLocalOwner(); + if (!IsHTMLIFrameElement(owner_element) || + !owner_element->FastHasAttribute(html_names::kSrcdocAttr)) { + // Cannot retrieve srcdoc content anymore (perhaps, the attribute was + // cleared) - load empty instead. + } else { + String srcdoc = owner_element->FastGetAttribute(html_names::kSrcdocAttr); + DCHECK(!srcdoc.IsNull()); + encoded_srcdoc = srcdoc.Utf8(); + } + WebNavigationParams::FillStaticResponse( + params, "text/html", "UTF-8", + base::make_span(encoded_srcdoc.data(), encoded_srcdoc.length())); + return; + } + + MHTMLArchive* archive = nullptr; + if (auto* parent = DynamicTo<LocalFrame>(frame->Tree().Parent())) + archive = parent->Loader().GetDocumentLoader()->Archive(); + if (archive) { + // If we have an archive loaded in some ancestor frame, we should + // retrieve document content from that archive. This is different from + // loading an archive into this frame, which will be handled separately + // once we load the body and parse it as an archive. + params->body_loader.reset(); + ArchiveResource* archive_resource = archive->SubresourceForURL(url); + if (archive_resource) { + SharedBuffer* archive_data = archive_resource->Data(); + WebNavigationParams::FillStaticResponse( + params, archive_resource->MimeType(), + archive_resource->TextEncoding(), + base::make_span(archive_data->Data(), archive_data->size())); + } + } +} + +static bool ShouldNavigate(WebNavigationParams* params, LocalFrame* frame) { + if (params->is_static_data) + return true; + if (DocumentLoader::WillLoadUrlAsEmpty(params->url)) + return true; + + int status_code = params->response.HttpStatusCode(); + if (status_code == 204 || status_code == 205) { + // The server does not want us to replace the page contents. + return false; + } + + if (IsContentDispositionAttachment( + params->response.HttpHeaderField(http_names::kContentDisposition))) { + // The server wants us to download instead of replacing the page contents. + // Downloading is handled by the embedder, but we still get the initial + // response so that we can ignore it and clean up properly. + return false; + } + + const String& mime_type = params->response.MimeType(); + if (MIMETypeRegistry::IsSupportedMIMEType(mime_type)) + return true; + PluginData* plugin_data = frame->GetPluginData(); + return !mime_type.IsEmpty() && plugin_data && + plugin_data->SupportsMimeType(mime_type); +} + void FrameLoader::CommitNavigation( std::unique_ptr<WebNavigationParams> navigation_params, std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) { @@ -841,6 +921,12 @@ return; } + FillStaticResponseIfNeeded(navigation_params.get(), frame_); + if (!ShouldNavigate(navigation_params.get(), frame_)) { + DidFinishNavigation(); + return; + } + // TODO(dgozman): navigation type should probably be passed by the caller. // It seems incorrect to pass |false| for |have_event| and then use // determined navigation type to update resource request. @@ -861,11 +947,6 @@ std::move(extra_data)); if (history_item) provisional_document_loader->SetItemForHistoryNavigation(history_item); - if (!provisional_document_loader->PrepareForLoad()) { - provisional_document_loader->CleanupWithoutStart(); - DidFinishNavigation(); - return; - } progress_tracker_->ProgressStarted(); provisional_document_loader_ = provisional_document_loader;
diff --git a/third_party/blink/renderer/core/page/frame_tree.cc b/third_party/blink/renderer/core/page/frame_tree.cc index 30087333..58ecc4e5 100644 --- a/third_party/blink/renderer/core/page/frame_tree.cc +++ b/third_party/blink/renderer/core/page/frame_tree.cc
@@ -255,13 +255,6 @@ if (EqualIgnoringASCIICase(name, "_blank")) return nullptr; - // TODO(japhet): window-open-noopener.html?indexed asserts that the noopener - // feature prevents named-window reuse, but the spec doesn't mention this. - // There is ongoing discussion at https://github.com/whatwg/html/issues/1826, - // and this will probably need to be updated once that discussion is resolved. - if (request.IsWindowOpen() && request.GetWindowFeatures().noopener) - return nullptr; - const KURL& url = request.GetResourceRequest().Url(); // Search subtree starting with this frame first. for (Frame* frame = this_frame_; frame;
diff --git a/third_party/blink/renderer/core/resize_observer/resize_observation.cc b/third_party/blink/renderer/core/resize_observer/resize_observation.cc index 7b9ad23..8b1cb60 100644 --- a/third_party/blink/renderer/core/resize_observer/resize_observation.cc +++ b/third_party/blink/renderer/core/resize_observer/resize_observation.cc
@@ -39,8 +39,8 @@ LayoutSize ResizeObservation::ComputeTargetSize() const { if (target_) { if (LayoutObject* layout_object = target_->GetLayoutObject()) { - if (target_->IsSVGElement() && - ToSVGElement(target_)->IsSVGGraphicsElement()) { + auto* svg_element = DynamicTo<SVGElement>(target_.Get()); + if (svg_element && svg_element->IsSVGGraphicsElement()) { SVGGraphicsElement& svg = ToSVGGraphicsElement(*target_); return LayoutSize(svg.GetBBox().Size()); }
diff --git a/third_party/blink/renderer/core/svg/svg_element.h b/third_party/blink/renderer/core/svg/svg_element.h index e71d501..3c5fb74 100644 --- a/third_party/blink/renderer/core/svg/svg_element.h +++ b/third_party/blink/renderer/core/svg/svg_element.h
@@ -30,6 +30,7 @@ #include "third_party/blink/renderer/core/svg_names.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h" namespace blink { @@ -334,6 +335,11 @@ DEFINE_ELEMENT_TYPE_CASTS(SVGElement, IsSVGElement()); +template <> +struct DowncastTraits<SVGElement> { + static bool AllowFrom(const Node& node) { return node.IsSVGElement(); } +}; + template <typename T> bool IsElementOfType(const SVGElement&); template <> @@ -342,7 +348,8 @@ } inline bool Node::HasTagName(const SVGQualifiedName& name) const { - return IsSVGElement() && ToSVGElement(*this).HasTagName(name); + auto* svg_element = DynamicTo<SVGElement>(this); + return svg_element && svg_element->HasTagName(name); } // This requires IsSVG*Element(const SVGElement&). @@ -353,7 +360,8 @@ return element && Is##thisType(*element); \ } \ inline bool Is##thisType(const Node& node) { \ - return node.IsSVGElement() && Is##thisType(ToSVGElement(node)); \ + auto* svg_element = DynamicTo<SVGElement>(node); \ + return svg_element && Is##thisType(svg_element); \ } \ inline bool Is##thisType(const Node* node) { \ return node && Is##thisType(*node); \
diff --git a/third_party/blink/renderer/devtools/BUILD.gn b/third_party/blink/renderer/devtools/BUILD.gn index 229998f..2fdcf9b 100644 --- a/third_party/blink/renderer/devtools/BUILD.gn +++ b/third_party/blink/renderer/devtools/BUILD.gn
@@ -878,6 +878,13 @@ "front_end/ui/XLink.js", "front_end/ui/XWidget.js", "front_end/ui/ZoomManager.js", + "front_end/web_audio/AudioContextContentBuilder.js", + "front_end/web_audio/audioContextSelector.css", + "front_end/web_audio/AudioContextSelector.js", + "front_end/web_audio/module.json", + "front_end/web_audio/webAudio.css", + "front_end/web_audio/WebAudioModel.js", + "front_end/web_audio/WebAudioView.js", "front_end/worker_main/WorkerMain.js", "front_end/worker_main/module.json", "front_end/worker_service/module.json", @@ -1147,6 +1154,7 @@ "$resources_out_dir/text_editor/text_editor_module.js", "$resources_out_dir/timeline_model/timeline_model_module.js", "$resources_out_dir/timeline/timeline_module.js", + "$resources_out_dir/web_audio/web_audio_module.js", "$resources_out_dir/workspace_diff/workspace_diff_module.js", ]
diff --git a/third_party/blink/renderer/devtools/front_end/devtools_app.json b/third_party/blink/renderer/devtools/front_end/devtools_app.json index 40f67e9e..82b5657e 100644 --- a/third_party/blink/renderer/devtools/front_end/devtools_app.json +++ b/third_party/blink/renderer/devtools/front_end/devtools_app.json
@@ -22,7 +22,8 @@ { "name": "resources" }, { "name": "security" }, { "name": "timeline" }, - { "name": "timeline_model" } + { "name": "timeline_model" }, + { "name": "web_audio" } ], "extends": "shell", "has_html": true
diff --git a/third_party/blink/renderer/devtools/front_end/web_audio/AudioContextContentBuilder.js b/third_party/blink/renderer/devtools/front_end/web_audio/AudioContextContentBuilder.js new file mode 100644 index 0000000..714d40d1c --- /dev/null +++ b/third_party/blink/renderer/devtools/front_end/web_audio/AudioContextContentBuilder.js
@@ -0,0 +1,89 @@ +// 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. + +WebAudio.ContextDetailBuilder = class { + /** + * @param {!Protocol.WebAudio.BaseAudioContext} context + */ + constructor(context) { + this._fragment = createDocumentFragment(); + this._container = createElementWithClass('div', 'context-detail-container'); + this._fragment.appendChild(this._container); + this._build(context); + } + + /** + * @param {!Protocol.WebAudio.BaseAudioContext} context + */ + _build(context) { + const title = context.contextType === 'realtime' ? ls`AudioContext` : ls`OfflineAudioContext`; + this._addTitle(title, context.contextId); + this._addEntry(ls`State`, context.contextState); + this._addEntry(ls`Sample Rate`, context.sampleRate, 'Hz'); + if (context.contextType === 'realtime') + this._addEntry(ls`Callback Buffer Size`, context.callbackBufferSize, 'frames'); + this._addEntry(ls`Max Output Channels`, context.maxOutputChannelCount, 'ch'); + } + + /** + * @param {string} title + * @param {string} subtitle + */ + _addTitle(title, subtitle) { + this._container.appendChild(UI.html` + <div class="context-detail-header"> + <div class="context-detail-title">${title}</div> + <div class="context-detail-subtitle">${subtitle}</div> + </div> + `); + } + + /** + * @param {string} entry + * @param {(string|number)} value + * @param {string=} unit + */ + _addEntry(entry, value, unit) { + const valueWithUnit = value + (unit ? ` ${unit}` : ''); + this._container.appendChild(UI.html` + <div class="context-detail-row"> + <div class="context-detail-row-entry">${entry}</div> + <div class="context-detail-row-value">${valueWithUnit}</div> + </div> + `); + } + + /** + * @return {!DocumentFragment} + */ + getFragment() { + return this._fragment; + } +}; + +WebAudio.AudioContextSummaryBuilder = class { + /** + * @param {!Protocol.WebAudio.ContextId} contextId + * @param {!Protocol.WebAudio.ContextRealtimeData} contextRealtimeData + */ + constructor(contextId, contextRealtimeData) { + const time = contextRealtimeData.currentTime.toFixed(3); + const capacity = (contextRealtimeData.renderCapacity * 100).toFixed(3); + this._fragment = createDocumentFragment(); + this._fragment.appendChild(UI.html` + <div class="context-summary-container"> + <span>${ls`Current Time`}: ${time} s</span> + <span>\u2758</span> + <span>${ls`Render Capacity`}: ${capacity} %</span> + </div> + `); + } + + /** + * @return {!DocumentFragment} + */ + getFragment() { + return this._fragment; + } +}; \ No newline at end of file
diff --git a/third_party/blink/renderer/devtools/front_end/web_audio/AudioContextSelector.js b/third_party/blink/renderer/devtools/front_end/web_audio/AudioContextSelector.js new file mode 100644 index 0000000..f40f41cf --- /dev/null +++ b/third_party/blink/renderer/devtools/front_end/web_audio/AudioContextSelector.js
@@ -0,0 +1,157 @@ +// 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. + +/** + * @implements {UI.SoftDropDown.Delegate<!Protocol.WebAudio.BaseAudioContext>} + */ +WebAudio.AudioContextSelector = class extends Common.Object { + constructor(title) { + super(); + + /** @type {!UI.ListModel<!Protocol.WebAudio.BaseAudioContext>} */ + this._items = new UI.ListModel(); + + /** @type {!UI.SoftDropDown<!Protocol.WebAudio.BaseAudioContext>} */ + this._dropDown = new UI.SoftDropDown(this._items, this); + this._dropDown.setPlaceholderText(ls`(no recordings)`); + + this._toolbarItem = new UI.ToolbarItem(this._dropDown.element); + this._toolbarItem.setEnabled(false); + this._toolbarItem.setTitle(title); + this._items.addEventListener(UI.ListModel.Events.ItemsReplaced, this._onListItemReplaced, this); + this._toolbarItem.element.classList.add('toolbar-has-dropdown'); + + /** @type {?Protocol.WebAudio.BaseAudioContext} */ + this._selectedContext = null; + } + + _onListItemReplaced() { + this._toolbarItem.setEnabled(!!this._items.length); + } + + /** + * @param {!Common.Event} event + */ + contextCreated(event) { + const context = /** @type {!Protocol.WebAudio.BaseAudioContext} */ (event.data); + this._items.insert(this._items.length, context); + + // Select if this is the first item. + if (this._items.length === 1) + this._dropDown.selectItem(context); + } + + /** + * @param {!Common.Event} event + */ + contextDestroyed(event) { + const contextId = /** @type {!Protocol.WebAudio.ContextId} */ (event.data); + const contextIndex = this._items.findIndex(context => context.contextId === contextId); + if (contextIndex > -1) + this._items.remove(contextIndex); + } + + /** + * @param {!Common.Event} event + */ + contextChanged(event) { + const changedContext = /** @type {!Protocol.WebAudio.BaseAudioContext} */ (event.data); + const contextIndex = this._items.findIndex(context => context.contextId === changedContext.contextId); + if (contextIndex > -1) { + this._items.remove(contextIndex); + this._items.insert(contextIndex, changedContext); + + // If the changed context is currently selected by user. Re-select it + // because the actual element is replaced with a new one. + if (this._selectedContext && this._selectedContext.contextId === changedContext.contextId) + this._dropDown.selectItem(changedContext); + } + } + + /** + * @override + * @param {!Protocol.WebAudio.BaseAudioContext} item + * @return {!Element} + */ + createElementForItem(item) { + const element = createElementWithClass('div'); + const shadowRoot = UI.createShadowRootWithCoreStyles(element, 'web_audio/audioContextSelector.css'); + const title = shadowRoot.createChild('div', 'title'); + title.createTextChild(this.titleFor(item).trimEnd(100)); + return element; + } + + /** + * @return {?Protocol.WebAudio.BaseAudioContext} + */ + selectedContext() { + if (!this._selectedContext) + return null; + + return this._selectedContext; + } + + /** + * @override + * @param {?Protocol.WebAudio.BaseAudioContext} from + * @param {?Protocol.WebAudio.BaseAudioContext} to + * @param {?Element} fromElement + * @param {?Element} toElement + */ + highlightedItemChanged(from, to, fromElement, toElement) { + if (fromElement) + fromElement.classList.remove('highlighted'); + if (toElement) + toElement.classList.add('highlighted'); + } + + /** + * @override + * @param {!Protocol.WebAudio.BaseAudioContext} item + * @return {boolean} + */ + isItemSelectable(item) { + return true; + } + + /** + * @override + * @param {?Protocol.WebAudio.BaseAudioContext} item + */ + itemSelected(item) { + if (!item) + return; + + // It's possible that no context is selected yet. + if (!this._selectedContext || this._selectedContext.contextId !== item.contextId) + this._selectedContext = item; + + this.dispatchEventToListeners(WebAudio.AudioContextSelector.Events.ContextSelected, item); + } + + reset() { + this._items.replaceAll([]); + } + + /** + * @override + * @param {!Protocol.WebAudio.BaseAudioContext} context + * @return {string} + */ + titleFor(context) { + return `${context.contextType} (${context.contextId.substr(-6)})`; + } + + /** + * @return {!UI.ToolbarItem} + */ + toolbarItem() { + return this._toolbarItem; + } +}; + +/** @enum {symbol} */ +WebAudio.AudioContextSelector.Events = { + ContextSelected: Symbol('ContextSelected') +}; \ No newline at end of file
diff --git a/third_party/blink/renderer/devtools/front_end/web_audio/WebAudioModel.js b/third_party/blink/renderer/devtools/front_end/web_audio/WebAudioModel.js new file mode 100644 index 0000000..47a3cfd --- /dev/null +++ b/third_party/blink/renderer/devtools/front_end/web_audio/WebAudioModel.js
@@ -0,0 +1,98 @@ +// 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. + +/** + * @implements {Protocol.WebAudioDispatcher} + */ +WebAudio.WebAudioModel = class extends SDK.SDKModel { + /** + * @param {!SDK.Target} target + */ + constructor(target) { + super(target); + + this._enabled = false; + + /** @type {!Map<!Protocol.WebAudio.ContextId, !Protocol.WebAudio.BaseAudioContext>} */ + this._contextMapById = new Map(); + + this._agent = target.webAudioAgent(); + target.registerWebAudioDispatcher(this); + } + + /** + * @override + * @return {!Promise} + */ + suspendModel() { + this._contextMapById.clear(); + return this._agent.disable(); + } + + /** + * @override + * @return {!Promise} + */ + resumeModel() { + if (!this._enabled) + return Promise.resolve(); + return this._agent.enable(); + } + + ensureEnabled() { + if (this._enabled) + return; + this._agent.enable(); + this._enabled = true; + } + + /** + * @param {!Protocol.WebAudio.BaseAudioContext} context + * @override + */ + contextCreated(context) { + this._contextMapById.set(context.contextId, context); + this.dispatchEventToListeners(WebAudio.WebAudioModel.Events.ContextCreated, context); + } + + /** + * @param {!Protocol.WebAudio.ContextId} contextId + * @override + */ + contextDestroyed(contextId) { + this._contextMapById.delete(contextId); + this.dispatchEventToListeners(WebAudio.WebAudioModel.Events.ContextDestroyed, contextId); + } + + /** + * @param {!Protocol.WebAudio.BaseAudioContext} context + * @override + */ + contextChanged(context) { + if (!this._contextMapById.has(context.contextId)) + return; + + this._contextMapById.set(context.contextId, context); + this.dispatchEventToListeners(WebAudio.WebAudioModel.Events.ContextChanged, context); + } + + /** + * @param {!Protocol.WebAudio.ContextId} contextId + * @return {!Promise<?Protocol.WebAudio.ContextRealtimeData>} + */ + async requestRealtimeData(contextId) { + if (!this._contextMapById.has(contextId)) + return Promise.resolve(); + return await this._agent.getRealtimeData(contextId); + } +}; + +SDK.SDKModel.register(WebAudio.WebAudioModel, SDK.Target.Capability.DOM, false); + +/** @enum {symbol} */ +WebAudio.WebAudioModel.Events = { + ContextCreated: Symbol('ContextCreated'), + ContextDestroyed: Symbol('ContextDestroyed'), + ContextChanged: Symbol('ContextChanged'), +};
diff --git a/third_party/blink/renderer/devtools/front_end/web_audio/WebAudioView.js b/third_party/blink/renderer/devtools/front_end/web_audio/WebAudioView.js new file mode 100644 index 0000000..ca286a4 --- /dev/null +++ b/third_party/blink/renderer/devtools/front_end/web_audio/WebAudioView.js
@@ -0,0 +1,183 @@ +// 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. + +/** + * @implements {SDK.SDKModelObserver<!WebAudio.WebAudioModel>} + */ +WebAudio.WebAudioView = class extends UI.ThrottledWidget { + constructor() { + super(true, 1000); + this.element.classList.add('web-audio-drawer'); + this.registerRequiredCSS('web_audio/webAudio.css'); + + // Creates the toolbar. + const toolbarContainer = this.contentElement.createChild( + 'div', 'web-audio-toolbar-container vbox'); + this._contextSelector = new WebAudio.AudioContextSelector(ls`BaseAudioContexts`); + const toolbar = new UI.Toolbar('web-audio-toolbar', toolbarContainer); + toolbar.appendToolbarItem(UI.Toolbar.createActionButtonForId('components.collect-garbage')); + toolbar.appendSeparator(); + toolbar.appendToolbarItem(this._contextSelector.toolbarItem()); + + // Creates the detail view. + this._detailViewContainer = this.contentElement.createChild('div', 'vbox flex-auto'); + + // Creates the landing page. + this._landingPage = new UI.VBox(); + this._landingPage.contentElement.classList.add('web-audio-landing-page', 'fill'); + this._landingPage.contentElement.appendChild(UI.html` + <div> + <p>${ls`Open a page that uses Web Audio API to start monitoring.`}</p> + </div> + `); + this._landingPage.show(this._detailViewContainer); + + // Creates the summary bar. + this._summaryBarContainer = this.contentElement.createChild('div', 'web-audio-summary-container'); + + this._contextSelector.addEventListener(WebAudio.AudioContextSelector.Events.ContextSelected, event => { + const context = + /** @type {!Protocol.WebAudio.BaseAudioContext} */ (event.data); + this._updateDetailView(context); + this.doUpdate(); + }); + + SDK.targetManager.observeModels(WebAudio.WebAudioModel, this); + } + + /** + * @override + */ + wasShown() { + for (const model of SDK.targetManager.models(WebAudio.WebAudioModel)) + this._addEventListeners(model); + } + + /** + * @override + */ + willHide() { + for (const model of SDK.targetManager.models(WebAudio.WebAudioModel)) + this._removeEventListeners(model); + } + + /** + * @override + * @param {!WebAudio.WebAudioModel} webAudioModel + */ + modelAdded(webAudioModel) { + if (this.isShowing()) + this._addEventListeners(webAudioModel); + } + + /** + * @override + * @param {!WebAudio.WebAudioModel} webAudioModel + */ + modelRemoved(webAudioModel) { + this._removeEventListeners(webAudioModel); + } + + /** + * @override + * @return {!Promise<?>} + */ + async doUpdate() { + await this._pollRealtimeData(); + this.update(); + } + + /** + * @param {!WebAudio.WebAudioModel} webAudioModel + */ + _addEventListeners(webAudioModel) { + webAudioModel.ensureEnabled(); + webAudioModel.addEventListener(WebAudio.WebAudioModel.Events.ContextCreated, this._contextCreated, this); + webAudioModel.addEventListener(WebAudio.WebAudioModel.Events.ContextDestroyed, this._contextDestroyed, this); + webAudioModel.addEventListener(WebAudio.WebAudioModel.Events.ContextChanged, this._contextChanged, this); + } + + /** + * @param {!WebAudio.WebAudioModel} webAudioModel + */ + _removeEventListeners(webAudioModel) { + webAudioModel.removeEventListener(WebAudio.WebAudioModel.Events.ContextCreated, this._contextCreated, this); + webAudioModel.removeEventListener(WebAudio.WebAudioModel.Events.ContextDestroyed, this._contextDestroyed, this); + webAudioModel.removeEventListener(WebAudio.WebAudioModel.Events.ContextChanged, this._contextChanged, this); + } + + /** + * @param {!Common.Event} event + */ + _contextCreated(event) { + this._contextSelector.contextCreated(event); + } + + /** + * @param {!Common.Event} event + */ + _contextDestroyed(event) { + this._contextSelector.contextDestroyed(event); + } + + /** + * @param {!Common.Event} event + */ + _contextChanged(event) { + this._contextSelector.contextChanged(event); + } + + _reset() { + if (this._landingPage.isShowing()) + this._landingPage.detach(); + this._contextSelector.reset(); + this._detailViewContainer.removeChildren(); + this._landingPage.show(this._detailViewContainer); + } + + /** + * @param {!Protocol.WebAudio.BaseAudioContext} context + */ + _updateDetailView(context) { + if (this._landingPage.isShowing()) + this._landingPage.detach(); + const detailBuilder = new WebAudio.ContextDetailBuilder(context); + this._detailViewContainer.removeChildren(); + this._detailViewContainer.appendChild(detailBuilder.getFragment()); + } + + /** + * @param {!Protocol.WebAudio.ContextId} contextId + * @param {!Protocol.WebAudio.ContextRealtimeData} contextRealtimeData + */ + _updateSummaryBar(contextId, contextRealtimeData) { + const summaryBuilder = + new WebAudio.AudioContextSummaryBuilder(contextId, contextRealtimeData); + this._summaryBarContainer.removeChildren(); + this._summaryBarContainer.appendChild(summaryBuilder.getFragment()); + } + + _clearSummaryBar() { + this._summaryBarContainer.removeChildren(); + } + + async _pollRealtimeData() { + const context = this._contextSelector.selectedContext(); + if (!context) { + this._clearSummaryBar(); + return; + } + + for (const model of SDK.targetManager.models(WebAudio.WebAudioModel)) { + // Display summary only for real-time context. + if (context.contextType === 'realtime') { + const realtimeData = await model.requestRealtimeData(context.contextId); + if (realtimeData && realtimeData.currentTime && realtimeData.renderCapacity) + this._updateSummaryBar(context.contextId, realtimeData); + } else { + this._clearSummaryBar(); + } + } + } +};
diff --git a/third_party/blink/renderer/devtools/front_end/web_audio/audioContextSelector.css b/third_party/blink/renderer/devtools/front_end/web_audio/audioContextSelector.css new file mode 100644 index 0000000..a689f25 --- /dev/null +++ b/third_party/blink/renderer/devtools/front_end/web_audio/audioContextSelector.css
@@ -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. + */ + +:host { + padding: 2px 1px 2px 2px; + white-space: nowrap; + display: flex; + flex-direction: column; + height: 36px; + justify-content: center; +} + +.title { + overflow: hidden; + text-overflow: ellipsis; + flex-grow: 0; +} \ No newline at end of file
diff --git a/third_party/blink/renderer/devtools/front_end/web_audio/module.json b/third_party/blink/renderer/devtools/front_end/web_audio/module.json new file mode 100644 index 0000000..7212a6e6 --- /dev/null +++ b/third_party/blink/renderer/devtools/front_end/web_audio/module.json
@@ -0,0 +1,29 @@ +{ + "extensions": [ + { + "type": "view", + "location": "drawer-view", + "id": "web-audio", + "title": "WebAudio", + "persistence": "closeable", + "order": 100, + "className": "WebAudio.WebAudioView", + "tags": "audio" + } + ], + "dependencies": [ + "components", + "sdk", + "ui" + ], + "scripts": [ + "WebAudioModel.js", + "AudioContextSelector.js", + "AudioContextContentBuilder.js", + "WebAudioView.js" + ], + "resources": [ + "webAudio.css", + "audioContextSelector.css" + ] +} \ No newline at end of file
diff --git a/third_party/blink/renderer/devtools/front_end/web_audio/webAudio.css b/third_party/blink/renderer/devtools/front_end/web_audio/webAudio.css new file mode 100644 index 0000000..0cbba877 --- /dev/null +++ b/third_party/blink/renderer/devtools/front_end/web_audio/webAudio.css
@@ -0,0 +1,97 @@ +/* + * 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. + */ + +:host { + overflow: hidden; +} + +.web-audio-toolbar-container { + background-color: var(--toolbar-bg-color); + border-bottom: var(--divider-border); +} + +.web-audio-toolbar { + display: inline-block; +} + +.web-audio-landing-page { + position: absolute; + background-color: white; + justify-content: center; + align-items: center; + overflow: auto; + font-size: 13px; + color: #777; +} + +.web-audio-landing-page > div { + max-width: 500px; + margin: 10px; +} + +.web-audio-landing-page > div > p { + flex: none; + white-space: pre-line; +} + +.context-detail-container { + flex: none; + display: flex; + background-color: white; + flex-direction: column; +} + +.context-detail-header { + border-bottom: 1px solid rgb(230, 230, 230); + padding: 12px 24px; + margin-bottom: 10px; +} + +.context-detail-title { + font-size: 15px; + font-weight: 400; +} + +.context-detail-subtitle { + font-size: 12px; + margin-top: 10px; + user-select: text; +} + +.context-detail-row { + flex-direction: row; + display: flex; + line-height: 18px; + padding-left: 24px; +} + +.context-detail-row-entry:not(:empty) { + color: hsla(0, 0%, 46%, 1); + overflow: hidden; + width: 130px; +} + +.context-detail-row-value { + user-select: text; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; +} + +.context-summary-container { + flex: 0 0 27px; + line-height: 27px; + padding-left: 5px; + background-color: #eee; + border-top: 1px solid #ccc; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; +} + +.context-summary-container span { + margin-right: 6px; +}
diff --git a/third_party/blink/renderer/modules/BUILD.gn b/third_party/blink/renderer/modules/BUILD.gn index 1f31992..ba1f02f45 100644 --- a/third_party/blink/renderer/modules/BUILD.gn +++ b/third_party/blink/renderer/modules/BUILD.gn
@@ -398,8 +398,11 @@ ] if (is_android && notouch_build) { - sources += - [ "media_controls/touchless/media_controls_touchless_impl_test.cc" ] + sources += [ + "media_controls/touchless/media_controls_touchless_impl_test.cc", + "media_controls/touchless/test_media_controls_menu_host.cc", + "media_controls/touchless/test_media_controls_menu_host.h", + ] } configs += [
diff --git a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc index ef0aaf32..57cdeb26 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
@@ -2724,7 +2724,7 @@ layout_text->FirstAbstractInlineTextBox(); box.get(); box = box->NextInlineTextBox()) { AXObject* ax_object = AXObjectCache().GetOrCreate(box.get()); - if (ax_object->AccessibilityIsIncludedInTree()) + if (!ax_object->AccessibilityIsIgnored()) children_.push_back(ax_object); } } @@ -3448,7 +3448,7 @@ // Find out where the last layout sibling is located within m_children. if (AXObject* child_object = AXObjectCache().Get(child.GetLayoutObject())) { - if (!child_object->AccessibilityIsIncludedInTree()) { + if (child_object->AccessibilityIsIgnored()) { const auto& children = child_object->Children(); child_object = children.size() ? children.back().Get() : nullptr; } @@ -3487,7 +3487,7 @@ AXImageMapLink* area_object = ToAXImageMapLink(obj); area_object->SetParent(this); DCHECK_NE(area_object->AXObjectID(), 0U); - if (area_object->AccessibilityIsIncludedInTree()) + if (!area_object->AccessibilityIsIgnored()) children_.push_back(area_object); else AXObjectCache().Remove(area_object->AXObjectID()); @@ -3529,7 +3529,7 @@ root->SetParent(this); - if (!root->AccessibilityIsIncludedInTree()) { + if (root->AccessibilityIsIgnored()) { for (const auto& child : root->Children()) children_.push_back(child); } else { @@ -3550,7 +3550,7 @@ if (HTMLTableCaptionElement* caption = ToHTMLTableElement(table_node)->caption()) { AXObject* caption_object = ax_cache.GetOrCreate(caption); - if (caption_object && caption_object->AccessibilityIsIncludedInTree()) + if (caption_object && !caption_object->AccessibilityIsIgnored()) children_.push_front(caption_object); } }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc b/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc index caaeda8..cdd8977 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc
@@ -78,7 +78,7 @@ return; ToAXMockObject(popup)->SetParent(this); - if (!popup->AccessibilityIsIncludedInTree()) { + if (popup->AccessibilityIsIgnored()) { cache.Remove(popup->AXObjectID()); return; }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc index 1e10458..2868adb 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -1486,7 +1486,7 @@ for (AXObject* child : parent->Children()) { DCHECK(child); if (child->RoleValue() == ax::mojom::Role::kRadioButton && - child->AccessibilityIsIncludedInTree()) { + !child->AccessibilityIsIgnored()) { radio_buttons.push_back(child); } } @@ -2364,7 +2364,7 @@ // getting children, ensure data is not stale. child->ClearChildren(); - if (!child->AccessibilityIsIncludedInTree()) { + if (child->AccessibilityIsIgnored()) { const auto& children = child->Children(); wtf_size_t length = children.size(); for (wtf_size_t i = 0; i < length; ++i)
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc index 98b3dc4..6041c19 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -888,12 +888,6 @@ return cached_is_ignored_; } -// TODO(janewman) AccessibilityIsIncludedInTree should be true for all nodes -// that should be included in the tree, ignored or not. -bool AXObject::AccessibilityIsIncludedInTree() const { - return !AccessibilityIsIgnored(); -} - void AXObject::UpdateCachedAttributeValuesIfNeeded() const { if (IsDetached()) return; @@ -910,8 +904,7 @@ cached_is_descendant_of_disabled_node_ = !!DisabledAncestor(); cached_has_inherited_presentational_role_ = !!InheritsPresentationalRoleFrom(); - IgnoredReasons ignored_reasons; - cached_is_ignored_ = ComputeAccessibilityIsIgnored(&ignored_reasons); + cached_is_ignored_ = ComputeAccessibilityIsIgnored(); cached_is_editable_root_ = ComputeIsEditableRoot(); // Compute live region root, which can be from any ARIA live value, including // "off", or from an automatic ARIA live value, e.g. from role="status".
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.h b/third_party/blink/renderer/modules/accessibility/ax_object.h index cbedc3b6..633f429 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.h +++ b/third_party/blink/renderer/modules/accessibility/ax_object.h
@@ -561,13 +561,8 @@ virtual bool CanSetFocusAttribute() const; bool CanSetValueAttribute() const; - // Whether objects are ignored, i.e. hidden in the tree for most ATs + // Whether objects are ignored, i.e. not included in the tree. bool AccessibilityIsIgnored() const; - - // Whether objects are included in the tree. A node may be Ignored, - // but allowed to pass into the tree, e.g. a hidden node referenced - // by labeled-by. - bool AccessibilityIsIncludedInTree() const; typedef HeapVector<IgnoredReason> IgnoredReasons; virtual bool ComputeAccessibilityIsIgnored(IgnoredReasons* = nullptr) const { return true; @@ -1112,7 +1107,6 @@ mutable int last_modification_count_; mutable RGBA32 cached_background_color_; mutable bool cached_is_ignored_ : 1; - mutable bool cached_is_inert_or_aria_hidden_ : 1; mutable bool cached_is_descendant_of_leaf_node_ : 1; mutable bool cached_is_descendant_of_disabled_node_ : 1;
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 2c689c0..0ac1c5b 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
@@ -219,7 +219,7 @@ // the HTML element, for example, is focusable but has an AX object that is // ignored - if (!obj->AccessibilityIsIncludedInTree()) + if (obj->AccessibilityIsIgnored()) obj = obj->ParentObjectUnignored(); return obj; @@ -1437,8 +1437,7 @@ return nullptr; AXObject* accessible_object = GetOrCreate(node->GetLayoutObject()); - while (accessible_object && - !accessible_object->AccessibilityIsIncludedInTree()) { + while (accessible_object && accessible_object->AccessibilityIsIgnored()) { node = NodeTraversal::Next(*node); while (node && !node->GetLayoutObject()) @@ -1616,7 +1615,7 @@ AXObject* obj = GetOrCreate(anchor_node->GetLayoutObject()); if (!obj) return; - if (!obj->AccessibilityIsIncludedInTree()) + if (obj->AccessibilityIsIgnored()) obj = obj->ParentObjectUnignored(); PostNotification(obj, ax::mojom::Event::kScrolledToAnchor); }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_slider.cc b/third_party/blink/renderer/modules/accessibility/ax_slider.cc index 05a3e36..8dc379b2 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_slider.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_slider.cc
@@ -87,7 +87,7 @@ // Before actually adding the value indicator to the hierarchy, // allow the platform to make a final decision about it. - if (!thumb->AccessibilityIsIncludedInTree()) + if (thumb->AccessibilityIsIgnored()) cache.Remove(thumb->AXObjectID()); else children_.push_back(thumb);
diff --git a/third_party/blink/renderer/modules/background_sync/BUILD.gn b/third_party/blink/renderer/modules/background_sync/BUILD.gn index 33df19a..6b48fec 100644 --- a/third_party/blink/renderer/modules/background_sync/BUILD.gn +++ b/third_party/blink/renderer/modules/background_sync/BUILD.gn
@@ -6,6 +6,8 @@ blink_modules_sources("background_sync") { sources = [ + "periodic_sync_event.cc", + "periodic_sync_event.h", "service_worker_global_scope_sync.h", "service_worker_registration_sync.cc", "service_worker_registration_sync.h",
diff --git a/third_party/blink/renderer/modules/background_sync/periodic_sync_event.cc b/third_party/blink/renderer/modules/background_sync/periodic_sync_event.cc new file mode 100644 index 0000000..b1eef2ac --- /dev/null +++ b/third_party/blink/renderer/modules/background_sync/periodic_sync_event.cc
@@ -0,0 +1,29 @@ +// 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 "third_party/blink/renderer/modules/background_sync/periodic_sync_event.h" + +namespace blink { + +PeriodicSyncEvent::PeriodicSyncEvent(const AtomicString& type, + const String& tag, + WaitUntilObserver* observer) + : ExtendableEvent(type, ExtendableEventInit::Create(), observer), + tag_(tag) {} + +PeriodicSyncEvent::PeriodicSyncEvent(const AtomicString& type, + const PeriodicSyncEventInit* init) + : ExtendableEvent(type, init), tag_(init->tag()) {} + +PeriodicSyncEvent::~PeriodicSyncEvent() = default; + +const AtomicString& PeriodicSyncEvent::InterfaceName() const { + return event_interface_names::kPeriodicSyncEvent; +} + +const String& PeriodicSyncEvent::tag() const { + return tag_; +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/background_sync/periodic_sync_event.h b/third_party/blink/renderer/modules/background_sync/periodic_sync_event.h new file mode 100644 index 0000000..56e5791 --- /dev/null +++ b/third_party/blink/renderer/modules/background_sync/periodic_sync_event.h
@@ -0,0 +1,48 @@ +// 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 THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_SYNC_PERIODIC_SYNC_EVENT_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_SYNC_PERIODIC_SYNC_EVENT_H_ + +#include "third_party/blink/renderer/modules/background_sync/periodic_sync_event_init.h" +#include "third_party/blink/renderer/modules/event_modules.h" +#include "third_party/blink/renderer/modules/service_worker/extendable_event.h" +#include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + +namespace blink { + +class MODULES_EXPORT PeriodicSyncEvent final : public ExtendableEvent { + DEFINE_WRAPPERTYPEINFO(); + + public: + static PeriodicSyncEvent* Create(const AtomicString& type, + const String& tag, + WaitUntilObserver* observer) { + return MakeGarbageCollected<PeriodicSyncEvent>(type, tag, observer); + } + static PeriodicSyncEvent* Create(const AtomicString& type, + const PeriodicSyncEventInit* init) { + return MakeGarbageCollected<PeriodicSyncEvent>(type, init); + } + + PeriodicSyncEvent(const AtomicString& type, + const String& tag, + WaitUntilObserver* observer); + PeriodicSyncEvent(const AtomicString& type, + const PeriodicSyncEventInit* init); + ~PeriodicSyncEvent() override; + + const AtomicString& InterfaceName() const override; + + const String& tag() const; + + private: + String tag_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_SYNC_PERIODIC_SYNC_EVENT_H_
diff --git a/third_party/blink/renderer/modules/background_sync/periodic_sync_event.idl b/third_party/blink/renderer/modules/background_sync/periodic_sync_event.idl new file mode 100644 index 0000000..caefac4c --- /dev/null +++ b/third_party/blink/renderer/modules/background_sync/periodic_sync_event.idl
@@ -0,0 +1,13 @@ +// 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. + +// TODO(crbug.com/925297): Link to spec. + +[ + Constructor(DOMString type, PeriodicSyncEventInit init), + Exposed=ServiceWorker, + RuntimeEnabled=PeriodicBackgroundSync +] interface PeriodicSyncEvent : ExtendableEvent { + readonly attribute DOMString tag; +};
diff --git a/third_party/blink/renderer/modules/background_sync/periodic_sync_event_init.idl b/third_party/blink/renderer/modules/background_sync/periodic_sync_event_init.idl new file mode 100644 index 0000000..3a53b41 --- /dev/null +++ b/third_party/blink/renderer/modules/background_sync/periodic_sync_event_init.idl
@@ -0,0 +1,9 @@ +// 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. + +// TODO(crbug.com/925297): Link to spec. + +dictionary PeriodicSyncEventInit : ExtendableEventInit { + required DOMString tag; +};
diff --git a/third_party/blink/renderer/modules/background_sync/sync_event.cc b/third_party/blink/renderer/modules/background_sync/sync_event.cc index bf5d209f..390b3317 100644 --- a/third_party/blink/renderer/modules/background_sync/sync_event.cc +++ b/third_party/blink/renderer/modules/background_sync/sync_event.cc
@@ -15,10 +15,9 @@ last_chance_(last_chance) {} SyncEvent::SyncEvent(const AtomicString& type, const SyncEventInit* init) - : ExtendableEvent(type, init) { - tag_ = init->tag(); - last_chance_ = init->lastChance(); -} + : ExtendableEvent(type, init), + tag_(init->tag()), + last_chance_(init->lastChance()) {} SyncEvent::~SyncEvent() = default; @@ -26,16 +25,12 @@ return event_interface_names::kSyncEvent; } -String SyncEvent::tag() { +const String& SyncEvent::tag() const { return tag_; } -bool SyncEvent::lastChance() { +bool SyncEvent::lastChance() const { return last_chance_; } -void SyncEvent::Trace(blink::Visitor* visitor) { - ExtendableEvent::Trace(visitor); -} - } // namespace blink
diff --git a/third_party/blink/renderer/modules/background_sync/sync_event.h b/third_party/blink/renderer/modules/background_sync/sync_event.h index 604bdec..f336c1f4 100644 --- a/third_party/blink/renderer/modules/background_sync/sync_event.h +++ b/third_party/blink/renderer/modules/background_sync/sync_event.h
@@ -29,16 +29,17 @@ return MakeGarbageCollected<SyncEvent>(type, init); } - SyncEvent(const AtomicString& type, const String&, bool, WaitUntilObserver*); - SyncEvent(const AtomicString& type, const SyncEventInit*); + SyncEvent(const AtomicString& type, + const String& tag, + bool last_chance, + WaitUntilObserver* observer); + SyncEvent(const AtomicString& type, const SyncEventInit* init); ~SyncEvent() override; const AtomicString& InterfaceName() const override; - String tag(); - bool lastChance(); - - void Trace(blink::Visitor*) override; + const String& tag() const; + bool lastChance() const; private: String tag_;
diff --git a/third_party/blink/renderer/modules/exported/web_ax_object.cc b/third_party/blink/renderer/modules/exported/web_ax_object.cc index 4829781..84ec4bb2 100644 --- a/third_party/blink/renderer/modules/exported/web_ax_object.cc +++ b/third_party/blink/renderer/modules/exported/web_ax_object.cc
@@ -1231,13 +1231,6 @@ return private_->AccessibilityIsIgnored(); } -bool WebAXObject::AccessibilityIsIncludedInTree() const { - if (IsDetached()) - return false; - - return private_->AccessibilityIsIncludedInTree(); -} - int WebAXObject::AriaColumnCount() const { if (IsDetached()) return 0;
diff --git a/third_party/blink/renderer/modules/hid/hid_collection_info.cc b/third_party/blink/renderer/modules/hid/hid_collection_info.cc index 3c72c06..fcfac53 100644 --- a/third_party/blink/renderer/modules/hid/hid_collection_info.cc +++ b/third_party/blink/renderer/modules/hid/hid_collection_info.cc
@@ -41,10 +41,6 @@ return feature_reports_; } -const Vector<uint8_t>& HIDCollectionInfo::reportIds() const { - return report_ids_; -} - uint32_t HIDCollectionInfo::collectionType() const { return 0; }
diff --git a/third_party/blink/renderer/modules/hid/hid_collection_info.h b/third_party/blink/renderer/modules/hid/hid_collection_info.h index 5beeec55..33950571 100644 --- a/third_party/blink/renderer/modules/hid/hid_collection_info.h +++ b/third_party/blink/renderer/modules/hid/hid_collection_info.h
@@ -27,7 +27,6 @@ const HeapVector<Member<HIDReportInfo>>& inputReports() const; const HeapVector<Member<HIDReportInfo>>& outputReports() const; const HeapVector<Member<HIDReportInfo>>& featureReports() const; - const Vector<uint8_t>& reportIds() const; uint32_t collectionType() const; void Trace(blink::Visitor* visitor) override; @@ -37,7 +36,6 @@ HeapVector<Member<HIDReportInfo>> input_reports_; HeapVector<Member<HIDReportInfo>> output_reports_; HeapVector<Member<HIDReportInfo>> feature_reports_; - Vector<uint8_t> report_ids_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/hid/hid_collection_info.idl b/third_party/blink/renderer/modules/hid/hid_collection_info.idl index d1b079c..23fcf24 100644 --- a/third_party/blink/renderer/modules/hid/hid_collection_info.idl +++ b/third_party/blink/renderer/modules/hid/hid_collection_info.idl
@@ -25,8 +25,4 @@ readonly attribute FrozenArray<HIDReportInfo> inputReports; readonly attribute FrozenArray<HIDReportInfo> outputReports; readonly attribute FrozenArray<HIDReportInfo> featureReports; - - // The 8-bit report IDs associated with this collection, in the order they - // were encountered in the report descriptor. - readonly attribute FrozenArray<octet> reportIds; };
diff --git a/third_party/blink/renderer/modules/hid/hid_report_item.cc b/third_party/blink/renderer/modules/hid/hid_report_item.cc index 80285ef..2696841 100644 --- a/third_party/blink/renderer/modules/hid/hid_report_item.cc +++ b/third_party/blink/renderer/modules/hid/hid_report_item.cc
@@ -10,8 +10,4 @@ HIDReportItem::~HIDReportItem() {} -void HIDReportItem::Trace(blink::Visitor* visitor) { - ScriptWrappable::Trace(visitor); -} - } // namespace blink
diff --git a/third_party/blink/renderer/modules/hid/hid_report_item.h b/third_party/blink/renderer/modules/hid/hid_report_item.h index 6ad3370..a791350 100644 --- a/third_party/blink/renderer/modules/hid/hid_report_item.h +++ b/third_party/blink/renderer/modules/hid/hid_report_item.h
@@ -7,6 +7,10 @@ #include "services/device/public/mojom/hid.mojom-blink.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" +#include "third_party/blink/renderer/platform/heap/heap_allocator.h" +#include "third_party/blink/renderer/platform/heap/member.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "third_party/blink/renderer/platform/wtf/vector.h" namespace blink { @@ -24,23 +28,25 @@ const Vector<uint32_t>& usages() const { return usages_; } uint32_t usageMinimum() const { return 0; } uint32_t usageMaximum() const { return 0; } - uint32_t designatorMinimum() const { return 0; } - uint32_t designatorMaximum() const { return 0; } - uint32_t stringMinimum() const { return 0; } - uint32_t stringMaximum() const { return 0; } + const Vector<String>& strings() const { return strings_; } uint16_t reportSize() const { return 0; } uint16_t reportCount() const { return 0; } uint32_t unitExponent() const { return 0; } - uint32_t unit() const { return 0; } + String unitSystem() const { return String(); } + int8_t unitFactorLengthExponent() const { return 0; } + int8_t unitFactorMassExponent() const { return 0; } + int8_t unitFactorTimeExponent() const { return 0; } + int8_t unitFactorTemperatureExponent() const { return 0; } + int8_t unitFactorCurrentExponent() const { return 0; } + int8_t unitFactorLuminousIntensityExponent() const { return 0; } int32_t logicalMinimum() const { return 0; } int32_t logicalMaximum() const { return 0; } int32_t physicalMinimum() const { return 0; } int32_t physicalMaximum() const { return 0; } - void Trace(blink::Visitor* visitor) override; - private: Vector<uint32_t> usages_; + Vector<String> strings_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/hid/hid_report_item.idl b/third_party/blink/renderer/modules/hid/hid_report_item.idl index 4f0c01f2..b682bf80 100644 --- a/third_party/blink/renderer/modules/hid/hid_report_item.idl +++ b/third_party/blink/renderer/modules/hid/hid_report_item.idl
@@ -6,6 +6,28 @@ // the report. // https://wicg.github.io/webhid/index.html#report-descriptor +// The HID specification allows a device to specify units in one of four +// standard unit systems. A device may also specify it is not using units, or is +// using a vendor-defined unit system. Each unit system corresponds to a set of +// units for length, mass, time, temperature, current, and luminous intensity. +// See the units table in section 6.2.2.7 of the Device Class Definition for +// HID, v1.11. +// https://www.usb.org/document-library/device-class-definition-hid-111 +enum HIDUnitSystem { + // No unit system in use. + "none", + // Centimeter, gram, seconds, kelvin, ampere, candela. + "si-linear", + // Radians, gram, seconds, kelvin, ampere, candela. + "si-rotation", + // Inch, slug, seconds, Fahrenheit, ampere, candela. + "english-linear", + // Degrees, slug, seconds, Fahrenheit, ampere, candela. + "english-rotation", + "vendor-defined", + "reserved", +}; + [ Exposed(Window WebHID), SecureContext @@ -39,18 +61,6 @@ readonly attribute unsigned long usageMinimum; readonly attribute unsigned long usageMaximum; - // The minimum and maximum designator indices associated with this item. If - // there are no designators, both are set to zero. - // TODO(mattreynolds): Expose the designators instead of the indices. - readonly attribute unsigned long designatorMinimum; - readonly attribute unsigned long designatorMaximum; - - // The minimum and maximum string indices associated with this item. If - // there are no designators, both are set to zero. - // TODO(mattreynolds): Expose the strings instead of the indices. - readonly attribute unsigned long stringMinimum; - readonly attribute unsigned long stringMaximum; - // The size of a single field described by this item, in bits. readonly attribute unsigned short reportSize; @@ -62,12 +72,21 @@ // kilograms |unitExponent| would be 3 and for micrograms it would be -6. readonly attribute unsigned long unitExponent; - // A value that specifies the unit factors that make up the units for this - // report item. See the units table in section 6.2.2.7 of the Device Class - // Definition for HID, v1.11. - // https://www.usb.org/document-library/device-class-definition-hid-111 - // TODO(mattreynolds): Split this into its component nibbles. - readonly attribute unsigned long unit; + // The unit system determines which units are used for length, mass, time, + // temperature, current, and luminous intensity. May be "none" if the values + // for this report item are unitless. + readonly attribute HIDUnitSystem unitSystem; + + // The following members determine the exponents for each factor of the + // unit definition. For instance, for acceleration all factors would have + // an exponent of 0 except |unitFactorLengthExponent| which would be 1 and + // |unitFactorTimeExponent| which would be -2. + readonly attribute byte unitFactorLengthExponent; + readonly attribute byte unitFactorMassExponent; + readonly attribute byte unitFactorTimeExponent; + readonly attribute byte unitFactorTemperatureExponent; + readonly attribute byte unitFactorCurrentExponent; + readonly attribute byte unitFactorLuminousIntensityExponent; // The minimum and maximum values that may be represented by this input. A // device with |hasNull| may report a value outside this range to indicate @@ -79,4 +98,7 @@ // and |unitExponent|. readonly attribute long physicalMinimum; readonly attribute long physicalMaximum; + + // The strings associated with this item. + readonly attribute FrozenArray<DOMString> strings; };
diff --git a/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.h b/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.h index a360819..5e0755f 100644 --- a/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.h +++ b/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.h
@@ -7,11 +7,12 @@ #include <memory> +#include "base/callback.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_checker.h" -#include "third_party/blink/public/platform/scoped_web_callbacks.h" +#include "third_party/blink/public/platform/web_callbacks.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_video_sink.h" #include "third_party/blink/renderer/bindings/core/v8/callback_promise_adapter.h" #include "third_party/skia/include/core/SkRefCnt.h" @@ -23,6 +24,99 @@ class ImageBitmap; class WebMediaStreamTrack; +// A ScopedWebCallbacks is a move-only scoper which helps manage the lifetime of +// a blink::WebCallbacks object. This is particularly useful when you're +// simultaneously dealing with the following two conditions: +// +// 1. Your WebCallbacks implementation requires either onSuccess or onError to +// be called before it's destroyed. This is the case with +// CallbackPromiseAdapter for example, because its underlying +// ScriptPromiseResolver must be resolved or rejected before destruction. +// +// 2. You are passing ownership of the WebCallbacks to code which may +// silenty drop it. A common way for this to happen is to bind the +// WebCallbacks as an argument to a base::Callback which gets destroyed +// before it can run. +// +// While it's possible to individually track the lifetime of pending +// WebCallbacks, this becomes cumbersome when dealing with many different +// callbacks types. ScopedWebCallbacks provides a generic and relatively +// lightweight solution to this problem. +// +// Example usage: +// +// using FooCallbacks = blink::WebCallbacks<const Foo&, const FooError&>; +// +// void RespondWithSuccess(ScopedWebCallbacks<FooCallbacks> callbacks) { +// callbacks.PassCallbacks()->onSuccess(Foo("everything is great")); +// } +// +// void OnCallbacksDropped(std::unique_ptr<FooCallbacks> callbacks) { +// // Ownership of the FooCallbacks is passed to this function if +// // ScopedWebCallbacks::PassCallbacks isn't called before the +// // ScopedWebCallbacks is destroyed. +// callbacks->onError(FooError("everything is terrible")); +// } +// +// // Blink client implementation +// void FooClientImpl::doMagic(std::unique_ptr<FooCallbacks> callbacks) { +// auto scoped_callbacks = make_scoped_web_callbacks( +// std::move(callbacks), base::BindOnce(&OnCallbacksDropped)); +// +// // Call to some lower-level service which may never run the callback we +// // give it. +// foo_service_->DoMagic(base::BindOnce(&RespondWithSuccess, +// std::move(scoped_callbacks))); +// } +// +// If the bound RespondWithSuccess callback actually runs, PassCallbacks() will +// reliquish ownership of the WebCallbacks object to a temporary scoped_ptr +// which will be destroyed immediately after onSuccess is called. +// +// If the bound RespondWithSuccess callback is instead destroyed first, +// the ScopedWebCallbacks destructor will invoke OnCallbacksDropped, executing +// our desired default behavior before deleting the WebCallbacks. +template <typename CallbacksType> +class ScopedWebCallbacks { + public: + using DestructionCallback = + base::OnceCallback<void(std::unique_ptr<CallbacksType> callbacks)>; + + ScopedWebCallbacks(std::unique_ptr<CallbacksType> callbacks, + DestructionCallback destruction_callback) + : callbacks_(std::move(callbacks)), + destruction_callback_(std::move(destruction_callback)) {} + + ~ScopedWebCallbacks() { + if (destruction_callback_) + std::move(destruction_callback_).Run(std::move(callbacks_)); + } + + ScopedWebCallbacks(ScopedWebCallbacks&& other) = default; + ScopedWebCallbacks(const ScopedWebCallbacks& other) = delete; + + ScopedWebCallbacks& operator=(ScopedWebCallbacks&& other) = default; + ScopedWebCallbacks& operator=(const ScopedWebCallbacks& other) = delete; + + std::unique_ptr<CallbacksType> PassCallbacks() { + destruction_callback_ = DestructionCallback(); + return std::move(callbacks_); + } + + private: + std::unique_ptr<CallbacksType> callbacks_; + DestructionCallback destruction_callback_; +}; + +template <typename CallbacksType> +ScopedWebCallbacks<CallbacksType> MakeScopedWebCallbacks( + std::unique_ptr<CallbacksType> callbacks, + typename ScopedWebCallbacks<CallbacksType>::DestructionCallback + destruction_callback) { + return ScopedWebCallbacks<CallbacksType>(std::move(callbacks), + std::move(destruction_callback)); +} + using ImageCaptureGrabFrameCallbacks = CallbackPromiseAdapter<ImageBitmap, void>;
diff --git a/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.cc b/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.cc index 7a2c2a8..4e2e108 100644 --- a/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.cc +++ b/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.cc
@@ -448,9 +448,13 @@ HTMLDivElement::Trace(visitor); } -void MediaControlsTouchlessImpl::OnMediaMenuResultForTest( - mojom::blink::MenuResponsePtr response) { - OnMediaMenuResult(std::move(response)); +void MediaControlsTouchlessImpl::SetMediaControlsMenuHostForTesting( + mojom::blink::MediaControlsMenuHostPtr menu_host) { + media_controls_host_ = std::move(menu_host); +} + +void MediaControlsTouchlessImpl::MenuHostFlushForTesting() { + media_controls_host_.FlushForTesting(); } } // namespace blink
diff --git a/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h b/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h index 9b569cc..b3d86bd5 100644 --- a/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h +++ b/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h
@@ -71,7 +71,9 @@ MediaControlsTouchlessMediaEventListener& MediaEventListener() const; // Test functions - void OnMediaMenuResultForTest(mojom::blink::MenuResponsePtr); + void SetMediaControlsMenuHostForTesting( + mojom::blink::MediaControlsMenuHostPtr); + void MenuHostFlushForTesting(); void Trace(blink::Visitor*) override;
diff --git a/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl_test.cc b/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl_test.cc index 2bf9fdb..388a69c 100644 --- a/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl_test.cc +++ b/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl_test.cc
@@ -8,12 +8,14 @@ #include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/mojom/media_controls/touchless/media_controls.mojom-blink.h" #include "third_party/blink/renderer/core/css/css_property_value_set.h" #include "third_party/blink/renderer/core/dom/dom_token_list.h" #include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/dom/element_traversal.h" #include "third_party/blink/renderer/core/events/keyboard_event.h" #include "third_party/blink/renderer/core/frame/settings.h" +#include "third_party/blink/renderer/core/fullscreen/fullscreen.h" #include "third_party/blink/renderer/core/geometry/dom_rect.h" #include "third_party/blink/renderer/core/html/media/html_media_element.h" #include "third_party/blink/renderer/core/html/media/html_media_test_helper.h" @@ -23,6 +25,7 @@ #include "third_party/blink/renderer/core/html/track/text_track_list.h" #include "third_party/blink/renderer/core/loader/empty_clients.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" +#include "third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.h" #include "third_party/blink/renderer/platform/keyboard_codes.h" #include "third_party/blink/renderer/platform/testing/empty_web_media_player.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" @@ -31,14 +34,27 @@ namespace { +const char kTextTracksOffString[] = "Off"; + +class LocalePlatformSupport : public TestingPlatformSupport { + public: + WebString QueryLocalizedString(WebLocalizedString::Name name) override { + if (name == WebLocalizedString::kTextTracksOff) + return kTextTracksOffString; + return TestingPlatformSupport::QueryLocalizedString(name); + } +}; + class MockWebMediaPlayerForTouchlessImpl : public EmptyWebMediaPlayer { public: WebTimeRanges Seekable() const override { return seekable_; } bool HasVideo() const override { return true; } + bool HasAudio() const override { return has_audio_; } WebTimeRanges Buffered() const override { return buffered_; } WebTimeRanges buffered_; WebTimeRanges seekable_; + bool has_audio_ = false; }; class MockChromeClientForTouchlessImpl : public EmptyChromeClient { @@ -52,6 +68,14 @@ return screen_info; } + void EnterFullscreen(LocalFrame& frame, const FullscreenOptions*) final { + Fullscreen::DidEnterFullscreen(*frame.GetDocument()); + } + + void ExitFullscreen(LocalFrame& frame) final { + Fullscreen::DidExitFullscreen(*frame.GetDocument()); + } + void SetOrientation(WebScreenOrientationType orientation_type) { orientation_ = orientation_type; } @@ -66,6 +90,7 @@ void InitializePage() { Page::PageClients clients; + FillWithEmptyClients(clients); chrome_client_ = MakeGarbageCollected<MockChromeClientForTouchlessImpl>(); clients.chrome_client = chrome_client_; @@ -78,6 +103,11 @@ ToHTMLVideoElement(*GetDocument().QuerySelector("video")); media_controls_ = static_cast<MediaControlsTouchlessImpl*>(video.GetMediaControls()); + + test_media_controls_host_ = std::make_unique<TestMediaControlsMenuHost>(); + + media_controls_->SetMediaControlsMenuHostForTesting( + test_media_controls_host_->CreateMediaControlsMenuHostPtr()); } MediaControlsTouchlessImpl& MediaControls() { return *media_controls_; } @@ -88,6 +118,10 @@ MediaElement().GetWebMediaPlayer()); } + TestMenuHostArgList& GetMenuHostArgList() { + return test_media_controls_host_->GetMenuHostArgList(); + } + void SimulateKeydownEvent(Element& element, int key_code) { KeyboardEventInit* keyboard_event_init = KeyboardEventInit::Create(); keyboard_event_init->setKeyCode(key_code); @@ -114,6 +148,8 @@ return !element->classList().contains("transparent"); } + void SetHasAudio(bool has_audio) { WebMediaPlayer()->has_audio_ = has_audio; } + Element* GetControlByShadowPseudoId(const char* shadow_pseudo_id) { for (Element& element : ElementTraversal::DescendantsOf(MediaControls())) { if (element.ShadowPseudoId() == shadow_pseudo_id) @@ -126,12 +162,15 @@ chrome_client_->SetOrientation(orientation_type); } - void SimulateClickOnMenuItem(mojom::blink::MenuItem menu_item, - int track_index) { - mojom::blink::MenuResponsePtr response(mojom::blink::MenuResponse::New()); - response->clicked = menu_item; - response->track_index = track_index; - media_controls_->OnMediaMenuResultForTest(std::move(response)); + void SetMenuResponse(mojom::blink::MenuItem menu_item, int track_index = -1) { + test_media_controls_host_->SetMenuResponse(menu_item, track_index); + } + + void SetMenuResponseAndShowMenu(mojom::blink::MenuItem menu_item, + int track_index = -1) { + SetMenuResponse(menu_item, track_index); + MediaControls().ShowContextMenu(); + MediaControls().MenuHostFlushForTesting(); } void CheckControlKeys(int seek_forward_key, @@ -161,6 +200,7 @@ private: Persistent<MediaControlsTouchlessImpl> media_controls_; Persistent<MockChromeClientForTouchlessImpl> chrome_client_; + std::unique_ptr<TestMediaControlsMenuHost> test_media_controls_host_; }; class MediaControlsTouchlessImplTestWithMockScheduler @@ -333,47 +373,69 @@ volume_bar_height / volume_bar_background_height, error); } -/** (jazzhsu@) TODO: Add mojom binding test and fix the following test. -TEST_F(MediaControlsTouchlessImplTest, ContextMenuTest) { - // Fullscreen buttom test. - EXPECT_FALSE(MediaElement().IsFullscreen()); - SimulateClickOnMenuItem(mojom::blink::MenuItem::FULLSCREEN, -1); +TEST_F(MediaControlsTouchlessImplTest, ContextMenuMojomTest) { + ScopedTestingPlatformSupport<LocalePlatformSupport> support; + + MediaControls().MediaElement().SetSrc("https://example.com/foo.mp4"); + std::unique_ptr<UserGestureIndicator> user_gesture_scope = + LocalFrame::NotifyUserActivation(GetDocument().GetFrame(), + UserGestureToken::kNewGesture); test::RunPendingTasks(); + + KeyboardEventInit* keyboard_event_init = KeyboardEventInit::Create(); + keyboard_event_init->setKey("SoftRight"); + Event* keyboard_event = + MakeGarbageCollected<KeyboardEvent>("keydown", keyboard_event_init); + + // Test fullscreen function. + SetMenuResponse(mojom::blink::MenuItem::FULLSCREEN); + MediaElement().DispatchEvent(*keyboard_event); + MediaControls().MenuHostFlushForTesting(); + test::RunPendingTasks(); + + TestMenuHostArgList& arg_list = GetMenuHostArgList(); + EXPECT_EQ((int)arg_list.menu_items.size(), 2); + EXPECT_EQ(arg_list.menu_items[0], mojom::blink::MenuItem::FULLSCREEN); + EXPECT_EQ(arg_list.menu_items[1], mojom::blink::MenuItem::DOWNLOAD); + EXPECT_FALSE(arg_list.video_state->is_fullscreen); EXPECT_TRUE(MediaElement().IsFullscreen()); - SimulateClickOnMenuItem(mojom::blink::MenuItem::FULLSCREEN, -1); + + SetMenuResponseAndShowMenu(mojom::blink::MenuItem::FULLSCREEN); test::RunPendingTasks(); + + EXPECT_TRUE(arg_list.video_state->is_fullscreen); EXPECT_FALSE(MediaElement().IsFullscreen()); - // Mute buttom test. - EXPECT_FALSE(MediaElement().muted()); - SimulateClickOnMenuItem(mojom::blink::MenuItem::MUTE, -1); + // Disable download and show mute option. + MediaElement().GetDocument().GetSettings()->SetHideDownloadUI(true); + SetHasAudio(true); + + SetMenuResponseAndShowMenu(mojom::blink::MenuItem::MUTE); + + EXPECT_EQ((int)arg_list.menu_items.size(), 2); + EXPECT_EQ(arg_list.menu_items[1], mojom::blink::MenuItem::MUTE); + EXPECT_FALSE(arg_list.video_state->is_muted); EXPECT_TRUE(MediaElement().muted()); - SimulateClickOnMenuItem(mojom::blink::MenuItem::MUTE, -1); + + SetMenuResponseAndShowMenu(mojom::blink::MenuItem::MUTE); + + EXPECT_TRUE(arg_list.video_state->is_muted); EXPECT_FALSE(MediaElement().muted()); - // Text track test. - TextTrack* track1 = MediaElement().addTextTrack("subtitle", "english", - "en", NASSERT_NO_EXCEPTION); - TextTrack* track2 = MediaElement().addTextTrack("subtitle", "english2", - "en", ASSERT_NO_EXCEPTION); - EXPECT_NE(track1->mode(), TextTrack::ShowingKeyword()); - EXPECT_NE(track2->mode(), TextTrack::ShowingKeyword()); + // Disable mute option and show text track option. + SetHasAudio(false); + TextTrack* track = MediaElement().addTextTrack("subtitles", "english", "en", + ASSERT_NO_EXCEPTION); + SetMenuResponseAndShowMenu(mojom::blink::MenuItem::CAPTIONS, 0); - // Select first track. - SimulateClickOnMenuItem(mojom::blink::MenuItem::CAPTIONS, 0); - EXPECT_EQ(track1->mode(), TextTrack::ShowingKeyword()); + EXPECT_EQ((int)arg_list.menu_items.size(), 2); + EXPECT_EQ(arg_list.menu_items[1], mojom::blink::MenuItem::CAPTIONS); + EXPECT_EQ(arg_list.text_tracks[1]->label, "english"); + EXPECT_EQ(track->mode(), TextTrack::ShowingKeyword()); - // Select second track. - SimulateClickOnMenuItem(mojom::blink::MenuItem::CAPTIONS, 1); - EXPECT_NE(track1->mode(), TextTrack::ShowingKeyword()); - EXPECT_EQ(track2->mode(), TextTrack::ShowingKeyword()); - - // Turn all tracks off. - SimulateClickOnMenuItem(mojom::blink::MenuItem::CAPTIONS, -1); - EXPECT_NE(track1->mode(), TextTrack::ShowingKeyword()); - EXPECT_NE(track2->mode(), TextTrack::ShowingKeyword()); + SetMenuResponseAndShowMenu(mojom::blink::MenuItem::CAPTIONS, -1); + EXPECT_NE(track->mode(), TextTrack::ShowingKeyword()); } -*/ TEST_F(MediaControlsTouchlessImplTestWithMockScheduler, MidOverlayHideTimerTest) {
diff --git a/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.cc b/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.cc new file mode 100644 index 0000000..d878077 --- /dev/null +++ b/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.cc
@@ -0,0 +1,47 @@ +// 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 "third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.h" + +namespace blink { + +mojom::blink::MediaControlsMenuHostPtr +TestMediaControlsMenuHost::CreateMediaControlsMenuHostPtr() { + mojom::blink::MediaControlsMenuHostPtr ptr; + binding_.Bind(mojo::MakeRequest(&ptr)); + return ptr; +} + +void TestMediaControlsMenuHost::ShowMediaMenu( + const WTF::Vector<mojom::MenuItem>& menu_items, + mojom::blink::VideoStatePtr video_state, + base::Optional<WTF::Vector<mojom::blink::TextTrackMetadataPtr>> text_tracks, + ShowMediaMenuCallback callback) { + arg_list_.menu_items = WTF::Vector<mojom::MenuItem>(menu_items); + + arg_list_.video_state = mojom::blink::VideoState::New(); + arg_list_.video_state->is_fullscreen = video_state->is_fullscreen; + arg_list_.video_state->is_muted = video_state->is_muted; + + arg_list_.text_tracks = WTF::Vector<mojom::blink::TextTrackMetadataPtr>( + std::move(text_tracks.value())); + + std::move(callback).Run(std::move(response_)); +} + +TestMenuHostArgList& TestMediaControlsMenuHost::GetMenuHostArgList() { + return arg_list_; +} + +void TestMediaControlsMenuHost::SetMenuResponse( + mojom::blink::MenuItem menu_item, + int track_index) { + if (response_.is_null()) + response_ = mojom::blink::MenuResponse::New(); + + response_->clicked = menu_item; + response_->track_index = track_index; +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.h b/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.h new file mode 100644 index 0000000..4378945 --- /dev/null +++ b/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.h
@@ -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. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_TEST_MEDIA_CONTROLS_MENU_HOST_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_TEST_MEDIA_CONTROLS_MENU_HOST_H_ + +#include "mojo/public/cpp/bindings/binding.h" +#include "third_party/blink/public/mojom/media_controls/touchless/media_controls.mojom-blink.h" + +namespace blink { + +struct TestMenuHostArgList { + WTF::Vector<mojom::MenuItem> menu_items; + mojom::blink::VideoStatePtr video_state; + WTF::Vector<mojom::blink::TextTrackMetadataPtr> text_tracks; +}; + +class TestMediaControlsMenuHost : public mojom::blink::MediaControlsMenuHost { + public: + mojom::blink::MediaControlsMenuHostPtr CreateMediaControlsMenuHostPtr(); + void ShowMediaMenu( + const WTF::Vector<mojom::MenuItem>& menu_items, + mojom::blink::VideoStatePtr video_state, + base::Optional<WTF::Vector<mojom::blink::TextTrackMetadataPtr>> + text_tracks, + ShowMediaMenuCallback callback) override; + + TestMenuHostArgList& GetMenuHostArgList(); + void SetMenuResponse(mojom::blink::MenuItem menu_item, int track_index); + + private: + mojo::Binding<mojom::blink::MediaControlsMenuHost> binding_{this}; + TestMenuHostArgList arg_list_; + mojom::blink::MenuResponsePtr response_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_TEST_MEDIA_CONTROLS_MENU_HOST_H_
diff --git a/third_party/blink/renderer/modules/modules_idl_files.gni b/third_party/blink/renderer/modules/modules_idl_files.gni index 02b352d..76aa479 100644 --- a/third_party/blink/renderer/modules/modules_idl_files.gni +++ b/third_party/blink/renderer/modules/modules_idl_files.gni
@@ -71,6 +71,7 @@ "background_fetch/background_fetch_registration.idl", "background_fetch/background_fetch_update_ui_event.idl", "background_sync/sync_event.idl", + "background_sync/periodic_sync_event.idl", "background_sync/sync_manager.idl", "badging/experimental_badge.idl", "battery/battery_manager.idl", @@ -549,6 +550,7 @@ "background_fetch/background_fetch_options.idl", "background_fetch/background_fetch_ui_options.idl", "background_sync/sync_event_init.idl", + "background_sync/periodic_sync_event_init.idl", "bluetooth/bluetooth_advertising_event_init.idl", "bluetooth/bluetooth_le_scan_filter_init.idl", "bluetooth/bluetooth_le_scan_options.idl",
diff --git a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc index f9d590b..ebd2193 100644 --- a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc +++ b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc
@@ -142,12 +142,20 @@ video_element->GetWebMediaPlayer()->OnRequestPictureInPicture(); + session_observer_binding_.Close(); + + mojom::blink::PictureInPictureSessionObserverPtr session_observer; + scoped_refptr<base::SingleThreadTaskRunner> task_runner = + element->GetDocument().GetTaskRunner(TaskType::kMediaElementEvent); + session_observer_binding_.Bind( + mojo::MakeRequest(&session_observer, task_runner), task_runner); + picture_in_picture_service_->StartSession( video_element->GetWebMediaPlayer()->GetDelegateId(), video_element->GetWebMediaPlayer()->GetSurfaceId(), video_element->GetWebMediaPlayer()->NaturalSize(), ShouldShowPlayPauseButton(*video_element), - ShouldShowMuteButton(*video_element), + ShouldShowMuteButton(*video_element), std::move(session_observer), WTF::Bind(&PictureInPictureControllerImpl::OnEnteredPictureInPicture, WrapPersistent(this), WrapPersistent(video_element), WrapPersistent(resolver))); @@ -156,24 +164,26 @@ void PictureInPictureControllerImpl::OnEnteredPictureInPicture( HTMLVideoElement* element, ScriptPromiseResolver* resolver, + mojom::blink::PictureInPictureSessionPtr session_ptr, const WebSize& picture_in_picture_window_size) { + picture_in_picture_session_ = std::move(session_ptr); + if (IsElementAllowed(*element) != Status::kEnabled) { if (resolver) { resolver->Reject( DOMException::Create(DOMExceptionCode::kInvalidStateError, "")); } + ExitPictureInPicture(element, nullptr); return; } + if (picture_in_picture_element_) + OnExitedPictureInPicture(nullptr); + picture_in_picture_element_ = element; - picture_in_picture_element_->OnEnteredPictureInPicture(); - // Closes the current Picture-in-Picture window if any. - if (picture_in_picture_window_) - picture_in_picture_window_->OnClose(); - picture_in_picture_window_ = MakeGarbageCollected<PictureInPictureWindow>( GetSupplementable(), picture_in_picture_window_size); @@ -182,20 +192,6 @@ event_type_names::kEnterpictureinpicture, WrapPersistent(picture_in_picture_window_.Get()))); - if (!EnsureService()) - return; - - if (delegate_binding_.is_bound()) - delegate_binding_.Close(); - - mojom::blink::PictureInPictureDelegatePtr delegate; - scoped_refptr<base::SingleThreadTaskRunner> task_runner = - picture_in_picture_element_->GetDocument().GetTaskRunner( - TaskType::kMediaElementEvent); - delegate_binding_.Bind(mojo::MakeRequest(&delegate, task_runner), - task_runner); - picture_in_picture_service_->SetDelegate(std::move(delegate)); - if (resolver) resolver->Resolve(picture_in_picture_window_); } @@ -206,10 +202,10 @@ if (!EnsureService()) return; - picture_in_picture_service_->EndSession( + picture_in_picture_session_->Stop( WTF::Bind(&PictureInPictureControllerImpl::OnExitedPictureInPicture, WrapPersistent(this), WrapPersistent(resolver))); - delegate_binding_.Close(); + session_observer_binding_.Close(); } void PictureInPictureControllerImpl::OnExitedPictureInPicture( @@ -341,14 +337,14 @@ void PictureInPictureControllerImpl::ContextDestroyed(Document*) { picture_in_picture_service_.reset(); - delegate_binding_.Close(); + session_observer_binding_.Close(); } void PictureInPictureControllerImpl::OnPictureInPictureStateChange() { DCHECK(picture_in_picture_element_); DCHECK(picture_in_picture_element_->GetWebMediaPlayer()); - picture_in_picture_service_->UpdateSession( + picture_in_picture_session_->Update( picture_in_picture_element_->GetWebMediaPlayer()->GetDelegateId(), picture_in_picture_element_->GetWebMediaPlayer()->GetSurfaceId(), picture_in_picture_element_->GetWebMediaPlayer()->NaturalSize(), @@ -356,12 +352,16 @@ ShouldShowMuteButton(*picture_in_picture_element_)); } -void PictureInPictureControllerImpl::PictureInPictureWindowSizeChanged( +void PictureInPictureControllerImpl::OnWindowSizeChanged( const blink::WebSize& size) { if (picture_in_picture_window_) picture_in_picture_window_->OnResize(size); } +void PictureInPictureControllerImpl::OnStopped() { + // TODO(940694): implement OnStopped() and remove IPC message. +} + bool PictureInPictureControllerImpl::ShouldShowMuteButton( const HTMLVideoElement& element) { DCHECK(GetSupplementable()); @@ -382,7 +382,7 @@ Document& document) : PictureInPictureController(document), PageVisibilityObserver(document.GetPage()), - delegate_binding_(this) {} + session_observer_binding_(this) {} bool PictureInPictureControllerImpl::EnsureService() { if (picture_in_picture_service_)
diff --git a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h index 3dc7ec8..94bd45c4 100644 --- a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h +++ b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h
@@ -32,7 +32,7 @@ : public PictureInPictureController, public PageVisibilityObserver, public DocumentShutdownObserver, - public blink::mojom::blink::PictureInPictureDelegate { + public blink::mojom::blink::PictureInPictureSessionObserver { USING_GARBAGE_COLLECTED_MIXIN(PictureInPictureControllerImpl); public: @@ -80,8 +80,9 @@ bool IsPictureInPictureElement(const Element*) const override; void OnPictureInPictureStateChange() override; - // Implementation of PictureInPictureDelegate. - void PictureInPictureWindowSizeChanged(const blink::WebSize&) override; + // Implementation of PictureInPictureSessionObserver. + void OnWindowSizeChanged(const blink::WebSize&) override; + void OnStopped() override; // Implementation of PageVisibilityObserver. void PageVisibilityChanged() override; @@ -91,15 +92,16 @@ void Trace(blink::Visitor*) override; - mojo::Binding<mojom::blink::PictureInPictureDelegate>& - GetDelegateBindingForTesting() { - return delegate_binding_; + mojo::Binding<mojom::blink::PictureInPictureSessionObserver>& + GetSessionObserverBindingForTesting() { + return session_observer_binding_; } private: void OnEnteredPictureInPicture(HTMLVideoElement*, ScriptPromiseResolver*, - const WebSize& picture_in_picture_window_size); + mojom::blink::PictureInPictureSessionPtr, + const WebSize&); void OnExitedPictureInPicture(ScriptPromiseResolver*) override; // Makes sure the `picture_in_picture_service_` is set. Returns whether it was @@ -120,12 +122,16 @@ // The Picture-in-Picture window for the associated document. Member<PictureInPictureWindow> picture_in_picture_window_; - // Mojo bindings for the delegate interface implemented by |this|. - mojo::Binding<mojom::blink::PictureInPictureDelegate> delegate_binding_; + // Mojo bindings for the session observer interface implemented by |this|. + mojo::Binding<mojom::blink::PictureInPictureSessionObserver> + session_observer_binding_; // Picture-in-Picture service living in the browser process. mojom::blink::PictureInPictureServicePtr picture_in_picture_service_; + // Instance of the Picture-in-Picture session sent back by the service. + mojom::blink::PictureInPictureSessionPtr picture_in_picture_session_; + DISALLOW_COPY_AND_ASSIGN(PictureInPictureControllerImpl); };
diff --git a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_test.cc b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_test.cc index 72a0fc88..5b14eff 100644 --- a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_test.cc +++ b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_test.cc
@@ -25,6 +25,33 @@ namespace blink { +// The MockPictureInPictureSession implements a PictureInPicture session in the +// same process as the test and guarantees that the callbacks are called in +// order for the events to be fired. +class MockPictureInPictureSession + : public mojom::blink::PictureInPictureSession { + public: + MockPictureInPictureSession( + mojo::InterfaceRequest<mojom::blink::PictureInPictureSession> request) + : binding_(this, std::move(request)) { + ON_CALL(*this, Stop(_)).WillByDefault([](StopCallback callback) { + std::move(callback).Run(); + }); + } + ~MockPictureInPictureSession() override = default; + + MOCK_METHOD1(Stop, void(StopCallback)); + MOCK_METHOD5(Update, + void(uint32_t, + const base::Optional<viz::SurfaceId>&, + const blink::WebSize&, + bool, + bool)); + + private: + mojo::Binding<mojom::blink::PictureInPictureSession> binding_; +}; + // The MockPictureInPictureService implements the PictureInPicture service in // the same process as the test and guarantees that the callbacks are called in // order for the events to be fired. @@ -33,41 +60,45 @@ public: MockPictureInPictureService() : binding_(this) { // Setup default implementations. - ON_CALL(*this, StartSession(_, _, _, _, _, _)) - .WillByDefault([](uint32_t, const base::Optional<viz::SurfaceId>&, - const blink::WebSize&, bool, bool, - StartSessionCallback callback) { - std::move(callback).Run(WebSize()); - }); - ON_CALL(*this, EndSession(_)) - .WillByDefault( - [](EndSessionCallback callback) { std::move(callback).Run(); }); + ON_CALL(*this, StartSession(_, _, _, _, _, _, _)) + .WillByDefault(testing::Invoke( + this, &MockPictureInPictureService::StartSessionInternal)); } ~MockPictureInPictureService() override = default; void Bind(mojo::ScopedMessagePipeHandle handle) { binding_.Bind( mojom::blink::PictureInPictureServiceRequest(std::move(handle))); + + session_.reset( + new MockPictureInPictureSession(mojo::MakeRequest(&session_ptr_))); } - MOCK_METHOD6(StartSession, + MOCK_METHOD7(StartSession, void(uint32_t, const base::Optional<viz::SurfaceId>&, const blink::WebSize&, bool, bool, + mojom::blink::PictureInPictureSessionObserverPtr, StartSessionCallback)); - MOCK_METHOD1(EndSession, void(EndSessionCallback)); - MOCK_METHOD5(UpdateSession, - void(uint32_t, - const base::Optional<viz::SurfaceId>&, - const blink::WebSize&, - bool, - bool)); - MOCK_METHOD1(SetDelegate, void(mojom::blink::PictureInPictureDelegatePtr)); + + MockPictureInPictureSession& Session() { return *session_.get(); } + + void StartSessionInternal(uint32_t, + const base::Optional<viz::SurfaceId>&, + const blink::WebSize&, + bool, + bool, + mojom::blink::PictureInPictureSessionObserverPtr, + StartSessionCallback callback) { + std::move(callback).Run(std::move(session_ptr_), WebSize()); + } private: mojo::Binding<mojom::blink::PictureInPictureService> binding_; + std::unique_ptr<MockPictureInPictureSession> session_; + mojom::blink::PictureInPictureSessionPtr session_ptr_; DISALLOW_COPY_AND_ASSIGN(MockPictureInPictureService); }; @@ -167,8 +198,7 @@ WebMediaPlayer* player = Video()->GetWebMediaPlayer(); EXPECT_CALL(Service(), StartSession(player->GetDelegateId(), player->GetSurfaceId(), - player->NaturalSize(), true, false, _)); - EXPECT_CALL(Service(), SetDelegate(_)); + player->NaturalSize(), true, false, _, _)); PictureInPictureControllerImpl::From(GetDocument()) .EnterPictureInPicture(Video(), nullptr /* options */, @@ -179,9 +209,6 @@ EXPECT_NE(nullptr, PictureInPictureControllerImpl::From(GetDocument()) .PictureInPictureElement()); - - // `SetDelegate()` may or may not have been called yet. Waiting a bit for it. - test::RunPendingTasks(); } TEST_F(PictureInPictureControllerTest, ExitPictureInPictureFiresEvent) { @@ -191,14 +218,14 @@ WebMediaPlayer* player = Video()->GetWebMediaPlayer(); EXPECT_CALL(Service(), StartSession(player->GetDelegateId(), player->GetSurfaceId(), - player->NaturalSize(), true, false, _)); - EXPECT_CALL(Service(), EndSession(_)); - EXPECT_CALL(Service(), SetDelegate(_)); + player->NaturalSize(), true, false, _, _)); PictureInPictureControllerImpl::From(GetDocument()) .EnterPictureInPicture(Video(), nullptr /* options */, nullptr /* promise */); + EXPECT_CALL(Service().Session(), Stop(_)); + MakeGarbageCollected<WaitForEvent>(Video(), event_type_names::kEnterpictureinpicture); @@ -214,14 +241,13 @@ TEST_F(PictureInPictureControllerTest, StartObserving) { EXPECT_FALSE(PictureInPictureControllerImpl::From(GetDocument()) - .GetDelegateBindingForTesting() + .GetSessionObserverBindingForTesting() .is_bound()); WebMediaPlayer* player = Video()->GetWebMediaPlayer(); EXPECT_CALL(Service(), StartSession(player->GetDelegateId(), player->GetSurfaceId(), - player->NaturalSize(), true, false, _)); - EXPECT_CALL(Service(), SetDelegate(_)); + player->NaturalSize(), true, false, _, _)); PictureInPictureControllerImpl::From(GetDocument()) .EnterPictureInPicture(Video(), nullptr /* options */, @@ -231,28 +257,26 @@ event_type_names::kEnterpictureinpicture); EXPECT_TRUE(PictureInPictureControllerImpl::From(GetDocument()) - .GetDelegateBindingForTesting() + .GetSessionObserverBindingForTesting() .is_bound()); - - // `SetDelegate()` may or may not have been called yet. Waiting a bit for it. - test::RunPendingTasks(); } TEST_F(PictureInPictureControllerTest, StopObserving) { EXPECT_FALSE(PictureInPictureControllerImpl::From(GetDocument()) - .GetDelegateBindingForTesting() + .GetSessionObserverBindingForTesting() .is_bound()); WebMediaPlayer* player = Video()->GetWebMediaPlayer(); EXPECT_CALL(Service(), StartSession(player->GetDelegateId(), player->GetSurfaceId(), - player->NaturalSize(), true, false, _)); - EXPECT_CALL(Service(), EndSession(_)); - EXPECT_CALL(Service(), SetDelegate(_)); + player->NaturalSize(), true, false, _, _)); PictureInPictureControllerImpl::From(GetDocument()) .EnterPictureInPicture(Video(), nullptr /* options */, nullptr /* promise */); + + EXPECT_CALL(Service().Session(), Stop(_)); + MakeGarbageCollected<WaitForEvent>(Video(), event_type_names::kEnterpictureinpicture); @@ -262,7 +286,7 @@ event_type_names::kLeavepictureinpicture); EXPECT_FALSE(PictureInPictureControllerImpl::From(GetDocument()) - .GetDelegateBindingForTesting() + .GetSessionObserverBindingForTesting() .is_bound()); } @@ -275,8 +299,7 @@ WebMediaPlayer* player = Video()->GetWebMediaPlayer(); EXPECT_CALL(Service(), StartSession(player->GetDelegateId(), player->GetSurfaceId(), - player->NaturalSize(), false, false, _)); - EXPECT_CALL(Service(), SetDelegate(_)); + player->NaturalSize(), false, false, _, _)); PictureInPictureControllerImpl::From(GetDocument()) .EnterPictureInPicture(Video(), nullptr /* options */, @@ -284,9 +307,6 @@ MakeGarbageCollected<WaitForEvent>(Video(), event_type_names::kEnterpictureinpicture); - - // `SetDelegate()` may or may not have been called yet. Waiting a bit for it. - test::RunPendingTasks(); } TEST_F(PictureInPictureControllerTest, PlayPauseButton_MediaSource) { @@ -299,8 +319,7 @@ WebMediaPlayer* player = Video()->GetWebMediaPlayer(); EXPECT_CALL(Service(), StartSession(player->GetDelegateId(), player->GetSurfaceId(), - player->NaturalSize(), false, false, _)); - EXPECT_CALL(Service(), SetDelegate(_)); + player->NaturalSize(), false, false, _, _)); PictureInPictureControllerImpl::From(GetDocument()) .EnterPictureInPicture(Video(), nullptr /* options */, @@ -308,9 +327,6 @@ MakeGarbageCollected<WaitForEvent>(Video(), event_type_names::kEnterpictureinpicture); - - // `SetDelegate()` may or may not have been called yet. Waiting a bit for it. - test::RunPendingTasks(); } TEST_F(PictureInPictureControllerTest, PerformMediaPlayerAction) {
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.cc index 4389ab3..c94a014 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.cc
@@ -271,6 +271,12 @@ client_.DidHandleSyncEvent(sync_event_id, status); } +void ServiceWorkerGlobalScopeClient::DidHandlePeriodicSyncEvent( + int periodic_sync_event_id, + mojom::ServiceWorkerEventStatus status) { + client_.DidHandlePeriodicSyncEvent(periodic_sync_event_id, status); +} + void ServiceWorkerGlobalScopeClient::DidHandleAbortPaymentEvent( int abort_payment_event_id, mojom::ServiceWorkerEventStatus status) {
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h index 6649b7c0f3..62adc28 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h
@@ -126,7 +126,10 @@ void DidHandleNotificationCloseEvent(int event_id, mojom::ServiceWorkerEventStatus); void DidHandlePushEvent(int push_event_id, mojom::ServiceWorkerEventStatus); - void DidHandleSyncEvent(int sync_event_id, mojom::ServiceWorkerEventStatus); + void DidHandleSyncEvent(int sync_event_id, + mojom::ServiceWorkerEventStatus status); + void DidHandlePeriodicSyncEvent(int periodic_sync_event_id, + mojom::ServiceWorkerEventStatus status); void DidHandleAbortPaymentEvent(int abort_payment_event_id, mojom::ServiceWorkerEventStatus); void DidHandleCanMakePaymentEvent(int payment_request_event_id,
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc index 31da8c6..628117f5 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc
@@ -60,6 +60,7 @@ #include "third_party/blink/renderer/modules/background_fetch/background_fetch_event_init.h" #include "third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h" #include "third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.h" +#include "third_party/blink/renderer/modules/background_sync/periodic_sync_event.h" #include "third_party/blink/renderer/modules/background_sync/sync_event.h" #include "third_party/blink/renderer/modules/cookie_store/cookie_change_event.h" #include "third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.h" @@ -531,6 +532,19 @@ WorkerGlobalScope(), WaitUntilObserver::kSync, event_id); Event* event = SyncEvent::Create(event_type_names::kSync, id, last_chance, observer); + + WorkerGlobalScope()->DispatchExtendableEvent(event, observer); +} + +void ServiceWorkerGlobalScopeProxy::DispatchPeriodicSyncEvent( + int event_id, + const WebString& id) { + DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_); + WaitUntilObserver* observer = WaitUntilObserver::Create( + WorkerGlobalScope(), WaitUntilObserver::kPeriodicSync, event_id); + Event* event = + PeriodicSyncEvent::Create(event_type_names::kPeriodicsync, id, observer); + WorkerGlobalScope()->DispatchExtendableEvent(event, observer); }
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h index c2ff4b0..fa37add7 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h
@@ -127,7 +127,11 @@ const WebString& notification_id, const WebNotificationData&) override; void DispatchPushEvent(int, const WebString& data) override; - void DispatchSyncEvent(int, const WebString& tag, bool last_chance) override; + void DispatchSyncEvent(int sync_event_id, + const WebString& tag, + bool last_chance) override; + void DispatchPeriodicSyncEvent(int periodic_sync_event_id, + const WebString& tag) override; void DispatchAbortPaymentEvent(int) override; void DispatchCanMakePaymentEvent(int, const WebCanMakePaymentEventData&) override;
diff --git a/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc b/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc index c81e4fd..eab8cda 100644 --- a/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc +++ b/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc
@@ -291,6 +291,9 @@ case kSync: client->DidHandleSyncEvent(event_id_, status); break; + case kPeriodicSync: + client->DidHandlePeriodicSyncEvent(event_id_, status); + break; case kPaymentRequest: client->DidHandlePaymentRequestEvent(event_id_, status); break;
diff --git a/third_party/blink/renderer/modules/service_worker/wait_until_observer.h b/third_party/blink/renderer/modules/service_worker/wait_until_observer.h index 4a80d125..8769b1e 100644 --- a/third_party/blink/renderer/modules/service_worker/wait_until_observer.h +++ b/third_party/blink/renderer/modules/service_worker/wait_until_observer.h
@@ -42,6 +42,7 @@ kPaymentRequest, kPush, kSync, + kPeriodicSync, kBackgroundFetchAbort, kBackgroundFetchClick, kBackgroundFetchFail,
diff --git a/third_party/blink/renderer/modules/xr/OWNERS b/third_party/blink/renderer/modules/xr/OWNERS index c42d16c5..04300e66 100644 --- a/third_party/blink/renderer/modules/xr/OWNERS +++ b/third_party/blink/renderer/modules/xr/OWNERS
@@ -1,3 +1,4 @@ +alcooper@chromium.org bajones@chromium.org klausw@chromium.org
diff --git a/third_party/blink/renderer/modules/xr/xr.cc b/third_party/blink/renderer/modules/xr/xr.cc index 21226d3..72c10b9 100644 --- a/third_party/blink/renderer/modules/xr/xr.cc +++ b/third_party/blink/renderer/modules/xr/xr.cc
@@ -477,6 +477,9 @@ EventTargetWithInlineData::AddedEventListener(event_type, registered_listener); + if (!service_) + return; + if (event_type == event_type_names::kDevicechange) { // Register for notifications if we haven't already. //
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc b/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc index 4b4e536..99839fe 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc
@@ -80,7 +80,7 @@ uint32_t GetFieldTrialUint32Param(const char* trial_name, const char* parameter_name, uint32_t default_param) { - std::map<std::string, std::string> trial_params; + base::FieldTrialParams trial_params; bool result = base::GetFieldTrialParams(trial_name, &trial_params); if (!result) return default_param;
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc index d0ef938..618e42a63 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
@@ -1532,9 +1532,9 @@ public: ResourceFetchPriorityExperimentTest() : FrameSchedulerImplTest({kUseResourceFetchPriority}, {}) { - std::map<std::string, std::string> params{ - {"HIGHEST", "HIGH"}, {"MEDIUM", "NORMAL"}, {"LOW", "NORMAL"}, - {"LOWEST", "LOW"}, {"IDLE", "LOW"}, {"THROTTLED", "LOW"}}; + base::FieldTrialParams params{{"HIGHEST", "HIGH"}, {"MEDIUM", "NORMAL"}, + {"LOW", "NORMAL"}, {"LOWEST", "LOW"}, + {"IDLE", "LOW"}, {"THROTTLED", "LOW"}}; const char kStudyName[] = "ResourceFetchPriorityExperiment"; const char kGroupName[] = "GroupName1"; @@ -1567,9 +1567,9 @@ public: ResourceFetchPriorityExperimentOnlyWhenLoadingTest() : FrameSchedulerImplTest({kUseResourceFetchPriorityOnlyWhenLoading}, {}) { - std::map<std::string, std::string> params{ - {"HIGHEST", "HIGH"}, {"MEDIUM", "NORMAL"}, {"LOW", "NORMAL"}, - {"LOWEST", "LOW"}, {"IDLE", "LOW"}, {"THROTTLED", "LOW"}}; + base::FieldTrialParams params{{"HIGHEST", "HIGH"}, {"MEDIUM", "NORMAL"}, + {"LOW", "NORMAL"}, {"LOWEST", "LOW"}, + {"IDLE", "LOW"}, {"THROTTLED", "LOW"}}; const char kStudyName[] = "ResourceFetchPriorityExperiment"; const char kGroupName[] = "GroupName2"; @@ -1746,9 +1746,8 @@ class ThrottleAndFreezeTaskTypesExperimentTest : public FrameSchedulerImplTest { public: - ThrottleAndFreezeTaskTypesExperimentTest( - std::map<std::string, std::string> params, - const char* group_name) { + ThrottleAndFreezeTaskTypesExperimentTest(const base::FieldTrialParams& params, + const char* group_name) { const char kStudyName[] = "ThrottleAndFreezeTaskTypes"; field_trial_list_ = std::make_unique<base::FieldTrialList>(nullptr); @@ -1772,7 +1771,7 @@ public: ThrottleableAndFreezableTaskTypesTest() : ThrottleAndFreezeTaskTypesExperimentTest( - std::map<std::string, std::string>{ + base::FieldTrialParams{ // Leading spaces are allowed. {kThrottleableTaskTypesListParam, "PostedMessage"}, {kFreezableTaskTypesListParam, @@ -1826,7 +1825,7 @@ public: FreezableOnlyTaskTypesTest() : ThrottleAndFreezeTaskTypesExperimentTest( - std::map<std::string, std::string>{ + base::FieldTrialParams{ {kThrottleableTaskTypesListParam, ""}, {kFreezableTaskTypesListParam, "PostedMessage,MediaElementEvent,DOMManipulation"}}, @@ -1880,7 +1879,7 @@ public: ThrottleableOnlyTaskTypesTest() : ThrottleAndFreezeTaskTypesExperimentTest( - std::map<std::string, std::string>{ + base::FieldTrialParams{ {kFreezableTaskTypesListParam, ""}, {kThrottleableTaskTypesListParam, "PostedMessage"}}, "Group3") {}
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc index bc5df91..ee6bbd0 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
@@ -565,7 +565,7 @@ if (use_resource_fetch_priority || use_resource_priorities_only_during_loading) { - std::map<std::string, std::string> params; + base::FieldTrialParams params; base::GetFieldTrialParams(kResourceFetchPriorityExperiment, ¶ms); for (size_t net_priority = 0; net_priority < net::RequestPrioritySize::NUM_PRIORITIES;
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc index 174520e..23af8563 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
@@ -68,10 +68,9 @@ base::Optional<base::TimeDelta> initial_budget; }; -double GetDoubleParameterFromMap( - const std::map<std::string, std::string>& settings, - const std::string& setting_name, - double default_value) { +double GetDoubleParameterFromMap(const base::FieldTrialParams& settings, + const std::string& setting_name, + double default_value) { const auto& find_it = settings.find(setting_name); if (find_it == settings.end()) return default_value; @@ -90,7 +89,7 @@ } BackgroundThrottlingSettings GetBackgroundThrottlingSettings() { - std::map<std::string, std::string> background_throttling_settings; + base::FieldTrialParams background_throttling_settings; base::GetFieldTrialParams("ExpensiveBackgroundTimerThrottling", &background_throttling_settings);
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc index 7c3435f9..3b4e8159 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc
@@ -1075,16 +1075,16 @@ } void InitializeTrialParams() { - std::map<std::string, std::string> params = {{"cpu_budget", "0.01"}, - {"max_budget", "0.0"}, - {"initial_budget", "0.0"}, - {"max_delay", "0.0"}}; + base::FieldTrialParams params = {{"cpu_budget", "0.01"}, + {"max_budget", "0.0"}, + {"initial_budget", "0.0"}, + {"max_delay", "0.0"}}; const char kParamName[] = "ExpensiveBackgroundTimerThrottling"; const char kGroupName[] = "Enabled"; EXPECT_TRUE(base::AssociateFieldTrialParams(kParamName, kGroupName, params)); EXPECT_TRUE(base::FieldTrialList::CreateFieldTrial(kParamName, kGroupName)); - std::map<std::string, std::string> actual_params; + base::FieldTrialParams actual_params; base::GetFieldTrialParams(kParamName, &actual_params); EXPECT_EQ(actual_params, params); }
diff --git a/third_party/blink/renderer/platform/weborigin/OWNERS b/third_party/blink/renderer/platform/weborigin/OWNERS index 306592d..bf1d39f 100644 --- a/third_party/blink/renderer/platform/weborigin/OWNERS +++ b/third_party/blink/renderer/platform/weborigin/OWNERS
@@ -1,4 +1,3 @@ -darin@chromium.org tsepez@chromium.org # TEAM: platform-architecture-dev@chromium.org
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json index fa373d0..f92e556e 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
@@ -95111,18 +95111,6 @@ {} ] ], - "css/filter-effects/backdrop-filter-clip-rect-zoom.html": [ - [ - "css/filter-effects/backdrop-filter-clip-rect-zoom.html", - [ - [ - "/css/filter-effects/backdrop-filter-clip-rect-zoom-ref.html", - "==" - ] - ], - {} - ] - ], "css/filter-effects/backdrop-filter-clip-rect.html": [ [ "css/filter-effects/backdrop-filter-clip-rect.html", @@ -95164,7 +95152,7 @@ "css/filter-effects/backdrop-filter-isolation-fixed.html", [ [ - "/css/filter-effects/backdrop-filter-isolation-ref.html", + "/css/filter-effects/backdrop-filter-non-isolation-ref.html", "==" ] ], @@ -95176,7 +95164,7 @@ "css/filter-effects/backdrop-filter-isolation-isolate.html", [ [ - "/css/filter-effects/backdrop-filter-isolation-ref.html", + "/css/filter-effects/backdrop-filter-non-isolation-ref.html", "==" ] ], @@ -158244,11 +158232,6 @@ {} ] ], - "css/filter-effects/backdrop-filter-clip-rect-zoom-ref.html": [ - [ - {} - ] - ], "css/filter-effects/backdrop-filter-edge-pixels-ref.html": [ [ {} @@ -158264,6 +158247,11 @@ {} ] ], + "css/filter-effects/backdrop-filter-non-isolation-ref.html": [ + [ + {} + ] + ], "css/filter-effects/backdrop-filter-paint-order-ref.html": [ [ {} @@ -165069,6 +165057,11 @@ {} ] ], + "feature-policy/experimental-features/resources/focus_steal.html": [ + [ + {} + ] + ], "feature-policy/experimental-features/resources/image.jpg": [ [ {} @@ -193614,6 +193607,11 @@ {} ] ], + "tools/ci/website_build.sh": [ + [ + {} + ] + ], "tools/conftest.py": [ [ {} @@ -193624,6 +193622,11 @@ {} ] ], + "tools/docker/documentation/Dockerfile": [ + [ + {} + ] + ], "tools/docker/github/Dockerfile": [ [ {} @@ -231521,6 +231524,12 @@ {} ] ], + "css/css-grid/grid-definition/grid-change-auto-repeat-tracks.html": [ + [ + "css/css-grid/grid-definition/grid-change-auto-repeat-tracks.html", + {} + ] + ], "css/css-grid/grid-definition/grid-change-fit-content-argument-001.html": [ [ "css/css-grid/grid-definition/grid-change-fit-content-argument-001.html", @@ -256389,6 +256398,12 @@ {} ] ], + "feature-policy/experimental-features/focus-without-user-activation-tentative.sub.html": [ + [ + "feature-policy/experimental-features/focus-without-user-activation-tentative.sub.html", + {} + ] + ], "feature-policy/experimental-features/intrinsicsize-with-unsized-media.tentative.https.sub.html": [ [ "feature-policy/experimental-features/intrinsicsize-with-unsized-media.tentative.https.sub.html", @@ -324868,6 +324883,12 @@ {} ] ], + "webxr/webxr-supported-by-feature-policy.html": [ + [ + "webxr/webxr-supported-by-feature-policy.html", + {} + ] + ], "webxr/webxr_availability.http.sub.html": [ [ "webxr/webxr_availability.http.sub.html", @@ -336735,7 +336756,7 @@ }, "paths": { ".github/main.workflow": [ - "4ff7845b9d23ad55724b78950bc94d7d5a7a9e5e", + "4f4447fdf0ff12f0910d20f16e6e31c9dd696749", "support" ], ".gitignore": [ @@ -386458,6 +386479,10 @@ "085d94996f1142d11f9f9c6076e6d9afc025c39c", "reftest" ], + "css/css-grid/grid-definition/grid-change-auto-repeat-tracks.html": [ + "33fcb248c26e00fe541d5081c9e34710c811788a", + "testharness" + ], "css/css-grid/grid-definition/grid-change-fit-content-argument-001.html": [ "9441b0a439e1bbdcd3954af439a49ac162a513a1", "testharness" @@ -422866,14 +422891,6 @@ "9082fa32de3bd022245d5f2c3a75c354674ff38e", "support" ], - "css/filter-effects/backdrop-filter-clip-rect-zoom-ref.html": [ - "5e43c7df922c27b104c3b2e6a975932e4ab70da2", - "support" - ], - "css/filter-effects/backdrop-filter-clip-rect-zoom.html": [ - "36f0b1b38bc6d8eb832a8d088ffa5ea3fb3e9877", - "reftest" - ], "css/filter-effects/backdrop-filter-clip-rect.html": [ "4fc4b739ddb5a316ca6ca4706940c04df96e57d3", "reftest" @@ -422895,11 +422912,11 @@ "reftest" ], "css/filter-effects/backdrop-filter-isolation-fixed.html": [ - "a3c3fa25a85077b8297feae745d2ab5cd9e24b23", + "f7835a151fad448121bc25e7c944f4c33bcfa4a4", "reftest" ], "css/filter-effects/backdrop-filter-isolation-isolate.html": [ - "88dd91ac8fe3c033a999315b342cbe82a482721f", + "008f6f845da0d8dc80e1af3b808c3789dc2e9ca0", "reftest" ], "css/filter-effects/backdrop-filter-isolation-ref.html": [ @@ -422910,6 +422927,10 @@ "500228df08162d4a946058e2252d225209a6d4e1", "reftest" ], + "css/filter-effects/backdrop-filter-non-isolation-ref.html": [ + "0453d7f2feda3367e0f7536d91b0b159d627dd5d", + "support" + ], "css/filter-effects/backdrop-filter-paint-order-ref.html": [ "bd82e520f0e70b75e45c687cb46f957a579e2358", "support" @@ -437046,6 +437067,10 @@ "7e09ef7e77a632f81fcc115271c9a74143bd34a7", "testharness" ], + "feature-policy/experimental-features/focus-without-user-activation-tentative.sub.html": [ + "ad90864fa472cbaa3f95a3fbc912529f31fb3765", + "testharness" + ], "feature-policy/experimental-features/intrinsicsize-with-unsized-media.tentative.https.sub.html": [ "9d4757f81ebe83544d428ff5a7161d6c69cdc795", "testharness" @@ -437146,6 +437171,10 @@ "a0008eea82455b370f65de5f58b285420c2ba30b", "support" ], + "feature-policy/experimental-features/resources/focus_steal.html": [ + "43e8688117d7ae01169793edb9392a03350749e5", + "support" + ], "feature-policy/experimental-features/resources/image.jpg": [ "430f5c514a86f110293636b513b396ac1ab5ed80", "support" @@ -462475,7 +462504,7 @@ "reftest" ], "lint.whitelist": [ - "f6411453345c249a4378709631569710a70945d2", + "06fcea129fe52a6631cffc839b9ba9e6139da32a", "support" ], "loading/preloader-css-import-no-quote.tentative.html": [ @@ -486183,7 +486212,7 @@ "support" ], "resources/chromium/web-bluetooth-test.js": [ - "db8f5480b8399775b8a4e3fad709eb28bf2ecd8b", + "4c89463dcd2fcf902f9072b656316c8ade3bf824", "support" ], "resources/chromium/web-bluetooth-test.js.headers": [ @@ -494422,6 +494451,10 @@ "91c763a7acdd3416d7eff55407bf8f73b840d96a", "support" ], + "tools/ci/website_build.sh": [ + "66593eb55290a9711c3e74b7786a91fd1be2a4e0", + "support" + ], "tools/conftest.py": [ "021a49fc297303b6e4178c427422d91813dbb762", "support" @@ -494430,6 +494463,10 @@ "e60b4ea6a3a1c909c715fb7248a6f1b0cc6e9d4e", "support" ], + "tools/docker/documentation/Dockerfile": [ + "e01f98e4d4df0e7f7501bb5d7057d1d528221bde", + "support" + ], "tools/docker/github/Dockerfile": [ "22d47f3e5fa9032e5f016f6f15720fa98e1ba625", "support" @@ -506891,7 +506928,7 @@ "support" ], "webvr/webvr-supported-by-feature-policy.html": [ - "9487c3516b7ca6f6bbe1384e2083ad2281a669cc", + "416e286c04cbeb9581903d96a18b0662c3357cf9", "testharness" ], "webvtt/META.yml": [ @@ -509974,6 +510011,10 @@ "3102008c57db1e32a0910eabfc93c55809b8300c", "testharness" ], + "webxr/webxr-supported-by-feature-policy.html": [ + "6d0531055c585fd3979a785b01fafdc748f4c6d0", + "testharness" + ], "webxr/webxr_availability.http.sub.html": [ "515b2ad1a8d015120032ea56c473922a2af73e85", "testharness"
diff --git a/third_party/blink/web_tests/external/wpt/.github/main.workflow b/third_party/blink/web_tests/external/wpt/.github/main.workflow index 4ff7845..4f4447f 100644 --- a/third_party/blink/web_tests/external/wpt/.github/main.workflow +++ b/third_party/blink/web_tests/external/wpt/.github/main.workflow
@@ -8,3 +8,14 @@ runs = ["python", "tools/ci/manifest_build.py"] secrets = ["GITHUB_TOKEN"] } + +workflow "Build & Publish Documentation Website" { + on = "push" + resolves = ["website-build-and-publish"] +} + +action "website-build-and-publish" { + uses = "./tools/docker/documentation" + runs = ["/bin/bash", "tools/ci/website_build.sh"] + secrets = ["DEPLOY_TOKEN"] +}
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/window-open-noopener_indexed-expected.txt b/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/window-open-noopener_indexed-expected.txt deleted file mode 100644 index f678e2d..0000000 --- a/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/window-open-noopener_indexed-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -This is a testharness.js-based test. -FAIL window.open() with 'noopener' should reuse existing target assert_equals: Should still have opener expected true but got false -FAIL noopener=1 means the same as noopener assert_equals: Should still have opener expected true but got false -PASS noopener=0 means lack of noopener -FAIL noopener separated only by spaces should work assert_equals: Should still have opener expected true but got false -FAIL Trailing noopener should work assert_equals: Should still have opener expected true but got false -FAIL Leading noopener should work assert_equals: Should still have opener expected true but got false -FAIL Interior noopener should work assert_equals: Should still have opener expected true but got false -FAIL noreferrer should also suppress opener when reusing existing target assert_equals: Should still have opener expected true but got false -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/lint.whitelist b/third_party/blink/web_tests/external/wpt/lint.whitelist index f641145..06fcea1 100644 --- a/third_party/blink/web_tests/external/wpt/lint.whitelist +++ b/third_party/blink/web_tests/external/wpt/lint.whitelist
@@ -76,6 +76,8 @@ WEB-PLATFORM.TEST:README.md WEB-PLATFORM.TEST:*/README.md WEB-PLATFORM.TEST:docs/* +INDENT TABS:docs/* +CR AT EOL:docs/* ## Helper scripts ##
diff --git a/third_party/blink/web_tests/external/wpt/tools/ci/website_build.sh b/third_party/blink/web_tests/external/wpt/tools/ci/website_build.sh new file mode 100755 index 0000000..66593eb --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/tools/ci/website_build.sh
@@ -0,0 +1,91 @@ +#!/bin/bash + +set -ex + +neutral_status=78 +source_revision=$(git rev-parse HEAD) +# The token available in the `GITHUB_TOKEN` variable may be used to push to the +# repository, but GitHub Pages will not rebuild the website in response to such +# events. Use an access token generated for the project's machine user, +# wpt-pr-bot. +# +# https://help.github.com/en/articles/generic-jekyll-build-failures +remote_url=https://${DEPLOY_TOKEN}@github.com/web-platform-tests/wpt.git + +function json_property { + cat ${1} | \ + python -c "import json, sys; print json.load(sys.stdin).get(\"${2}\", \"\")" +} + +function is_pull_request { + test -n "$(json_property ${GITHUB_EVENT_PATH} pull_request)" +} + +function targets_master { + test $(json_property ${GITHUB_EVENT_PATH} ref) == 'refs/heads/master' +} + +function modifies_relevant_files { + base_revision=$(json_property ${GITHUB_EVENT_PATH} before) + + git diff --name-only ${base_revision} | \ + grep -E --silent '^(docs|tools)/' +} + +if is_pull_request ; then + echo Submission comes from a pull request. Exiting without building. + + exit ${neutral_status} +fi + +if ! targets_master ; then + echo Submission does not target the 'master' branch. Exiting without building. + + exit ${neutral_status} +fi + +if ! modifies_relevant_files ; then + echo No files related to the website have been modified. Exiting without + echo building. + + exit ${neutral_status} +fi + +git config --global user.email "wpt-pr-bot@users.noreply.github.com" +git config --global user.name "wpt-pr-bot" + +# Prepare the output directory so that the new build can be pushed to the +# repository as an incremental change to the prior build. +mkdir --parents docs/_build/html +cd docs/_build/html +git init +git fetch --depth 1 ${remote_url} gh-pages +git checkout FETCH_HEAD +git rm -r . + +# Build the website +cd ../.. +pip install -r requirements.txt +make html + +cd _build/html +# Configure DNS +echo web-platform-tests.org > CNAME +# Disable Jekyll +# https://github.blog/2009-12-29-bypassing-jekyll-on-github-pages/ +touch .nojekyll + +# Publish the website by pushing the built contents to the `gh-pages` branch +git add . + +if ! git diff --exit-code --quiet --staged ; then + echo No change to the website contents. Exiting without publishing. + + exit ${neutral_status} +fi + +git commit --message "Build documentation + +These files were generated from commit ${source_revision}" + +git push --force ${remote_url} HEAD:gh-pages
diff --git a/third_party/blink/web_tests/external/wpt/tools/docker/documentation/Dockerfile b/third_party/blink/web_tests/external/wpt/tools/docker/documentation/Dockerfile new file mode 100644 index 0000000..e01f98e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/tools/docker/documentation/Dockerfile
@@ -0,0 +1,3 @@ +FROM python:2-stretch + +RUN apt-get update && apt-get install --yes git
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 89335df..195b031 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
@@ -2369,7 +2369,6 @@ getter featureReports getter inputReports getter outputReports - getter reportIds getter usage getter usagePage method constructor @@ -2405,8 +2404,6 @@ method constructor interface HIDReportItem attribute @@toStringTag - getter designatorMaximum - getter designatorMinimum getter hasNull getter isAbsolute getter isArray @@ -2417,10 +2414,15 @@ getter physicalMinimum getter reportCount getter reportSize - getter stringMaximum - getter stringMinimum - getter unit + getter strings getter unitExponent + getter unitFactorCurrentExponent + getter unitFactorLengthExponent + getter unitFactorLuminousIntensityExponent + getter unitFactorMassExponent + getter unitFactorTemperatureExponent + getter unitFactorTimeExponent + getter unitSystem getter usageMaximum getter usageMinimum getter usages
diff --git a/third_party/cacheinvalidation/BUILD.gn b/third_party/cacheinvalidation/BUILD.gn index 3b055f3..c137cef 100644 --- a/third_party/cacheinvalidation/BUILD.gn +++ b/third_party/cacheinvalidation/BUILD.gn
@@ -134,7 +134,7 @@ android_library("cacheinvalidation_javalib") { chromium_code = false - emma_never_instrument = true + jacoco_never_instrument = true deps = [ ":cacheinvalidation_proto_java", "$google_play_services_package:google_play_services_gcm_java",
diff --git a/third_party/jacoco/BUILD.gn b/third_party/jacoco/BUILD.gn index 0d06a82..9ce40ff 100644 --- a/third_party/jacoco/BUILD.gn +++ b/third_party/jacoco/BUILD.gn
@@ -18,7 +18,8 @@ } java_prebuilt("jacocoagent_java") { - testonly = true + include_java_resources = true + supports_android = true jar_path = "lib/jacocoagent.jar" }
diff --git a/third_party/jacoco/OWNERS b/third_party/jacoco/OWNERS index e121426..fb9288c 100644 --- a/third_party/jacoco/OWNERS +++ b/third_party/jacoco/OWNERS
@@ -1,3 +1,4 @@ +agrieve@chromium.org bjoyce@chromium.org aluo@chromium.org yzjr@chromium.org
diff --git a/third_party/pyjson5/src/benchmarks/mb_config.json b/third_party/pyjson5/src/benchmarks/mb_config.json index af93ef0f..fc3a96a 100644 --- a/third_party/pyjson5/src/benchmarks/mb_config.json +++ b/third_party/pyjson5/src/benchmarks/mb_config.json
@@ -1966,7 +1966,7 @@ "gn_args": "internal_gles2_conform_tests=true" }, "java_coverage": { - "gn_args": "emma_coverage=true emma_filter=\"org.chromium.*\"" + "gn_args": "jacoco_coverage=true" }, "libfuzzer": { "gn_args": "use_libfuzzer=true"
diff --git a/third_party/webxr_test_pages/OWNERS b/third_party/webxr_test_pages/OWNERS index 58b4c46a..86ae16e 100644 --- a/third_party/webxr_test_pages/OWNERS +++ b/third_party/webxr_test_pages/OWNERS
@@ -1,3 +1,4 @@ +alcooper@chromium.org bajones@chromium.org bialpio@chromium.org billorr@chromium.org
diff --git a/tools/android/errorprone_plugin/BUILD.gn b/tools/android/errorprone_plugin/BUILD.gn index e61b0c4..2df1476 100644 --- a/tools/android/errorprone_plugin/BUILD.gn +++ b/tools/android/errorprone_plugin/BUILD.gn
@@ -19,8 +19,8 @@ enable_errorprone = false enable_bytecode_rewriter = false - # So that we don't need to inject emma runtime into the compiler's classpath. - emma_never_instrument = true + # So that we don't need to inject jacoco runtime into the compiler's classpath. + jacoco_never_instrument = true annotation_processor_deps = [ "//third_party/auto:auto_service_processor" ] deps = [
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 7c6d35e..2946bd0 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -2209,7 +2209,7 @@ }, 'java_coverage': { - 'gn_args': 'emma_coverage=true emma_filter="org.chromium.*"', + 'gn_args': 'jacoco_coverage=true', }, 'jumbo': {
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index da4f905..c7a7e0d 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -7012,6 +7012,9 @@ </enum> <enum name="ChromeChannelForHistogram"> + <obsolete> + Relevant histogram (DidSuppressJavaScriptException) expired 2018-08. + </obsolete> <int value="0" label="UNKNOWN"/> <int value="1" label="CANARY"/> <int value="2" label="DEV"/> @@ -8846,6 +8849,7 @@ <int value="21" label="QUIC/43"/> <int value="22" label="QUIC/99"/> <int value="23" label="QUIC/44"/> + <int value="27" label="QUIC/999"/> </enum> <enum name="ConnectionResult"> @@ -16834,6 +16838,7 @@ <int value="562" label="DockedMagnifierEnabled"/> <int value="563" label="AppRecommendationZeroStateEnabled"/> <int value="564" label="BrowserSwitcherExternalGreylistUrl"/> + <int value="565" label="PolicyDictionaryMultipleSourceMergeList"/> </enum> <enum name="EnterprisePolicyInvalidations"> @@ -40610,6 +40615,48 @@ label="cbad7b1d384849df0946b7ee8e7f5f7ce3aed876fda7bc9d30d8b16f29ff2c53"/> <int value="493" label="e0c780c629903e126f1d919570dce7c496f85f33aae66b9a3147ee75f8d1620a"/> + <int value="494" + label="376a1a7082a593dccc20d561d119e9ab8d30f11cc321d0a37fa41f0df284e01c"/> + <int value="495" + label="8d417db2dd8bf5e3084d1e3f196d583849d81bdd4c00c70b9d39369e96b8c782"/> + <int value="496" + label="b7408b4d2be0238ba37004dd34e276c6019bd2f24c9db7d4980f5f6c359a4bcc"/> + <int value="497" + label="eabc185c4e82d942b1a5978ba3c0181487d6b3b9974e5c49f72f6d0bd9637150"/> + <int value="498" + label="2541e53ba5b3b07acbe7097ac4a03e040c11cf7a6d4a67cb213d558b50167a06"/> + <int value="499" + label="68ded9a203ff6e367e12aa49977cd200f7127a800faa6f859f0bafed8286a4fb"/> + <int value="500" + label="36d7c79f3d089a0ff79972d90923dea5ca76b4ccbaf7c2751cb152e9494f52d0"/> + <int value="501" + label="be3280c6863c770a33c9040bd97d5540b216d1d91db8b088ceac1197dae1d660"/> + <int value="502" + label="c5750bf85f459fb70e2b6cd1898d375e92d7938e47a6e034cce0c12d30372ccd"/> + <int value="503" + label="22a36994f28f2fa3b16ae872a79dbb12a982da5b824d7ae434f96178ac540351"/> + <int value="504" + label="f26cdaa1c48e2d369eaf24993a424f8290983af7094a5bde9c7d44341f2e2428"/> + <int value="505" + label="c372f6d18ebee5aa23d9e919f3e6be98488ec01607df3162fc192e4b1346afb3"/> + <int value="506" + label="68aa635451d83962167e88fb08f8678d73aec66fc559462137cff9d1bc3d3871"/> + <int value="507" + label="b2f7298b52bf2c3cac4ddfe72de4d682ac58957595982f2b62301af597c699c5"/> + <int value="508" + label="35f53ce1264611e03340fe37e1ec7d4cc986c5613dca70fd04aa44545f2daf28"/> + <int value="509" + label="9091e31fe92546a5f5e1b3ed4071f4440b840c1e80dbfcba7a7ec6d5825f0b24"/> + <int value="510" + label="786ffa578618c3b9a311175e50816f4dda0605c3869f296ebc5943bf09f4e904"/> + <int value="511" + label="828b0eeff24654e8ff5841a29dd5d4e3ed30952ca43425a79283407208d39d16"/> + <int value="512" + label="497128fc90656b87290482b223efb72240fe9c421e79938de5f8110cb0be9056"/> + <int value="513" + label="2e06cae1fc20b200e6fb748557a4444bec9317dfff2e4151669e0f7944f0a9e0"/> + <int value="514" + label="122312c081949106b7049f3febf199c010ada13e3281cd358a41e7bd09c829d7"/> </enum> <enum name="Network3GGobiError"> @@ -50805,7 +50852,9 @@ <int value="28" label="CAN_MAKE_PAYMENT"/> <int value="29" label="ABORT_PAYMENT"/> <int value="30" label="COOKIE_CHANGE"/> - <int value="31" label="BACKGROUND_FETCH_SUCCESS"/> + <int value="31" label="LONG_RUNNING_MESSAGE"/> + <int value="32" label="BACKGROUND_FETCH_SUCCESS"/> + <int value="33" label="PERIODIC_SYNC"/> </enum> <enum name="ServiceWorkerPreparationType">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 15e1ce56..865a0cbc 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -36899,6 +36899,9 @@ <histogram name="Extensions.DidSuppressJavaScriptException" enum="ChromeChannelForHistogram" expires_after="2018-08-30"> + <obsolete> + Expired 2018-08 + </obsolete> <owner>rdevlin.cronin@chromium.org</owner> <summary> Records the Chrome channel when JavaScript exceptions are not gracefully @@ -114349,6 +114352,17 @@ </summary> </histogram> +<histogram name="ServiceWorker.PeriodicBackgroundSyncEvent.Time" units="ms" + expires_after="M87"> + <owner>nator@chromium.org</owner> + <owner>platform-capabilities@chromium.org</owner> + <summary> + The time taken between dispatching a PeriodicSyncEvent to a Service Worker + and receiving a message that it finished handling the event. Includes the + time for the waitUntil() promise to settle. + </summary> +</histogram> + <histogram name="ServiceWorker.PushEvent.Time" units="ms" expires_after="M77"> <owner>peter@chromium.org</owner> <summary>
diff --git a/tools/perf/benchmarks/benchmark_unittest.py b/tools/perf/benchmarks/benchmark_unittest.py index 7222891..e39c2bba 100644 --- a/tools/perf/benchmarks/benchmark_unittest.py +++ b/tools/perf/benchmarks/benchmark_unittest.py
@@ -19,7 +19,7 @@ def _GetAllPerfBenchmarks(): return discover.DiscoverClasses( - path_util.GetPerfBenchmarksDir(), path_util.GetPerfDir(), + path_util.GetOfficialBenchmarksDir(), path_util.GetPerfDir(), benchmark_module.Benchmark, index_by_class_name=True).values()
diff --git a/tools/perf/benchmarks/system_health_unittest.py b/tools/perf/benchmarks/system_health_unittest.py index d6c13849..ace7395 100644 --- a/tools/perf/benchmarks/system_health_unittest.py +++ b/tools/perf/benchmarks/system_health_unittest.py
@@ -17,7 +17,7 @@ def _GetAllSystemHealthBenchmarks(): all_perf_benchmarks = discover.DiscoverClasses( - path_util.GetPerfBenchmarksDir(), path_util.GetPerfDir(), + path_util.GetOfficialBenchmarksDir(), path_util.GetPerfDir(), benchmark_module.Benchmark, index_by_class_name=True).values() return [b for b in all_perf_benchmarks if
diff --git a/tools/perf/core/benchmark_finders.py b/tools/perf/core/benchmark_finders.py index 3d24898..1bc046d 100644 --- a/tools/perf/core/benchmark_finders.py +++ b/tools/perf/core/benchmark_finders.py
@@ -43,12 +43,12 @@ sys.path = original_sys_path -def GetAllPerfBenchmarks(): +def GetOfficialBenchmarks(): """Returns the list of all benchmarks to be run on perf waterfall. The benchmarks are sorted by order of their names. """ benchmarks = discover.DiscoverClasses( - start_dir=path_util.GetPerfBenchmarksDir(), + start_dir=path_util.GetOfficialBenchmarksDir(), top_level_dir=path_util.GetPerfDir(), base_class=benchmark_module.Benchmark, index_by_class_name=True).values() @@ -56,12 +56,12 @@ return benchmarks -def GetAllContribBenchmarks(): +def GetContribBenchmarks(): """Returns the list of all contrib benchmarks. The benchmarks are sorted by order of their names. """ benchmarks = discover.DiscoverClasses( - start_dir=path_util.GetPerfContribDir(), + start_dir=path_util.GetContribDir(), top_level_dir=path_util.GetPerfDir(), base_class=benchmark_module.Benchmark, index_by_class_name=True).values() @@ -73,9 +73,9 @@ """Returns all benchmarks in tools/perf directory. The benchmarks are sorted by order of their names. """ - all_perf_benchmarks = GetAllPerfBenchmarks() - all_contrib_benchmarks = GetAllContribBenchmarks() - benchmarks = all_perf_benchmarks + all_contrib_benchmarks + waterfall_benchmarks = GetOfficialBenchmarks() + contrib_benchmarks = GetContribBenchmarks() + benchmarks = waterfall_benchmarks + contrib_benchmarks benchmarks.sort(key=lambda b: b.Name()) return benchmarks
diff --git a/tools/perf/core/bot_platforms.py b/tools/perf/core/bot_platforms.py index 18751ae2..521cea3 100644 --- a/tools/perf/core/bot_platforms.py +++ b/tools/perf/core/bot_platforms.py
@@ -10,12 +10,12 @@ _SHARD_MAP_DIR = os.path.join(os.path.dirname(__file__), 'shard_maps') -_ALL_TELEMETRY_BENCHMARKS_BY_NAMES= dict( +_ALL_BENCHMARKS_BY_NAMES= dict( (b.Name(), b) for b in benchmark_finders.GetAllBenchmarks()) -_ALL_PERF_WATERFALL_TELEMETRY_BENCHMARKS = frozenset( - benchmark_finders.GetAllPerfBenchmarks()) +_OFFICIAL_BENCHMARKS = frozenset( + benchmark_finders.GetOfficialBenchmarks()) def _IsPlatformSupported(benchmark, platform): @@ -38,10 +38,10 @@ if benchmarks_names_to_run: benchmarks = [] for benchmark_name in benchmarks_names_to_run: - benchmarks.append(_ALL_TELEMETRY_BENCHMARKS_BY_NAMES[benchmark_name]) + benchmarks.append(_ALL_BENCHMARKS_BY_NAMES[benchmark_name]) benchmarks_to_run = frozenset(benchmarks) else: - benchmarks_to_run = _ALL_PERF_WATERFALL_TELEMETRY_BENCHMARKS + benchmarks_to_run = _OFFICIAL_BENCHMARKS platform = self._sort_key.split(' ', 1)[0] self._benchmarks_to_run = frozenset([ b for b in benchmarks_to_run if _IsPlatformSupported(b, platform)]) @@ -203,12 +203,12 @@ p for p in locals().values() if isinstance(p, PerfPlatform) } -ALL_PERF_FYI_PLATFORMS = { +FYI_PLATFORMS = { p for p in ALL_PLATFORMS if p.is_fyi } -ALL_PERF_PLATFORMS = { +OFFICIAL_PLATFORMS = { p for p in ALL_PLATFORMS if not p.is_fyi } @@ -218,6 +218,6 @@ } -ALL_PERF_PLATFORM_NAMES = { - p.name for p in ALL_PERF_PLATFORMS +OFFICIAL_PLATFORM_NAMES = { + p.name for p in OFFICIAL_PLATFORMS }
diff --git a/tools/perf/core/path_util.py b/tools/perf/core/path_util.py index dac9205..1976811 100644 --- a/tools/perf/core/path_util.py +++ b/tools/perf/core/path_util.py
@@ -34,11 +34,11 @@ return os.path.join(GetPerfDir(), 'page_sets') -def GetPerfBenchmarksDir(): +def GetOfficialBenchmarksDir(): return os.path.join(GetPerfDir(), 'benchmarks') -def GetPerfContribDir(): +def GetContribDir(): return os.path.join(GetPerfDir(), 'contrib')
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py index d0c1917..c1e4604d 100755 --- a/tools/perf/core/perf_data_generator.py +++ b/tools/perf/core/perf_data_generator.py
@@ -791,7 +791,7 @@ def _get_telemetry_perf_benchmarks_metadata(): metadata = {} - benchmark_list = benchmark_finders.GetAllPerfBenchmarks() + benchmark_list = benchmark_finders.GetOfficialBenchmarks() for benchmark in benchmark_list: emails = decorators.GetEmails(benchmark)
diff --git a/tools/perf/core/perf_json_config_validator.py b/tools/perf/core/perf_json_config_validator.py index 722db78..0b9ba21 100644 --- a/tools/perf/core/perf_json_config_validator.py +++ b/tools/perf/core/perf_json_config_validator.py
@@ -161,14 +161,14 @@ else: raise ValueError('%s has unrecognizable type: %s' % key) if (is_main_perf_waterfall and - perf_testing_builder_names != bot_platforms.ALL_PERF_PLATFORM_NAMES): + perf_testing_builder_names != bot_platforms.OFFICIAL_PLATFORM_NAMES): raise ValueError( 'Found mismatches between actual perf waterfall builders and platforms ' 'in core.bot_platforms. Please update the platforms in ' 'bot_platforms.py.\nPlatforms should be aded to core.bot_platforms:%s' '\nPlatforms should be removed from core.bot_platforms:%s' % ( - perf_testing_builder_names - bot_platforms.ALL_PERF_PLATFORM_NAMES, - bot_platforms.ALL_PERF_PLATFORM_NAMES - perf_testing_builder_names)) + perf_testing_builder_names - bot_platforms.OFFICIAL_PLATFORM_NAMES, + bot_platforms.OFFICIAL_PLATFORM_NAMES - perf_testing_builder_names)) def main(args):
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config index 210b0a0..87e274d 100644 --- a/tools/perf/expectations.config +++ b/tools/perf/expectations.config
@@ -273,6 +273,9 @@ crbug.com/944978 [ Win_7 ] system_health.memory_desktop/multitab:misc:typical24 [ Skip ] crbug.com/934270 [ Win ] system_health.memory_desktop/multitab:misc:typical24:2018 [ Skip ] crbug.com/942952 [ ChromeOS ] system_health.memory_desktop/browse:news:hackernews:2018 [ Skip ] +crbug.com/959418 [ ChromeOS ] system_health.memory_desktop/long_running:tools:gmail-background [ Skip ] +crbug.com/959418 [ ChromeOS ] system_health.memory_desktop/load:games:spychase:2018 [ Skip ] +crbug.com/959418 [ ChromeOS ] system_health.memory_desktop/long_running:tools:gmail-foreground [ Skip ] # Benchmark: system_health.memory_mobile crbug.com/914390 [ Nexus_5 ] system_health.memory_mobile/browse:chrome:newtab [ Skip ]
diff --git a/tools/perf/fetch_benchmark_deps.py b/tools/perf/fetch_benchmark_deps.py index 66eebbfa..20d3b7f7 100755 --- a/tools/perf/fetch_benchmark_deps.py +++ b/tools/perf/fetch_benchmark_deps.py
@@ -128,7 +128,7 @@ raw_input( 'No benchmark name is specified. Fetching all benchmark deps. ' 'Press enter to continue...') - for b in benchmark_finders.GetAllPerfBenchmarks(): + for b in benchmark_finders.GetOfficialBenchmarks(): deps[b.Name()] = _FetchDepsForBenchmark(b) if options.output_deps:
diff --git a/tools/perf/list_benchmarks b/tools/perf/list_benchmarks index 1061f39..1f93edd3 100755 --- a/tools/perf/list_benchmarks +++ b/tools/perf/list_benchmarks
@@ -28,7 +28,7 @@ if options.include_contrib: benchmarks = benchmark_finders.GetAllBenchmarks() else: - benchmarks = benchmark_finders.GetAllPerfBenchmarks() + benchmarks = benchmark_finders.GetOfficialBenchmarks() for b in benchmarks: print '{:<60}'.format(b.Name())
diff --git a/tools/perf/record_wpr b/tools/perf/record_wpr index a288a8c..026a512 100755 --- a/tools/perf/record_wpr +++ b/tools/perf/record_wpr
@@ -13,6 +13,6 @@ if __name__ == '__main__': config = chromium_config.ChromiumConfig( - benchmark_dirs=[path_util.GetPerfBenchmarksDir()], + benchmark_dirs=[path_util.GetOfficialBenchmarksDir()], top_level_dir=path_util.GetPerfDir()) sys.exit(record_wpr.Main(environment=config))
diff --git a/tools/perf/run_benchmark b/tools/perf/run_benchmark index fed3004..ec39769 100755 --- a/tools/perf/run_benchmark +++ b/tools/perf/run_benchmark
@@ -15,8 +15,8 @@ def main(): config = chromium_config.ChromiumConfig( - benchmark_dirs=[path_util.GetPerfBenchmarksDir(), - path_util.GetPerfContribDir()], + benchmark_dirs=[path_util.GetOfficialBenchmarksDir(), + path_util.GetContribDir()], top_level_dir=path_util.GetPerfDir(), expectations_files=[path_util.GetExpectationsPath()]) return benchmark_runner.main(config)
diff --git a/ui/accessibility/ax_node.cc b/ui/accessibility/ax_node.cc index e72aa83..db33d5b 100644 --- a/ui/accessibility/ax_node.cc +++ b/ui/accessibility/ax_node.cc
@@ -26,12 +26,6 @@ parent_(parent), language_info_(nullptr) { data_.id = id; - // If this node is the root, use the given index_in_parent to provide - // consistency. - if (!parent) - unignored_index_in_parent_ = index_in_parent_; - else - unignored_index_in_parent_ = -1; } AXNode::~AXNode() = default; @@ -81,7 +75,15 @@ } int AXNode::GetUnignoredIndexInParent() const { - return unignored_index_in_parent_; + AXNode* parent = GetUnignoredParent(); + if (parent) { + for (int i = 0; i < parent->GetUnignoredChildCount(); ++i) { + if (parent->GetUnignoredChildAtIndex(i) == this) + return i; + } + } + + return 0; } bool AXNode::IsText() const { @@ -115,11 +117,6 @@ index_in_parent_ = index_in_parent; } -void AXNode::UpdateUnignoredIndexInParentForChildren() { - if (!data().HasState(ax::mojom::State::kIgnored)) - ComputeUnignoredIndexInParentForChildrenRecursive(0); -} - void AXNode::SwapChildren(std::vector<AXNode*>& children) { children.swap(children_); } @@ -690,21 +687,6 @@ } } -int AXNode::ComputeUnignoredIndexInParentForChildrenRecursive(int startIndex) { - int count = 0; - for (int i = 0; i < child_count(); i++) { - AXNode* child = children_[i]; - if (child->data().HasState(ax::mojom::State::kIgnored)) { - child->unignored_index_in_parent_ = -1; - count += child->ComputeUnignoredIndexInParentForChildrenRecursive( - startIndex + count); - } else { - child->unignored_index_in_parent_ = startIndex + count++; - } - } - return count; -} - // Finds ordered set that immediately contains node. // Is not required for set's role to match node's role. AXNode* AXNode::GetOrderedSet() const {
diff --git a/ui/accessibility/ax_node.h b/ui/accessibility/ax_node.h index 8dd03db9..a9e2cb69 100644 --- a/ui/accessibility/ax_node.h +++ b/ui/accessibility/ax_node.h
@@ -94,9 +94,6 @@ // Set the index in parent, for example if siblings were inserted or deleted. void SetIndexInParent(int index_in_parent); - // Update the unignored index in parent for unignored children. - void UpdateUnignoredIndexInParentForChildren(); - // Swap the internal children vector with |children|. This instance // now owns all of the passed children. void SwapChildren(std::vector<AXNode*>& children); @@ -311,14 +308,11 @@ void IdVectorToNodeVector(std::vector<int32_t>& ids, std::vector<AXNode*>* nodes) const; - int ComputeUnignoredIndexInParentForChildrenRecursive(int startIndex); - // Finds and returns a pointer to ordered set containing node. AXNode* GetOrderedSet() const; OwnerTree* tree_; // Owns this. int index_in_parent_; - int unignored_index_in_parent_; AXNode* parent_; std::vector<AXNode*> children_; AXNodeData data_;
diff --git a/ui/accessibility/ax_table_info.cc b/ui/accessibility/ax_table_info.cc index 272caaa..7466c2f 100644 --- a/ui/accessibility/ax_table_info.cc +++ b/ui/accessibility/ax_table_info.cc
@@ -376,13 +376,8 @@ data.id = id; data.role = ax::mojom::Role::kColumn; node->SetData(data); - for (AXTreeObserver& observer : tree_->observers()) { + for (AXTreeObserver& observer : tree_->observers()) observer.OnNodeCreated(tree_, node); - observer.OnAtomicUpdateFinished( - tree_, false, - {AXTreeObserver::Change(node, - AXTreeObserver::ChangeType::NODE_CREATED)}); - } return node; } @@ -394,14 +389,8 @@ data.id = id; data.role = ax::mojom::Role::kTableHeaderContainer; node->SetData(data); - - for (AXTreeObserver& observer : tree_->observers()) { + for (AXTreeObserver& observer : tree_->observers()) observer.OnNodeCreated(tree_, node); - observer.OnAtomicUpdateFinished( - tree_, false, - {AXTreeObserver::Change(node, - AXTreeObserver::ChangeType::NODE_CREATED)}); - } return node; }
diff --git a/ui/accessibility/ax_tree.cc b/ui/accessibility/ax_tree.cc index cdd12fc..36e661e 100644 --- a/ui/accessibility/ax_tree.cc +++ b/ui/accessibility/ax_tree.cc
@@ -132,10 +132,6 @@ // decisions about when to notify observers of removals or reparenting. std::set<int> changed_node_ids; - // keeps track of parents whose unignored children have changed. Used for - // caching unignored relationships. - std::unordered_set<int> changed_unignored_parent_ids; - // Keeps track of new nodes created during this update. std::set<const AXNode*> new_nodes; @@ -502,12 +498,6 @@ changes.push_back(AXTreeObserver::Change(node, change)); } - for (int parent_id : update_state.changed_unignored_parent_ids) { - AXNode* parent = GetFromId(parent_id); - if (parent) - parent->UpdateUnignoredIndexInParentForChildren(); - } - // Tree is no longer updating. SetTreeUpdateInProgressState(false); @@ -576,10 +566,6 @@ else observer.OnNodeReparented(this, new_node); } - AXNode* unignored_parent = new_node->GetUnignoredParent(); - if (unignored_parent) { - update_state->changed_unignored_parent_ids.insert(unignored_parent->id()); - } return new_node; } @@ -603,18 +589,10 @@ if (!update_state->IsNewNode(node) || update_state->IsReparentedNode(node)) { auto it = update_state->reparented_node_id_to_data.find(node->id()); - const AXNodeData& old_data = - it != update_state->reparented_node_id_to_data.end() ? it->second - : node->data(); - CallNodeChangeCallbacks(node, old_data, src); - if (old_data.HasState(ax::mojom::State::kIgnored) != - src.HasState(ax::mojom::State::kIgnored)) { - AXNode* unignored_parent = node->GetUnignoredParent(); - if (unignored_parent) { - update_state->changed_unignored_parent_ids.insert( - unignored_parent->id()); - } - } + if (it != update_state->reparented_node_id_to_data.end()) + CallNodeChangeCallbacks(node, it->second, src); + else + CallNodeChangeCallbacks(node, node->data(), src); } UpdateReverseRelations(node, src); node->SetData(src); @@ -873,10 +851,6 @@ for (int i = 0; i < node->child_count(); ++i) DestroyNodeAndSubtree(node->ChildAtIndex(i), update_state); if (update_state) { - AXNode* unignored_parent = node->GetUnignoredParent(); - if (unignored_parent) { - update_state->changed_unignored_parent_ids.insert(unignored_parent->id()); - } update_state->pending_nodes.erase(node); update_state->removed_node_ids.insert(node->id()); } @@ -997,8 +971,8 @@ bool node_is_radio_button = (original_node.data().role == ax::mojom::Role::kRadioButton); - for (int i = 0; i < local_parent->GetUnignoredChildCount(); ++i) { - const AXNode* child = local_parent->GetUnignoredChildAtIndex(i); + for (int i = 0; i < local_parent->child_count(); ++i) { + const AXNode* child = local_parent->ChildAtIndex(i); // Invisible children should not be counted. // However, in the collapsed container case (e.g. a combobox), items can
diff --git a/ui/accessibility/ax_tree_unittest.cc b/ui/accessibility/ax_tree_unittest.cc index be46697..3a14156 100644 --- a/ui/accessibility/ax_tree_unittest.cc +++ b/ui/accessibility/ax_tree_unittest.cc
@@ -1403,100 +1403,6 @@ EXPECT_EQ(1, root->GetUnignoredChildAtIndex(0)->GetUnignoredParent()->id()); } -TEST(AXTreeTest, UnignoredIndexInParentCache) { - AXTreeUpdate initial_state; - initial_state.root_id = 1; - initial_state.nodes.resize(5); - initial_state.nodes[0].id = 1; - initial_state.nodes[0].child_ids = {2, 3}; - initial_state.nodes[1].id = 2; - initial_state.nodes[1].AddState(ax::mojom::State::kIgnored); - initial_state.nodes[1].child_ids = {4, 5}; - initial_state.nodes[2].id = 3; - initial_state.nodes[3].id = 4; - initial_state.nodes[4].id = 5; - - AXTree tree(initial_state); - AXNode* root = tree.root(); - ASSERT_EQ(2, root->child_count()); - ASSERT_EQ(2, root->ChildAtIndex(0)->id()); - ASSERT_EQ(3, root->ChildAtIndex(1)->id()); - - EXPECT_EQ(3, root->GetUnignoredChildCount()); - EXPECT_EQ(4, root->GetUnignoredChildAtIndex(0)->id()); - EXPECT_EQ(5, root->GetUnignoredChildAtIndex(1)->id()); - EXPECT_EQ(3, root->GetUnignoredChildAtIndex(2)->id()); - EXPECT_EQ(0, root->GetUnignoredChildAtIndex(0)->GetUnignoredIndexInParent()); - EXPECT_EQ(1, root->GetUnignoredChildAtIndex(1)->GetUnignoredIndexInParent()); - EXPECT_EQ(2, root->GetUnignoredChildAtIndex(2)->GetUnignoredIndexInParent()); - - EXPECT_EQ(1, root->GetUnignoredChildAtIndex(0)->GetUnignoredParent()->id()); - - EXPECT_EQ(-1, tree.GetFromId(2)->GetUnignoredIndexInParent()); - - // Ensure when a node goes from ignored to unignored, its children have their - // unignored_index_in_parent updated. - AXTreeUpdate update = initial_state; - update.nodes[1].RemoveState(ax::mojom::State::kIgnored); - - EXPECT_TRUE(tree.Unserialize(update)); - - root = tree.root(); - EXPECT_EQ(2, root->GetUnignoredChildCount()); - EXPECT_EQ(2, root->GetUnignoredChildAtIndex(0)->id()); - EXPECT_EQ(0, tree.GetFromId(4)->GetUnignoredIndexInParent()); - EXPECT_EQ(1, tree.GetFromId(5)->GetUnignoredIndexInParent()); - - // Ensure when a node goes from unignored to unignored, siblings are correctly - // updated. - AXTreeUpdate update2 = update; - update2.nodes[3].AddState(ax::mojom::State::kIgnored); - - EXPECT_TRUE(tree.Unserialize(update2)); - - EXPECT_EQ(-1, tree.GetFromId(4)->GetUnignoredIndexInParent()); - EXPECT_EQ(0, tree.GetFromId(5)->GetUnignoredIndexInParent()); - - // Ensure siblings of a deleted node are updated. - AXTreeUpdate update3 = update2; - update3.nodes.resize(1); - update3.nodes[0].id = 1; - update3.nodes[0].child_ids = {3}; - - EXPECT_TRUE(tree.Unserialize(update3)); - - EXPECT_EQ(0, tree.GetFromId(3)->GetUnignoredIndexInParent()); - - // Ensure new nodes are correctly updated. - AXTreeUpdate update4 = update3; - update4.nodes.resize(3); - update4.nodes[0].id = 1; - update4.nodes[0].child_ids = {3, 6}; - update4.nodes[1].id = 6; - update4.nodes[1].child_ids = {7}; - update4.nodes[2].id = 7; - - EXPECT_TRUE(tree.Unserialize(update4)); - - EXPECT_EQ(0, tree.GetFromId(3)->GetUnignoredIndexInParent()); - EXPECT_EQ(1, tree.GetFromId(6)->GetUnignoredIndexInParent()); - EXPECT_EQ(0, tree.GetFromId(7)->GetUnignoredIndexInParent()); - - // Ensure reparented nodes are correctly updated. - AXTreeUpdate update5 = update4; - update5.nodes.resize(2); - update5.node_id_to_clear = 6; - update5.nodes[0].id = 1; - update5.nodes[0].child_ids = {3, 7}; - update5.nodes[1].id = 7; - update5.nodes[1].child_ids = {}; - - EXPECT_TRUE(tree.Unserialize(update5)); - - EXPECT_EQ(0, tree.GetFromId(3)->GetUnignoredIndexInParent()); - EXPECT_EQ(1, tree.GetFromId(7)->GetUnignoredIndexInParent()); -} - TEST(AXTreeTest, TestRecursionUnignoredChildCount) { AXTreeUpdate tree_update; tree_update.root_id = 1;
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc index 9310a35..79da0d8 100644 --- a/ui/accessibility/platform/ax_platform_node_win.cc +++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -399,6 +399,9 @@ SAFEARRAY* AXPlatformNodeWin::CreateUIAElementsArrayFromIdVector( std::vector<int32_t>& ids) { + if (ids.size() == 0) + return nullptr; + SAFEARRAY* uia_array = SafeArrayCreateVector(VT_UNKNOWN, 0, ids.size()); LONG i = 0; @@ -2080,12 +2083,10 @@ return E_FAIL; std::vector<int32_t> column_header_ids = - GetDelegate()->GetColHeaderNodeIds(GetTableColumn()); + GetTable()->GetDelegate()->GetColHeaderNodeIds(GetTableColumn()); base::EraseIf(column_header_ids, [&](int32_t node_id) { return !IsValidUiaRelationTarget(GetDelegate()->GetFromNodeID(node_id)); }); - if (column_header_ids.empty()) - return S_FALSE; *result = CreateUIAElementsArrayFromIdVector(column_header_ids); return S_OK; } @@ -2098,12 +2099,10 @@ return E_FAIL; std::vector<int32_t> row_header_ids = - GetDelegate()->GetRowHeaderNodeIds(GetTableRow()); + GetTable()->GetDelegate()->GetRowHeaderNodeIds(GetTableRow()); base::EraseIf(row_header_ids, [&](int32_t node_id) { return !IsValidUiaRelationTarget(GetDelegate()->GetFromNodeID(node_id)); }); - if (row_header_ids.empty()) - return S_FALSE; *result = CreateUIAElementsArrayFromIdVector(row_header_ids); return S_OK; }
diff --git a/ui/accessibility/platform/ax_platform_node_win_unittest.cc b/ui/accessibility/platform/ax_platform_node_win_unittest.cc index 2dd6312..42e099c9 100644 --- a/ui/accessibility/platform/ax_platform_node_win_unittest.cc +++ b/ui/accessibility/platform/ax_platform_node_win_unittest.cc
@@ -136,38 +136,46 @@ EXPECT_EQ(expectedVariant.ptr()->intVal, actual.ptr()->intVal); \ } -#define EXPECT_UIA_ELEMENT_ARRAY_BSTR_EQ(node, array_property_id, \ - element_test_property_id, \ - expected_property_values) \ +#define EXPECT_UIA_ELEMENT_ARRAY_BSTR_EQ(array, element_test_property_id, \ + expected_property_values) \ + { \ + ASSERT_EQ(1u, SafeArrayGetDim(array)); \ + LONG array_lower_bound; \ + ASSERT_HRESULT_SUCCEEDED( \ + SafeArrayGetLBound(array, 1, &array_lower_bound)); \ + LONG array_upper_bound; \ + ASSERT_HRESULT_SUCCEEDED( \ + SafeArrayGetUBound(array, 1, &array_upper_bound)); \ + IUnknown** array_data; \ + ASSERT_HRESULT_SUCCEEDED( \ + ::SafeArrayAccessData(array, reinterpret_cast<void**>(&array_data))); \ + size_t count = array_upper_bound - array_lower_bound + 1; \ + ASSERT_EQ(expected_property_values.size(), count); \ + for (size_t i = 0; i < count; ++i) { \ + CComPtr<IRawElementProviderSimple> element; \ + ASSERT_HRESULT_SUCCEEDED(array_data[i]->QueryInterface(&element)); \ + EXPECT_UIA_BSTR_EQ(element, element_test_property_id, \ + expected_property_values[i].c_str()); \ + } \ + ASSERT_HRESULT_SUCCEEDED(::SafeArrayUnaccessData(array)); \ + } + +#define EXPECT_UIA_PROPERTY_ELEMENT_ARRAY_BSTR_EQ(node, array_property_id, \ + element_test_property_id, \ + expected_property_values) \ { \ ScopedVariant array; \ ASSERT_HRESULT_SUCCEEDED( \ node->GetPropertyValue(array_property_id, array.Receive())); \ ASSERT_EQ(VT_ARRAY | VT_UNKNOWN, array.type()); \ - ASSERT_EQ(1u, SafeArrayGetDim(array.ptr()->parray)); \ - LONG array_lower_bound; \ - ASSERT_HRESULT_SUCCEEDED( \ - SafeArrayGetLBound(array.ptr()->parray, 1, &array_lower_bound)); \ - LONG array_upper_bound; \ - ASSERT_HRESULT_SUCCEEDED( \ - SafeArrayGetUBound(array.ptr()->parray, 1, &array_upper_bound)); \ - IUnknown** array_data; \ - ASSERT_HRESULT_SUCCEEDED(::SafeArrayAccessData( \ - array.ptr()->parray, reinterpret_cast<void**>(&array_data))); \ - size_t count = array_upper_bound - array_lower_bound + 1; \ - ASSERT_EQ(expected_property_values.size(), count); \ - for (size_t i = 0; i < count; ++i) { \ - CComPtr<IRawElementProviderSimple> element; \ - ASSERT_HRESULT_SUCCEEDED(array_data[i]->QueryInterface(&element)); \ - EXPECT_UIA_BSTR_EQ(element, element_test_property_id, \ - expected_property_values[i].c_str()); \ - } \ - ASSERT_HRESULT_SUCCEEDED(::SafeArrayUnaccessData(array.ptr()->parray)); \ + EXPECT_UIA_ELEMENT_ARRAY_BSTR_EQ(array.ptr()->parray, \ + element_test_property_id, \ + expected_property_values); \ } -#define EXPECT_UIA_UNORDERED_ELEMENT_ARRAY_BSTR_EQ(node, array_property_id, \ - element_test_property_id, \ - expected_property_values) \ +#define EXPECT_UIA_PROPERTY_UNORDERED_ELEMENT_ARRAY_BSTR_EQ( \ + node, array_property_id, element_test_property_id, \ + expected_property_values) \ { \ ScopedVariant array; \ ASSERT_HRESULT_SUCCEEDED( \ @@ -3119,11 +3127,13 @@ AXNodeData column_header; column_header.id = 3; column_header.role = ax::mojom::Role::kColumnHeader; + column_header.SetName(L"column_header"); row1.child_ids.push_back(column_header.id); AXNodeData row_header; row_header.id = 4; row_header.role = ax::mojom::Role::kRowHeader; + row_header.SetName(L"row_header"); row1.child_ids.push_back(row_header.id); Init(root, row1, column_header, row_header); @@ -3131,34 +3141,25 @@ ComPtr<ITableProvider> root_itableprovider( QueryInterfaceFromNode<ITableProvider>(GetRootNode())); - ComPtr<IRawElementProviderSimple> column_header_irawelementprovidersimple( - QueryInterfaceFromNode<IRawElementProviderSimple>( - GetRootNode()->children()[0]->children()[0])); - base::win::ScopedSafearray safearray; EXPECT_HRESULT_SUCCEEDED( root_itableprovider->GetColumnHeaders(safearray.Receive())); EXPECT_NE(nullptr, safearray.Get()); - EXPECT_EQ(1U, ::SafeArrayGetDim(safearray.Get())); - EXPECT_EQ(sizeof(IRawElementProviderSimple*), - ::SafeArrayGetElemsize(safearray.Get())); - LONG array_lbound; - EXPECT_HRESULT_SUCCEEDED( - ::SafeArrayGetLBound(safearray.Get(), 1, &array_lbound)); - EXPECT_EQ(0, array_lbound); + std::vector<std::wstring> expected_names = {L"column_header"}; + EXPECT_UIA_ELEMENT_ARRAY_BSTR_EQ(safearray.Get(), UIA_NamePropertyId, + expected_names); - LONG array_ubound; - EXPECT_HRESULT_SUCCEEDED( - ::SafeArrayGetUBound(safearray.Get(), 1, &array_ubound)); - EXPECT_EQ(0, array_ubound); + // Remove column_header's native event target and verify it's no longer + // returned. + TestAXNodeWrapper* column_header_wrapper = TestAXNodeWrapper::GetOrCreate( + tree_.get(), GetRootNode()->children()[0]->children()[0]); + column_header_wrapper->ResetNativeEventTarget(); - LONG index = 0; - CComPtr<IRawElementProviderSimple> array_element; + safearray.Release(); EXPECT_HRESULT_SUCCEEDED( - ::SafeArrayGetElement(safearray.Get(), &index, &array_element)); - EXPECT_NE(nullptr, array_element); - EXPECT_EQ(array_element, column_header_irawelementprovidersimple.Get()); + root_itableprovider->GetColumnHeaders(safearray.Receive())); + EXPECT_EQ(nullptr, safearray.Get()); } TEST_F(AXPlatformNodeWinTest, TestITableProviderGetRowHeaders) { @@ -3174,11 +3175,13 @@ AXNodeData column_header; column_header.id = 3; column_header.role = ax::mojom::Role::kColumnHeader; + column_header.SetName(L"column_header"); row1.child_ids.push_back(column_header.id); AXNodeData row_header; row_header.id = 4; row_header.role = ax::mojom::Role::kRowHeader; + row_header.SetName(L"row_header"); row1.child_ids.push_back(row_header.id); Init(root, row1, column_header, row_header); @@ -3186,34 +3189,23 @@ ComPtr<ITableProvider> root_itableprovider( QueryInterfaceFromNode<ITableProvider>(GetRootNode())); - ComPtr<IRawElementProviderSimple> row_header_irawelementprovidersimple( - QueryInterfaceFromNode<IRawElementProviderSimple>( - GetRootNode()->children()[0]->children()[1])); - base::win::ScopedSafearray safearray; EXPECT_HRESULT_SUCCEEDED( root_itableprovider->GetRowHeaders(safearray.Receive())); EXPECT_NE(nullptr, safearray.Get()); - EXPECT_EQ(1U, ::SafeArrayGetDim(safearray.Get())); - EXPECT_EQ(sizeof(IRawElementProviderSimple*), - ::SafeArrayGetElemsize(safearray.Get())); + std::vector<std::wstring> expected_names = {L"row_header"}; + EXPECT_UIA_ELEMENT_ARRAY_BSTR_EQ(safearray.Get(), UIA_NamePropertyId, + expected_names); - LONG array_lbound; - EXPECT_HRESULT_SUCCEEDED( - ::SafeArrayGetLBound(safearray.Get(), 1, &array_lbound)); - EXPECT_EQ(0, array_lbound); + // Remove row_header's native event target and verify it's no longer returned. + TestAXNodeWrapper* row_header_wrapper = TestAXNodeWrapper::GetOrCreate( + tree_.get(), GetRootNode()->children()[0]->children()[1]); + row_header_wrapper->ResetNativeEventTarget(); - LONG array_ubound; + safearray.Release(); EXPECT_HRESULT_SUCCEEDED( - ::SafeArrayGetUBound(safearray.Get(), 1, &array_ubound)); - EXPECT_EQ(0, array_ubound); - - LONG index = 0; - CComPtr<IRawElementProviderSimple> array_element; - EXPECT_HRESULT_SUCCEEDED( - ::SafeArrayGetElement(safearray.Get(), &index, &array_element)); - EXPECT_NE(nullptr, array_element); - EXPECT_EQ(array_element, row_header_irawelementprovidersimple.Get()); + root_itableprovider->GetRowHeaders(safearray.Receive())); + EXPECT_EQ(nullptr, safearray.Get()); } TEST_F(AXPlatformNodeWinTest, TestITableProviderGetRowOrColumnMajor) { @@ -3232,6 +3224,131 @@ EXPECT_EQ(row_or_column_major, RowOrColumnMajor_RowMajor); } +TEST_F(AXPlatformNodeWinTest, TestITableItemProviderGetColumnHeaderItems) { + AXNodeData root; + root.id = 1; + root.role = ax::mojom::Role::kTable; + + AXNodeData row1; + row1.id = 2; + row1.role = ax::mojom::Role::kRow; + root.child_ids.push_back(row1.id); + + AXNodeData column_header_1; + column_header_1.id = 3; + column_header_1.role = ax::mojom::Role::kColumnHeader; + column_header_1.SetName(L"column_header_1"); + row1.child_ids.push_back(column_header_1.id); + + AXNodeData column_header_2; + column_header_2.id = 4; + column_header_2.role = ax::mojom::Role::kColumnHeader; + column_header_2.SetName(L"column_header_2"); + row1.child_ids.push_back(column_header_2.id); + + AXNodeData row2; + row2.id = 5; + row2.role = ax::mojom::Role::kRow; + root.child_ids.push_back(row2.id); + + AXNodeData cell; + cell.id = 6; + cell.role = ax::mojom::Role::kCell; + row2.child_ids.push_back(cell.id); + + Init(root, row1, column_header_1, column_header_2, row2, cell); + + TestAXNodeWrapper* root_wrapper = + TestAXNodeWrapper::GetOrCreate(tree_.get(), GetRootNode()); + root_wrapper->BuildAllWrappers(tree_.get(), GetRootNode()); + + ComPtr<ITableItemProvider> cell_itableitemprovider( + QueryInterfaceFromNode<ITableItemProvider>( + GetRootNode()->children()[1]->children()[0])); + + base::win::ScopedSafearray safearray; + EXPECT_HRESULT_SUCCEEDED( + cell_itableitemprovider->GetColumnHeaderItems(safearray.Receive())); + EXPECT_NE(nullptr, safearray.Get()); + + std::vector<std::wstring> expected_names = {L"column_header_1"}; + EXPECT_UIA_ELEMENT_ARRAY_BSTR_EQ(safearray.Get(), UIA_NamePropertyId, + expected_names); + + // Remove column_header_1's native event target and verify it's no longer + // returned. + TestAXNodeWrapper* column_header_wrapper = TestAXNodeWrapper::GetOrCreate( + tree_.get(), GetRootNode()->children()[0]->children()[0]); + column_header_wrapper->ResetNativeEventTarget(); + + safearray.Release(); + EXPECT_HRESULT_SUCCEEDED( + cell_itableitemprovider->GetColumnHeaderItems(safearray.Receive())); + EXPECT_EQ(nullptr, safearray.Get()); +} + +TEST_F(AXPlatformNodeWinTest, TestITableItemProviderGetRowHeaderItems) { + AXNodeData root; + root.id = 1; + root.role = ax::mojom::Role::kTable; + + AXNodeData row1; + row1.id = 2; + row1.role = ax::mojom::Role::kRow; + root.child_ids.push_back(row1.id); + + AXNodeData row_header_1; + row_header_1.id = 3; + row_header_1.role = ax::mojom::Role::kRowHeader; + row_header_1.SetName(L"row_header_1"); + row1.child_ids.push_back(row_header_1.id); + + AXNodeData cell; + cell.id = 4; + cell.role = ax::mojom::Role::kCell; + row1.child_ids.push_back(cell.id); + + AXNodeData row2; + row2.id = 5; + row2.role = ax::mojom::Role::kRow; + root.child_ids.push_back(row2.id); + + AXNodeData row_header_2; + row_header_2.id = 6; + row_header_2.role = ax::mojom::Role::kRowHeader; + row_header_2.SetName(L"row_header_2"); + row2.child_ids.push_back(row_header_2.id); + + Init(root, row1, row_header_1, cell, row2, row_header_2); + + TestAXNodeWrapper* root_wrapper = + TestAXNodeWrapper::GetOrCreate(tree_.get(), GetRootNode()); + root_wrapper->BuildAllWrappers(tree_.get(), GetRootNode()); + + ComPtr<ITableItemProvider> cell_itableitemprovider( + QueryInterfaceFromNode<ITableItemProvider>( + GetRootNode()->children()[0]->children()[1])); + + base::win::ScopedSafearray safearray; + EXPECT_HRESULT_SUCCEEDED( + cell_itableitemprovider->GetRowHeaderItems(safearray.Receive())); + EXPECT_NE(nullptr, safearray.Get()); + std::vector<std::wstring> expected_names = {L"row_header_1"}; + EXPECT_UIA_ELEMENT_ARRAY_BSTR_EQ(safearray.Get(), UIA_NamePropertyId, + expected_names); + + // Remove row_header_1's native event target and verify it's no longer + // returned. + TestAXNodeWrapper* row_header_wrapper = TestAXNodeWrapper::GetOrCreate( + tree_.get(), GetRootNode()->children()[0]->children()[0]); + row_header_wrapper->ResetNativeEventTarget(); + + safearray.Release(); + EXPECT_HRESULT_SUCCEEDED( + cell_itableitemprovider->GetRowHeaderItems(safearray.Receive())); + EXPECT_EQ(nullptr, safearray.Get()); +} + TEST_F(AXPlatformNodeWinTest, TestIA2GetAttribute) { AXNodeData root; root.id = 1; @@ -3399,16 +3516,18 @@ GetRootNode()->children()[0]); std::vector<std::wstring> expected_names_1 = {L"panel1", L"panel2"}; - EXPECT_UIA_ELEMENT_ARRAY_BSTR_EQ(tab_node, UIA_ControllerForPropertyId, - UIA_NamePropertyId, expected_names_1); + EXPECT_UIA_PROPERTY_ELEMENT_ARRAY_BSTR_EQ( + tab_node, UIA_ControllerForPropertyId, UIA_NamePropertyId, + expected_names_1); // Remove panel1's native event target and verify it's no longer returned. TestAXNodeWrapper* panel1_wrapper = TestAXNodeWrapper::GetOrCreate(tree_.get(), GetRootNode()->children()[1]); panel1_wrapper->ResetNativeEventTarget(); std::vector<std::wstring> expected_names_2 = {L"panel2"}; - EXPECT_UIA_ELEMENT_ARRAY_BSTR_EQ(tab_node, UIA_ControllerForPropertyId, - UIA_NamePropertyId, expected_names_2); + EXPECT_UIA_PROPERTY_ELEMENT_ARRAY_BSTR_EQ( + tab_node, UIA_ControllerForPropertyId, UIA_NamePropertyId, + expected_names_2); } TEST_F(AXPlatformNodeWinTest, TestUIAGetDescribedByPropertyId) { @@ -3440,8 +3559,8 @@ GetRootIRawElementProviderSimple(); std::vector<std::wstring> expected_names = {L"child1", L"child2"}; - EXPECT_UIA_ELEMENT_ARRAY_BSTR_EQ(root_node, UIA_DescribedByPropertyId, - UIA_NamePropertyId, expected_names); + EXPECT_UIA_PROPERTY_ELEMENT_ARRAY_BSTR_EQ( + root_node, UIA_DescribedByPropertyId, UIA_NamePropertyId, expected_names); } TEST_F(AXPlatformNodeWinTest, TestUIAItemStatusPropertyId) { @@ -3539,8 +3658,8 @@ ComPtr<IRawElementProviderSimple> root_node = GetRootIRawElementProviderSimple(); std::vector<std::wstring> expected_names = {L"child1", L"child2"}; - EXPECT_UIA_ELEMENT_ARRAY_BSTR_EQ(root_node, UIA_FlowsToPropertyId, - UIA_NamePropertyId, expected_names); + EXPECT_UIA_PROPERTY_ELEMENT_ARRAY_BSTR_EQ(root_node, UIA_FlowsToPropertyId, + UIA_NamePropertyId, expected_names); } TEST_F(AXPlatformNodeWinTest, TestUIAGetPropertyValueFlowsFromNone) { @@ -3553,9 +3672,12 @@ ComPtr<IRawElementProviderSimple> root_node = GetRootIRawElementProviderSimple(); - std::vector<std::wstring> expected_names = {}; - EXPECT_UIA_ELEMENT_ARRAY_BSTR_EQ(root_node, UIA_FlowsFromPropertyId, - UIA_NamePropertyId, expected_names); + + ScopedVariant property_value; + EXPECT_HRESULT_SUCCEEDED(root_node->GetPropertyValue( + UIA_FlowsFromPropertyId, property_value.Receive())); + EXPECT_EQ(VT_ARRAY | VT_UNKNOWN, property_value.type()); + EXPECT_EQ(nullptr, V_ARRAY(property_value.ptr())); } TEST_F(AXPlatformNodeWinTest, TestUIAGetPropertyValueFlowsFromSingle) { @@ -3579,8 +3701,8 @@ QueryInterfaceFromNode<IRawElementProviderSimple>( GetRootNode()->children()[0]); std::vector<std::wstring> expected_names = {L"root"}; - EXPECT_UIA_ELEMENT_ARRAY_BSTR_EQ(child_node1, UIA_FlowsFromPropertyId, - UIA_NamePropertyId, expected_names); + EXPECT_UIA_PROPERTY_ELEMENT_ARRAY_BSTR_EQ( + child_node1, UIA_FlowsFromPropertyId, UIA_NamePropertyId, expected_names); } TEST_F(AXPlatformNodeWinTest, TestUIAGetPropertyValueFlowsFromMultiple) { @@ -3613,7 +3735,7 @@ QueryInterfaceFromNode<IRawElementProviderSimple>( GetRootNode()->children()[1]); std::vector<std::wstring> expected_names_1 = {L"root", L"child1"}; - EXPECT_UIA_UNORDERED_ELEMENT_ARRAY_BSTR_EQ( + EXPECT_UIA_PROPERTY_UNORDERED_ELEMENT_ARRAY_BSTR_EQ( child_node2, UIA_FlowsFromPropertyId, UIA_NamePropertyId, expected_names_1); @@ -3622,7 +3744,7 @@ TestAXNodeWrapper::GetOrCreate(tree_.get(), GetRootNode()->children()[0]); child1_wrapper->ResetNativeEventTarget(); std::vector<std::wstring> expected_names_2 = {L"root"}; - EXPECT_UIA_UNORDERED_ELEMENT_ARRAY_BSTR_EQ( + EXPECT_UIA_PROPERTY_UNORDERED_ELEMENT_ARRAY_BSTR_EQ( child_node2, UIA_FlowsFromPropertyId, UIA_NamePropertyId, expected_names_2); }
diff --git a/ui/android/java/src/org/chromium/ui/widget/RoundedCornerImageView.java b/ui/android/java/src/org/chromium/ui/widget/RoundedCornerImageView.java index a57ede4..e5cb396 100644 --- a/ui/android/java/src/org/chromium/ui/widget/RoundedCornerImageView.java +++ b/ui/android/java/src/org/chromium/ui/widget/RoundedCornerImageView.java
@@ -18,6 +18,7 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.shapes.RoundRectShape; import android.graphics.drawable.shapes.Shape; +import android.support.annotation.ColorRes; import android.support.annotation.Nullable; import android.support.v4.view.ViewCompat; import android.util.AttributeSet; @@ -119,6 +120,15 @@ updateApplyShader(); } + /** + * Set the fill color resource. + * @param id The color resource id. + */ + public void setRoundedFillColor(@ColorRes int id) { + mFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + mFillPaint.setColor(getContext().getResources().getColor(id)); + } + protected void maybeCreateShader() { // Only create the shader if we have a rectangle to use as a mask. Drawable drawable = getDrawable();
diff --git a/ui/aura/window_occlusion_tracker.h b/ui/aura/window_occlusion_tracker.h index e6b3611..cf475b1 100644 --- a/ui/aura/window_occlusion_tracker.h +++ b/ui/aura/window_occlusion_tracker.h
@@ -66,9 +66,12 @@ DISALLOW_COPY_AND_ASSIGN(ScopedPause); }; - // Forces the occlusion state of a window and all its descendants to VISIBLE. - // Ignores the window that is forced VISIBLE and its descendants when - // computing the occlusion state of other windows is the tree. + // Used to exclude a window and all descendants from occlusion calculation. + // The occlusion state of the window and all descendants is set from the + // the drawn state of the window, *not* based on what windows may be stacked + // above them. Further, ignores the window that is excluded and its + // descendants when computing the occlusion state of other windows in the + // tree. // // This is useful for a window being dragged or resized to avoid unnecessary // occlusion state change triggered by these operation, because the window @@ -92,11 +95,12 @@ DISALLOW_COPY_AND_ASSIGN(ScopedExclude); }; - // Forces the occlusion state of a window to VISIBLE. Causes the occlusion - // state of descendants of the window that is forced VISIBLE to be computed - // as if they were in an isolated tree with a root that is drawn. Ignores the - // window that is forced VISIBLE and its descendants when computing the - // occlusion state of other windows is the tree. + // Forces the occlusion state of a window to VISIBLE regardless of the drawn + // state of the window. Causes the occlusion state of descendants of the + // window that is forced VISIBLE to be computed as if they were in an + // isolated tree with a root that is drawn. Ignores the window that is forced + // VISIBLE and its descendants when computing the occlusion state of other + // windows in the tree. // // This function is primarily useful for situations that show the contents of // a hidden window, such as overview mode on ChromeOS.
diff --git a/ui/gl/gl_surface_format.cc b/ui/gl/gl_surface_format.cc index 2e99157..2fc6ef0 100644 --- a/ui/gl/gl_surface_format.cc +++ b/ui/gl/gl_surface_format.cc
@@ -15,21 +15,6 @@ GLSurfaceFormat::~GLSurfaceFormat() { } -GLSurfaceFormat::GLSurfaceFormat(SurfacePixelLayout layout) { - pixel_layout_ = layout; -} - -GLSurfaceFormat::SurfacePixelLayout GLSurfaceFormat::GetPixelLayout() const { - return pixel_layout_; -} - -void GLSurfaceFormat::SetDefaultPixelLayout(SurfacePixelLayout layout) { - if (pixel_layout_ == PIXEL_LAYOUT_DONT_CARE && - layout != PIXEL_LAYOUT_DONT_CARE) { - pixel_layout_ = layout; - } -} - void GLSurfaceFormat::SetRGB565() { red_bits_ = blue_bits_ = 5; green_bits_ = 6; @@ -51,8 +36,7 @@ GetBitSize(alpha_bits_) == GetBitSize(other.alpha_bits_) && GetValue(stencil_bits_, 8) == GetValue(other.stencil_bits_, 8) && GetValue(depth_bits_, 24) == GetValue(other.depth_bits_, 24) && - GetValue(samples_, 0) == GetValue(other.samples_, 0) && - pixel_layout_ == other.pixel_layout_) { + GetValue(samples_, 0) == GetValue(other.samples_, 0)) { return true; } return false;
diff --git a/ui/gl/gl_surface_format.h b/ui/gl/gl_surface_format.h index 70af5e1..827ccac 100644 --- a/ui/gl/gl_surface_format.h +++ b/ui/gl/gl_surface_format.h
@@ -15,21 +15,10 @@ // checking compatibility. class GL_EXPORT GLSurfaceFormat { public: - - // For use with constructor. - enum SurfacePixelLayout { - PIXEL_LAYOUT_DONT_CARE = -1, - PIXEL_LAYOUT_BGRA, - PIXEL_LAYOUT_RGBA, - }; - // Default surface format for the underlying gl_surface subtype. // Use the setters below to change attributes if needed. GLSurfaceFormat(); - // Use a specified pixel layout, cf. GLSurfaceFormatTest. - GLSurfaceFormat(SurfacePixelLayout layout); - // Copy constructor from pre-existing format. GLSurfaceFormat(const GLSurfaceFormat& other); @@ -58,9 +47,6 @@ void SetSamples(int samples); int GetSamples() const { return samples_; } - void SetDefaultPixelLayout(SurfacePixelLayout layout); - SurfacePixelLayout GetPixelLayout() const; - enum SurfaceColorSpace { COLOR_SPACE_UNSPECIFIED = -1, COLOR_SPACE_SRGB, @@ -77,7 +63,6 @@ int GetBufferSize() const; private: - SurfacePixelLayout pixel_layout_ = PIXEL_LAYOUT_DONT_CARE; SurfaceColorSpace color_space_ = COLOR_SPACE_UNSPECIFIED; int red_bits_ = -1; int green_bits_ = -1;
diff --git a/ui/gl/gl_surface_format_unittest.cc b/ui/gl/gl_surface_format_unittest.cc index 119f218c..a4c1fa0 100644 --- a/ui/gl/gl_surface_format_unittest.cc +++ b/ui/gl/gl_surface_format_unittest.cc
@@ -12,8 +12,6 @@ // Check default format properties. GLSurfaceFormat format = GLSurfaceFormat(); EXPECT_EQ(32, format.GetBufferSize()); - EXPECT_EQ(GLSurfaceFormat::PIXEL_LAYOUT_DONT_CARE, - format.GetPixelLayout()); } { @@ -22,21 +20,6 @@ format.SetRGB565(); EXPECT_EQ(16, format.GetBufferSize()); } - - { - // Check custom pixel layout. - GLSurfaceFormat format = GLSurfaceFormat( - GLSurfaceFormat::PIXEL_LAYOUT_RGBA); - EXPECT_EQ(GLSurfaceFormat::PIXEL_LAYOUT_RGBA, - format.GetPixelLayout()); - - // The custom pixel layout should remain after other modifications. - format.SetDepthBits(24); - EXPECT_EQ(GLSurfaceFormat::PIXEL_LAYOUT_RGBA, - format.GetPixelLayout()); - EXPECT_EQ(24, format.GetDepthBits()); - } - { // Check IsCompatible GLSurfaceFormat format = GLSurfaceFormat();
diff --git a/ui/message_center/views/notification_view_md.cc b/ui/message_center/views/notification_view_md.cc index 1119acb..acb16aff 100644 --- a/ui/message_center/views/notification_view_md.cc +++ b/ui/message_center/views/notification_view_md.cc
@@ -1232,7 +1232,7 @@ bool inline_settings_visible = !settings_row_->visible(); bool disable_notification = - settings_row_->visible() && block_all_button_->checked(); + settings_row_->visible() && block_all_button_->GetChecked(); settings_row_->SetVisible(inline_settings_visible); content_row_->SetVisible(!inline_settings_visible);
diff --git a/ui/native_theme/caption_style_mac.mm b/ui/native_theme/caption_style_mac.mm index f800923..d237eaff 100644 --- a/ui/native_theme/caption_style_mac.mm +++ b/ui/native_theme/caption_style_mac.mm
@@ -11,6 +11,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/sys_string_conversions.h" #include "skia/ext/skia_utils_mac.h" +#include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/color_utils.h" #include "ui/native_theme/caption_style.h" @@ -44,12 +45,14 @@ skia::CGColorRefToSkColor(cg_color.get())); } -std::string GetMABackgroundColorAsCSSColor() { +std::string GetMABackgroundColorAndOpacityAsCSSColor() { base::ScopedCFTypeRef<CGColorRef> cg_color( MACaptionAppearanceCopyBackgroundColor(kUserDomain, nullptr)); + float opacity = MACaptionAppearanceGetBackgroundOpacity(kUserDomain, nullptr); - return color_utils::SkColorToRgbaString( - skia::CGColorRefToSkColor(cg_color.get())); + SkColor rgba_color = + SkColorSetA(skia::CGColorRefToSkColor(cg_color.get()), 0xff * opacity); + return color_utils::SkColorToRgbaString(rgba_color); } // The MA text scale is a float between 0.0 and 2.0; this function converts it @@ -122,7 +125,7 @@ CaptionStyle style; style.text_color = GetMAForegroundColorAsCSSColor(); - style.background_color = GetMABackgroundColorAsCSSColor(); + style.background_color = GetMABackgroundColorAndOpacityAsCSSColor(); style.text_size = GetMATextScaleAsCSSPercent(); style.text_shadow = GetMATextEdgeStyleAsCSSShadow();
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn index fb918f7..0bedd6d 100644 --- a/ui/views/BUILD.gn +++ b/ui/views/BUILD.gn
@@ -640,15 +640,6 @@ "touchui/touch_selection_menu_runner_views.h", "touchui/touch_selection_menu_views.h", "view_constants_aura.h", - "widget/desktop_aura/desktop_capture_client.h", - "widget/desktop_aura/desktop_drop_target_win.h", - "widget/desktop_aura/desktop_event_client.h", - "widget/desktop_aura/desktop_focus_rules.h", - "widget/desktop_aura/desktop_native_cursor_manager.h", - "widget/desktop_aura/desktop_native_widget_aura.h", - "widget/desktop_aura/desktop_screen.h", - "widget/desktop_aura/desktop_screen_position_client.h", - "widget/desktop_aura/desktop_window_tree_host.h", "widget/focus_manager_event_handler.h", "widget/native_widget_aura.h", "widget/tooltip_manager_aura.h", @@ -681,15 +672,6 @@ "touchui/touch_selection_menu_views.cc", "view_constants_aura.cc", "views_touch_selection_controller_factory_aura.cc", - "widget/desktop_aura/desktop_capture_client.cc", - "widget/desktop_aura/desktop_drop_target_win.cc", - "widget/desktop_aura/desktop_event_client.cc", - "widget/desktop_aura/desktop_focus_rules.cc", - "widget/desktop_aura/desktop_native_cursor_manager.cc", - "widget/desktop_aura/desktop_native_widget_aura.cc", - "widget/desktop_aura/desktop_screen.cc", - "widget/desktop_aura/desktop_screen_position_client.cc", - "widget/desktop_aura/desktop_window_tree_host.cc", "widget/focus_manager_event_handler.cc", "widget/native_widget_aura.cc", "widget/tooltip_manager_aura.cc", @@ -706,6 +688,28 @@ "//ui/wm/public", ] if (!is_chromeos) { + public += [ + "widget/desktop_aura/desktop_capture_client.h", + "widget/desktop_aura/desktop_drop_target_win.h", + "widget/desktop_aura/desktop_event_client.h", + "widget/desktop_aura/desktop_focus_rules.h", + "widget/desktop_aura/desktop_native_cursor_manager.h", + "widget/desktop_aura/desktop_native_widget_aura.h", + "widget/desktop_aura/desktop_screen.h", + "widget/desktop_aura/desktop_screen_position_client.h", + "widget/desktop_aura/desktop_window_tree_host.h", + ] + sources += [ + "widget/desktop_aura/desktop_capture_client.cc", + "widget/desktop_aura/desktop_drop_target_win.cc", + "widget/desktop_aura/desktop_event_client.cc", + "widget/desktop_aura/desktop_focus_rules.cc", + "widget/desktop_aura/desktop_native_cursor_manager.cc", + "widget/desktop_aura/desktop_native_widget_aura.cc", + "widget/desktop_aura/desktop_screen.cc", + "widget/desktop_aura/desktop_screen_position_client.cc", + "widget/desktop_aura/desktop_window_tree_host.cc", + ] if (use_x11) { public += [ "widget/desktop_aura/desktop_drag_drop_client_aurax11.h", @@ -918,35 +922,6 @@ "//ui/gl:test_support", ] - if (enable_mus) { - sources += [ - "test/platform_test_helper_mus.cc", - "test/platform_test_helper_mus.h", - ] - - deps += [ - "//services/service_manager", - "//services/service_manager/public/cpp", - "//services/service_manager/public/mojom", - "//services/viz/public/cpp:manifest", - "//services/ws/common", - "//services/ws/ime/test_ime_driver/public/cpp:manifest", - "//services/ws/public/mojom", - "//services/ws/test_ws:manifest", - "//testing/gtest", - "//ui/compositor:test_support", - "//ui/gl:test_support", - "//ui/resources", - "//ui/resources:ui_test_pak", - ] - - data_deps = [ - "//services/viz", - "//services/ws/ime/test_ime_driver", - "//ui/resources:ui_test_pak_data", - ] - } - if (is_win) { sources += [ "test/desktop_window_tree_host_win_test_api.cc", @@ -972,7 +947,6 @@ deps += [ "//ui/aura", "//ui/aura:test_support", - "//ui/views/mus", "//ui/wm", "//ui/wm/public", ] @@ -1084,7 +1058,6 @@ "view_unittest.cc", "view_unittest_mac.mm", "widget/ax_native_widget_mac_unittest.mm", - "widget/desktop_widget_unittest.cc", "widget/native_widget_mac_unittest.mm", "widget/native_widget_unittest.cc", "widget/root_view_unittest.cc", @@ -1141,24 +1114,6 @@ "//ui/resources:ui_test_pak_data", ] - if (enable_mus) { - sources += [ - "mus/desktop_window_tree_host_mus_unittest.cc", - "mus/screen_mus_unittest.cc", - ] - - deps += [ - "//services/ws/test_ws:mojom", - "//ui/views/mus", - "//ui/views/mus/remote_view:tests", - ] - - data_deps += [ - "//services/ws/ime/test_ime_driver", - "//services/ws/test_ws", - ] - } - if (is_win) { public_deps = [ "//build/win:default_exe_manifest", @@ -1209,8 +1164,6 @@ "touchui/touch_selection_controller_impl_unittest.cc", "touchui/touch_selection_menu_runner_views_unittest.cc", "view_unittest_aura.cc", - "widget/desktop_aura/desktop_focus_rules_unittest.cc", - "widget/desktop_aura/desktop_native_widget_aura_unittest.cc", "widget/native_widget_aura_unittest.cc", "widget/window_reorderer_unittest.cc", ] @@ -1246,6 +1199,12 @@ } if (!is_chromeos) { + if (!is_chromeos) { + sources += [ + "widget/desktop_aura/desktop_focus_rules_unittest.cc", + "widget/desktop_aura/desktop_native_widget_aura_unittest.cc", + ] + } if (use_x11) { sources += [ "widget/desktop_aura/desktop_drag_drop_client_aurax11_unittest.cc", @@ -1260,6 +1219,10 @@ } } } + + if (!is_chromeos) { + sources += [ "widget/desktop_widget_unittest.cc" ] + } } # This target is added as a dependency of browser interactive_ui_tests. It must @@ -1336,28 +1299,6 @@ if (is_chromeos) { sources -= [ "corewm/desktop_capture_controller_unittest.cc" ] } - - if (enable_mus) { - sources += [ - "mus/clipboard_unittest.cc", - "mus/drag_interactive_uitest.cc", - ] - - deps += [ - "//mojo/core/embedder", - "//services/ws/public/mojom", - "//testing/gmock", - "//ui/base/ime", - "//ui/base/mojo:lib", - "//ui/events:events_base", - "//ui/touch_selection", - "//ui/views/mus", - ] - - data_deps = [ - "//services/ws/test_ws", - ] - } } test("views_perftests") {
diff --git a/ui/views/DEPS b/ui/views/DEPS index d6c4afa4..07b7bc43 100644 --- a/ui/views/DEPS +++ b/ui/views/DEPS
@@ -38,12 +38,6 @@ "views_perftests\.cc": [ "+mojo/core/embedder", ], - "views_test_base\.cc": [ - "+mojo/core/embedder", - "+services/service_manager/public", - "+services/ws", - "+ui/gl", - ], "view_unittest\.cc": [ "+cc/playback", "+components/viz/common",
diff --git a/ui/views/controls/button/checkbox.cc b/ui/views/controls/button/checkbox.cc index 9be12ea..fea527b 100644 --- a/ui/views/controls/button/checkbox.cc +++ b/ui/views/controls/button/checkbox.cc
@@ -22,6 +22,7 @@ #include "ui/views/controls/button/label_button_border.h" #include "ui/views/controls/focus_ring.h" #include "ui/views/layout/layout_provider.h" +#include "ui/views/metadata/metadata_impl_macros.h" #include "ui/views/painter.h" #include "ui/views/resources/grit/views_resources.h" #include "ui/views/style/platform_style.h" @@ -54,15 +55,29 @@ Checkbox::~Checkbox() = default; void Checkbox::SetChecked(bool checked) { - if (checked_ != checked) { - checked_ = checked; - NotifyAccessibilityEvent(ax::mojom::Event::kCheckedStateChanged, true); - } + if (GetChecked() == checked) + return; + checked_ = checked; + NotifyAccessibilityEvent(ax::mojom::Event::kCheckedStateChanged, true); UpdateImage(); + OnPropertyChanged(&checked_, kPropertyEffectsNone); +} + +bool Checkbox::GetChecked() const { + return checked_; } void Checkbox::SetMultiLine(bool multi_line) { + if (GetMultiLine() == multi_line) + return; label()->SetMultiLine(multi_line); + // TODO(pkasting): Remove this and forward callback subscriptions to the + // underlying label property when Label is converted to properties. + OnPropertyChanged(this, kPropertyEffectsNone); +} + +bool Checkbox::GetMultiLine() const { + return label()->multi_line(); } void Checkbox::SetAssociatedLabel(View* labelling_view) { @@ -85,15 +100,13 @@ LabelButton::GetAccessibleNodeData(node_data); node_data->role = ax::mojom::Role::kCheckBox; const ax::mojom::CheckedState checked_state = - checked() ? ax::mojom::CheckedState::kTrue - : ax::mojom::CheckedState::kFalse; + GetChecked() ? ax::mojom::CheckedState::kTrue + : ax::mojom::CheckedState::kFalse; node_data->SetCheckedState(checked_state); if (enabled()) { - if (checked()) { - node_data->SetDefaultActionVerb(ax::mojom::DefaultActionVerb::kUncheck); - } else { - node_data->SetDefaultActionVerb(ax::mojom::DefaultActionVerb::kCheck); - } + node_data->SetDefaultActionVerb(GetChecked() + ? ax::mojom::DefaultActionVerb::kUncheck + : ax::mojom::DefaultActionVerb::kCheck); } if (label_ax_id_) { node_data->AddIntListAttribute(ax::mojom::IntListAttribute::kLabelledbyIds, @@ -132,10 +145,13 @@ } gfx::ImageSkia Checkbox::GetImage(ButtonState for_state) const { - const int checked = checked_ ? IconState::CHECKED : 0; - const int enabled = for_state != STATE_DISABLED ? IconState::ENABLED : 0; + int icon_state = 0; + if (GetChecked()) + icon_state |= IconState::CHECKED; + if (for_state != STATE_DISABLED) + icon_state |= IconState::ENABLED; return gfx::CreateVectorIcon(GetVectorIcon(), 16, - GetIconImageColor(checked | enabled)); + GetIconImageColor(icon_state)); } std::unique_ptr<LabelButtonBorder> Checkbox::CreateDefaultBorder() const { @@ -161,7 +177,7 @@ } const gfx::VectorIcon& Checkbox::GetVectorIcon() const { - return checked() ? kCheckboxActiveIcon : kCheckboxNormalIcon; + return GetChecked() ? kCheckboxActiveIcon : kCheckboxNormalIcon; } SkColor Checkbox::GetIconImageColor(int icon_state) const { @@ -176,7 +192,7 @@ } void Checkbox::NotifyClick(const ui::Event& event) { - SetChecked(!checked()); + SetChecked(!GetChecked()); LabelButton::NotifyClick(event); } @@ -186,7 +202,13 @@ void Checkbox::GetExtraParams(ui::NativeTheme::ExtraParams* params) const { LabelButton::GetExtraParams(params); - params->button.checked = checked_; + params->button.checked = GetChecked(); } +BEGIN_METADATA(Checkbox) +METADATA_PARENT_CLASS(LabelButton) +ADD_PROPERTY_METADATA(Checkbox, bool, Checked) +ADD_PROPERTY_METADATA(Checkbox, bool, MultiLine) +END_METADATA() + } // namespace views
diff --git a/ui/views/controls/button/checkbox.h b/ui/views/controls/button/checkbox.h index e9c24c6..68ea1f7 100644 --- a/ui/views/controls/button/checkbox.h +++ b/ui/views/controls/button/checkbox.h
@@ -24,6 +24,8 @@ // platform specific objects to replicate the native platforms looks and feel. class VIEWS_EXPORT Checkbox : public LabelButton { public: + METADATA_HEADER(Checkbox); + static const char kViewClassName[]; // |force_md| forces MD even when --secondary-ui-md flag is not set. @@ -33,9 +35,10 @@ // Sets/Gets whether or not the checkbox is checked. virtual void SetChecked(bool checked); - bool checked() const { return checked_; } + bool GetChecked() const; void SetMultiLine(bool multi_line); + bool GetMultiLine() const; // If the accessible name should be the same as the labelling view's text, // use this. It will set the accessible label relationship and copy the
diff --git a/ui/views/controls/button/radio_button.cc b/ui/views/controls/button/radio_button.cc index 2f9ab6a..fb1a1ac 100644 --- a/ui/views/controls/button/radio_button.cc +++ b/ui/views/controls/button/radio_button.cc
@@ -44,7 +44,7 @@ for (Views::const_iterator i(views.begin()); i != views.end(); ++i) { // REVIEW: why don't we check the runtime type like is done above? RadioButton* radio_button = static_cast<RadioButton*>(*i); - if (radio_button->checked()) + if (radio_button->GetChecked()) return radio_button; } return nullptr; @@ -76,7 +76,7 @@ void RadioButton::NotifyClick(const ui::Event& event) { // Set the checked state to true only if we are unchecked, since we can't // be toggled on and off like a checkbox. - if (!checked()) + if (!GetChecked()) SetChecked(true); LabelButton::NotifyClick(event); } @@ -86,7 +86,7 @@ } void RadioButton::SetChecked(bool checked) { - if (checked == RadioButton::checked()) + if (checked == RadioButton::GetChecked()) return; if (checked) { // We can't start from the root view because other parts of the UI might use @@ -110,7 +110,7 @@ } const gfx::VectorIcon& RadioButton::GetVectorIcon() const { - return checked() ? kRadioButtonActiveIcon : kRadioButtonNormalIcon; + return GetChecked() ? kRadioButtonActiveIcon : kRadioButtonNormalIcon; } SkPath RadioButton::GetFocusRingPath() const {
diff --git a/ui/views/controls/button/radio_button_unittest.cc b/ui/views/controls/button/radio_button_unittest.cc index dd8cac9..77f4f55 100644 --- a/ui/views/controls/button/radio_button_unittest.cc +++ b/ui/views/controls/button/radio_button_unittest.cc
@@ -58,12 +58,12 @@ button_container().AddChildView(button2); button1->SetChecked(true); - EXPECT_TRUE(button1->checked()); - EXPECT_FALSE(button2->checked()); + EXPECT_TRUE(button1->GetChecked()); + EXPECT_FALSE(button2->GetChecked()); button2->SetChecked(true); - EXPECT_FALSE(button1->checked()); - EXPECT_TRUE(button2->checked()); + EXPECT_FALSE(button1->GetChecked()); + EXPECT_TRUE(button2->GetChecked()); } TEST_F(RadioButtonTest, Focus) { @@ -85,14 +85,14 @@ focus_manager->OnKeyEvent( ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_DOWN, ui::EF_NONE)); EXPECT_EQ(button2, focus_manager->GetFocusedView()); - EXPECT_FALSE(button1->checked()); - EXPECT_TRUE(button2->checked()); + EXPECT_FALSE(button1->GetChecked()); + EXPECT_TRUE(button2->GetChecked()); focus_manager->OnKeyEvent( ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_UP, ui::EF_NONE)); EXPECT_EQ(button1, focus_manager->GetFocusedView()); - EXPECT_TRUE(button1->checked()); - EXPECT_FALSE(button2->checked()); + EXPECT_TRUE(button1->GetChecked()); + EXPECT_FALSE(button2->GetChecked()); } TEST_F(RadioButtonTest, FocusOnClick) { @@ -111,7 +111,7 @@ button2->OnMousePressed(event); button2->OnMouseReleased(event); - EXPECT_TRUE(button2->checked()); + EXPECT_TRUE(button2->GetChecked()); auto* focus_manager = button_container().GetFocusManager(); // No focus on click. EXPECT_EQ(nullptr, focus_manager->GetFocusedView()); @@ -123,7 +123,7 @@ button1->OnMousePressed(event); button1->OnMouseReleased(event); // Button 1 gets focus on click because button 2 already had it. - EXPECT_TRUE(button1->checked()); + EXPECT_TRUE(button1->GetChecked()); EXPECT_EQ(button1, focus_manager->GetFocusedView()); }
diff --git a/ui/views/controls/message_box_view.cc b/ui/views/controls/message_box_view.cc index e3823c0d..73b3997b 100644 --- a/ui/views/controls/message_box_view.cc +++ b/ui/views/controls/message_box_view.cc
@@ -96,7 +96,7 @@ } bool MessageBoxView::IsCheckBoxSelected() { - return checkbox_ ? checkbox_->checked() : false; + return checkbox_ && checkbox_->GetChecked(); } void MessageBoxView::SetCheckBoxLabel(const base::string16& label) {
diff --git a/ui/views/examples/box_layout_example.cc b/ui/views/examples/box_layout_example.cc index 40cc17c..9895f78 100644 --- a/ui/views/examples/box_layout_example.cc +++ b/ui/views/examples/box_layout_example.cc
@@ -115,7 +115,7 @@ orientation_->GetSelectedIndex() == 0 ? BoxLayout::Orientation::kHorizontal : BoxLayout::Orientation::kVertical, - gfx::Insets(0, 0), child_spacing, collapse_margins_->checked()); + gfx::Insets(0, 0), child_spacing, collapse_margins_->GetChecked()); layout->set_cross_axis_alignment(static_cast<BoxLayout::CrossAxisAlignment>( cross_axis_alignment_->GetSelectedIndex())); layout->set_main_axis_alignment(static_cast<BoxLayout::MainAxisAlignment>(
diff --git a/ui/views/examples/dialog_example.cc b/ui/views/examples/dialog_example.cc index eb28c28..152a8a5e 100644 --- a/ui/views/examples/dialog_example.cc +++ b/ui/views/examples/dialog_example.cc
@@ -62,7 +62,7 @@ // TODO(crbug.com/961660): CreateExtraView should return std::unique_ptr<View> // DialogDelegate: View* CreateExtraView() override { - if (!parent_->has_extra_button_->checked()) + if (!parent_->has_extra_button_->GetChecked()) return nullptr; auto view = MdTextButton::CreateSecondaryUiButton( nullptr, parent_->extra_button_label_->text()); @@ -91,7 +91,7 @@ Bubble(DialogExample* parent, View* anchor) : BubbleDialogDelegateView(anchor, BubbleBorder::TOP_LEFT), Delegate(parent) { - set_close_on_deactivate(!parent->persistent_bubble_->checked()); + set_close_on_deactivate(!parent->persistent_bubble_->GetChecked()); } // BubbleDialogDelegateView: @@ -228,9 +228,9 @@ int DialogExample::GetDialogButtons() const { int buttons = 0; - if (has_ok_button_->checked()) + if (has_ok_button_->GetChecked()) buttons |= ui::DIALOG_BUTTON_OK; - if (has_cancel_button_->checked()) + if (has_cancel_button_->GetChecked()) buttons |= ui::DIALOG_BUTTON_CANCEL; return buttons; } @@ -259,7 +259,7 @@ void DialogExample::ButtonPressed(Button* sender, const ui::Event& event) { if (sender == show_) { - if (bubble_->checked()) { + if (bubble_->GetChecked()) { Bubble* bubble = new Bubble(this, sender); last_dialog_ = bubble; BubbleDialogDelegateView::CreateBubble(bubble); @@ -282,14 +282,14 @@ } if (sender == bubble_) { - if (bubble_->checked() && GetModalType() != ui::MODAL_TYPE_CHILD) { + if (bubble_->GetChecked() && GetModalType() != ui::MODAL_TYPE_CHILD) { mode_->SetSelectedIndex(ui::MODAL_TYPE_CHILD); PrintStatus("You nearly always want Child Modal for bubbles."); } - persistent_bubble_->SetEnabled(bubble_->checked()); + persistent_bubble_->SetEnabled(bubble_->GetChecked()); OnPerformAction(mode_); // Validate the modal type. - if (!bubble_->checked() && GetModalType() == ui::MODAL_TYPE_CHILD) { + if (!bubble_->GetChecked() && GetModalType() == ui::MODAL_TYPE_CHILD) { // Do something reasonable when simply unchecking bubble and re-enable. mode_->SetSelectedIndex(ui::MODAL_TYPE_WINDOW); OnPerformAction(mode_); @@ -324,7 +324,7 @@ } void DialogExample::OnPerformAction(Combobox* combobox) { - bool enable = bubble_->checked() || GetModalType() != ui::MODAL_TYPE_CHILD; + bool enable = bubble_->GetChecked() || GetModalType() != ui::MODAL_TYPE_CHILD; #if defined(OS_MACOSX) enable = enable && GetModalType() != ui::MODAL_TYPE_SYSTEM; #endif
diff --git a/ui/views/examples/flex_layout_example.cc b/ui/views/examples/flex_layout_example.cc index f8697b93..0983e30 100644 --- a/ui/views/examples/flex_layout_example.cc +++ b/ui/views/examples/flex_layout_example.cc
@@ -88,7 +88,7 @@ void FlexLayoutExample::ButtonPressedImpl(Button* sender) { if (sender == collapse_margins_) - layout_->SetCollapseMargins(collapse_margins_->checked()); + layout_->SetCollapseMargins(collapse_margins_->GetChecked()); RefreshLayoutPanel(false); }
diff --git a/ui/views/examples/label_example.cc b/ui/views/examples/label_example.cc index f57bbc8e..82a9bd87 100644 --- a/ui/views/examples/label_example.cc +++ b/ui/views/examples/label_example.cc
@@ -122,16 +122,16 @@ void LabelExample::ButtonPressed(Button* button, const ui::Event& event) { if (button == multiline_) { - custom_label_->SetMultiLine(multiline_->checked()); + custom_label_->SetMultiLine(multiline_->GetChecked()); } else if (button == shadows_) { gfx::ShadowValues shadows; - if (shadows_->checked()) { + if (shadows_->GetChecked()) { shadows.push_back(gfx::ShadowValue(gfx::Vector2d(), 1, SK_ColorRED)); shadows.push_back(gfx::ShadowValue(gfx::Vector2d(2, 2), 0, SK_ColorGRAY)); } custom_label_->SetShadows(shadows); } else if (button == selectable_) { - custom_label_->SetSelectable(selectable_->checked()); + custom_label_->SetSelectable(selectable_->GetChecked()); } custom_label_->parent()->parent()->InvalidateLayout(); custom_label_->SchedulePaint();
diff --git a/ui/views/examples/multiline_example.cc b/ui/views/examples/multiline_example.cc index bbff7cd..7533fb2 100644 --- a/ui/views/examples/multiline_example.cc +++ b/ui/views/examples/multiline_example.cc
@@ -178,7 +178,7 @@ void MultilineExample::ContentsChanged(Textfield* sender, const base::string16& new_contents) { render_text_view_->SetText(new_contents); - if (label_checkbox_->checked()) + if (label_checkbox_->GetChecked()) label_->SetText(new_contents); container()->InvalidateLayout(); container()->SchedulePaint(); @@ -186,10 +186,10 @@ void MultilineExample::ButtonPressed(Button* sender, const ui::Event& event) { if (sender == label_checkbox_) { - label_->SetText(label_checkbox_->checked() ? textfield_->text() - : base::string16()); + label_->SetText(label_checkbox_->GetChecked() ? textfield_->text() + : base::string16()); } else if (sender == elision_checkbox_) { - render_text_view_->SetMaxLines(elision_checkbox_->checked() ? 3 : 0); + render_text_view_->SetMaxLines(elision_checkbox_->GetChecked() ? 3 : 0); } container()->InvalidateLayout(); container()->SchedulePaint();
diff --git a/ui/views/examples/radio_button_example.cc b/ui/views/examples/radio_button_example.cc index bb9b9be..4923f96 100644 --- a/ui/views/examples/radio_button_example.cc +++ b/ui/views/examples/radio_button_example.cc
@@ -63,9 +63,9 @@ } else if (sender == status_) { // Show the state of radio buttons. PrintStatus("Group: 1:%s, 2:%s, 3:%s", - BoolToOnOff(radio_buttons_[0]->checked()), - BoolToOnOff(radio_buttons_[1]->checked()), - BoolToOnOff(radio_buttons_[2]->checked())); + BoolToOnOff(radio_buttons_[0]->GetChecked()), + BoolToOnOff(radio_buttons_[1]->GetChecked()), + BoolToOnOff(radio_buttons_[2]->GetChecked())); } }
diff --git a/ui/views/examples/table_example.cc b/ui/views/examples/table_example.cc index 0a763f0..fc264a8 100644 --- a/ui/views/examples/table_example.cc +++ b/ui/views/examples/table_example.cc
@@ -160,16 +160,16 @@ bool show = true; if (sender == column1_visible_checkbox_) { index = 0; - show = column1_visible_checkbox_->checked(); + show = column1_visible_checkbox_->GetChecked(); } else if (sender == column2_visible_checkbox_) { index = 1; - show = column2_visible_checkbox_->checked(); + show = column2_visible_checkbox_->GetChecked(); } else if (sender == column3_visible_checkbox_) { index = 2; - show = column3_visible_checkbox_->checked(); + show = column3_visible_checkbox_->GetChecked(); } else if (sender == column4_visible_checkbox_) { index = 3; - show = column4_visible_checkbox_->checked(); + show = column4_visible_checkbox_->GetChecked(); } table_->SetColumnVisibility(index, show); }
diff --git a/ui/views/examples/text_example.cc b/ui/views/examples/text_example.cc index f9fad26..48f7115 100644 --- a/ui/views/examples/text_example.cc +++ b/ui/views/examples/text_example.cc
@@ -65,7 +65,7 @@ // Toggles bit |flag| on |flags| based on state of |checkbox|. void SetFlagFromCheckbox(Checkbox* checkbox, int* flags, int flag) { - if (checkbox->checked()) + if (checkbox->GetChecked()) *flags |= flag; else *flags &= ~flag;
diff --git a/ui/views/focus/focus_manager_unittest.cc b/ui/views/focus/focus_manager_unittest.cc index 4743770..0af0ee35 100644 --- a/ui/views/focus/focus_manager_unittest.cc +++ b/ui/views/focus/focus_manager_unittest.cc
@@ -1073,11 +1073,11 @@ EXPECT_TRUE(bubble_child->HasFocus()); } -// This test is specifically for the permutation where the main -// widget is a DesktopNativeWidgetAura and the bubble is a -// NativeWidgetAura. When focus moves back from the bubble to the -// parent widget, ensure that the DNWA's aura window is focused. -#if defined(USE_AURA) +#if defined(USE_AURA) && !defined(OS_CHROMEOS) +// This test is specifically for the permutation where the main widget is a +// DesktopNativeWidgetAura and the bubble is a NativeWidgetAura. When focus +// moves back from the bubble to the parent widget, ensure that the DNWA's aura +// window is focused. class DesktopWidgetFocusManagerTest : public FocusManagerTest { public: DesktopWidgetFocusManagerTest() = default; @@ -1152,7 +1152,7 @@ // Finally, the outer widget's window should be focused again. ASSERT_EQ(widget.GetNativeView(), focus_client->GetFocusedWindow()); } -#endif // defined(USE_AURA) +#endif // Ensures graceful failure if there is a focus cycle. TEST_F(FocusManagerTest, HandlesFocusCycles) {
diff --git a/ui/views/mus/BUILD.gn b/ui/views/mus/BUILD.gn deleted file mode 100644 index 4bddaf31..0000000 --- a/ui/views/mus/BUILD.gn +++ /dev/null
@@ -1,101 +0,0 @@ -# Copyright 2014 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//build/config/features.gni") -import("//build/config/jumbo.gni") -import("//build/config/ui.gni") -import("//testing/test.gni") -import("//tools/grit/repack.gni") - -jumbo_component("mus") { - output_name = "ui_views_mus_lib" - - sources = [ - "aura_init.cc", - "aura_init.h", - "cursor_manager_owner.cc", - "cursor_manager_owner.h", - "desktop_window_tree_host_mus.cc", - "desktop_window_tree_host_mus.h", - "mus_client.cc", - "mus_client.h", - "mus_client_observer.h", - "mus_export.h", - "mus_property_mirror.h", - "mus_views_delegate.cc", - "mus_views_delegate.h", - "screen_mus.cc", - "screen_mus.h", - "screen_mus_delegate.h", - "screen_position_client_mus.cc", - "screen_position_client_mus.h", - "window_manager_constants_converters.cc", - "window_manager_constants_converters.h", - "window_manager_frame_values.cc", - "window_manager_frame_values.h", - ] - - defines = [ "VIEWS_MUS_IMPLEMENTATION" ] - - public_deps = [ - ":resources", - "//services/ws/public/cpp", - "//ui/aura", - ] - deps = [ - "//base", - "//base:i18n", - "//base/third_party/dynamic_annotations", - "//cc", - "//mojo/public/cpp/bindings", - "//net", - "//services/service_manager/public/cpp", - "//services/service_manager/public/mojom", - "//services/ws/public/cpp", - "//services/ws/public/cpp/input_devices", - "//services/ws/public/mojom", - "//skia", - "//third_party/icu", - "//ui/aura", - "//ui/base/ime/init", - "//ui/base/mojo:lib", - "//ui/compositor", - "//ui/display", - "//ui/events", - "//ui/events:events_base", - "//ui/gfx", - "//ui/gfx/geometry", - "//ui/gfx/geometry/mojo", - "//ui/gl", - "//ui/native_theme", - "//ui/platform_window", - "//ui/platform_window/mojo", - "//ui/platform_window/mojo:interfaces", - "//ui/platform_window/stub", - "//ui/views", - "//ui/wm", - "//ui/wm/public", - ] -} - -repack("resources") { - sources = [ - "$root_gen_dir/ui/resources/ui_resources_100_percent.pak", - "$root_gen_dir/ui/strings/app_locale_settings_en-US.pak", - "$root_gen_dir/ui/strings/ui_strings_en-US.pak", - "$root_gen_dir/ui/views/resources/views_resources_100_percent.pak", - ] - output = "$root_out_dir/views_mus_resources.pak" - deps = [ - "//ui/resources", - "//ui/strings", - "//ui/views/resources", - ] -} - -group("for_mojo_application") { - public_deps = [ - ":mus", - ] -}
diff --git a/ui/views/mus/DEPS b/ui/views/mus/DEPS deleted file mode 100644 index aba0de2..0000000 --- a/ui/views/mus/DEPS +++ /dev/null
@@ -1,22 +0,0 @@ -include_rules = [ - "+cc", - "+components/gpu", - "+components/viz/common", - "+mojo/cc", - "+mojo/converters", - "+mojo/core/embedder", - "+mojo/public", - "+services/service_manager/public", - "+services/ws", - "+skia", - "+ui/aura", - "+ui/base", - "+ui/compositor", - "+ui/events", - "+ui/gfx", - "+ui/gl", - "+ui/mojo/display", - "+ui/mojo/ime", - "+ui/platform_window", - "+ui/wm", -]
diff --git a/ui/views/mus/OWNERS b/ui/views/mus/OWNERS deleted file mode 100644 index 1b6d3c5..0000000 --- a/ui/views/mus/OWNERS +++ /dev/null
@@ -1,5 +0,0 @@ -jamescook@chromium.org -msw@chromium.org -sky@chromium.org - -per-file ax_*=file://ui/accessibility/OWNERS
diff --git a/ui/views/mus/aura_init.cc b/ui/views/mus/aura_init.cc deleted file mode 100644 index 1e25a3a..0000000 --- a/ui/views/mus/aura_init.cc +++ /dev/null
@@ -1,61 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/aura_init.h" - -#include <utility> - -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "base/path_service.h" -#include "build/build_config.h" -#include "services/service_manager/public/cpp/connector.h" -#include "ui/aura/env.h" -#include "ui/base/ime/init/input_method_initializer.h" -#include "ui/base/material_design/material_design_controller.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/base/ui_base_paths.h" -#include "ui/views/mus/mus_client.h" -#include "ui/views/mus/mus_views_delegate.h" - -namespace views { - -AuraInit::InitParams::InitParams() : resource_file("views_mus_resources.pak") {} - -AuraInit::InitParams::~InitParams() = default; - -AuraInit::AuraInit() { - if (!ViewsDelegate::GetInstance()) - views_delegate_ = std::make_unique<MusViewsDelegate>(); -} - -AuraInit::~AuraInit() = default; - -// static -std::unique_ptr<AuraInit> AuraInit::Create(const InitParams& params) { - // Using 'new' to access a non-public constructor. go/totw/134 - std::unique_ptr<AuraInit> aura_init = base::WrapUnique(new AuraInit()); - if (!aura_init->Init(params)) - aura_init.reset(); - return aura_init; -} - -bool AuraInit::Init(const InitParams& params) { - env_ = aura::Env::CreateInstance(aura::Env::Mode::MUS); - - MusClient::InitParams mus_params; - mus_params.connector = params.connector; - mus_params.identity = params.identity; - mus_params.io_task_runner = params.io_task_runner; - mus_params.create_wm_state = true; - mus_client_ = std::make_unique<MusClient>(mus_params); - ui::MaterialDesignController::Initialize(); - - DCHECK(ui::ResourceBundle::HasSharedInstance()); - - ui::InitializeInputMethodForTesting(); - return true; -} - -} // namespace views
diff --git a/ui/views/mus/aura_init.h b/ui/views/mus/aura_init.h deleted file mode 100644 index 0ae261b..0000000 --- a/ui/views/mus/aura_init.h +++ /dev/null
@@ -1,75 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_MUS_AURA_INIT_H_ -#define UI_VIEWS_MUS_AURA_INIT_H_ - -#include <memory> -#include <string> - -#include "base/macros.h" -#include "services/service_manager/public/cpp/identity.h" -#include "ui/aura/env.h" -#include "ui/views/mus/mus_export.h" - -namespace aura { -class Env; -} - -namespace base { -class SingleThreadTaskRunner; -} - -namespace service_manager { -class Connector; -} - -namespace views { -class MusClient; -class ViewsDelegate; - -// Sets up necessary state for aura when run with the viewmanager. -// |resource_file| is the path to the apk file containing the resources. -class VIEWS_MUS_EXPORT AuraInit { - public: - ~AuraInit(); - - struct VIEWS_MUS_EXPORT InitParams { - InitParams(); - ~InitParams(); - service_manager::Connector* connector = nullptr; - service_manager::Identity identity; - // File for strings and 1x icons. Defaults to views_mus_resources.pak. - std::string resource_file; - // File for 2x icons. Can be empty. - std::string resource_file_200; - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner = nullptr; - bool register_path_provider = true; - }; - - // Returns an AuraInit if initialization can be completed successfully, - // otherwise a nullptr is returned. If initialization fails then Aura is in an - // unusable state, and calling services should shutdown. - static std::unique_ptr<AuraInit> Create(const InitParams& params); - - MusClient* mus_client() { return mus_client_.get(); } - - private: - AuraInit(); - - // Returns true if AuraInit was able to successfully complete initialization. - // If this returns false, then Aura is in an unusable state, and calling - // services should shutdown. - bool Init(const InitParams& params); - - std::unique_ptr<aura::Env> env_; - std::unique_ptr<MusClient> mus_client_; - std::unique_ptr<ViewsDelegate> views_delegate_; - - DISALLOW_COPY_AND_ASSIGN(AuraInit); -}; - -} // namespace views - -#endif // UI_VIEWS_MUS_AURA_INIT_H_
diff --git a/ui/views/mus/clipboard_unittest.cc b/ui/views/mus/clipboard_unittest.cc deleted file mode 100644 index 6c91d1e..0000000 --- a/ui/views/mus/clipboard_unittest.cc +++ /dev/null
@@ -1,61 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/base/mojo/clipboard_client.h" - -#include "ui/events/platform/platform_event_source.h" -#include "ui/views/test/views_interactive_ui_test_base.h" - -namespace ui { - -namespace { - -views::ViewsTestBase* g_test_base = nullptr; - -// This class is necessary to allow the Mus version of ClipboardTest to -// initialize itself as if it's a ViewsTestBase (which creates the MusClient and -// does other necessary setup). TODO(crbug/917180): improve this. -class ViewsTestBaseNoTest : public views::ViewsInteractiveUITestBase { - public: - ViewsTestBaseNoTest() = default; - ~ViewsTestBaseNoTest() override = default; - - // views::ViewsInteractiveUITestBase: - void TestBody() override {} -}; - -} // namespace - -struct PlatformClipboardTraits { - static std::unique_ptr<PlatformEventSource> GetEventSource() { - return nullptr; - } - - static Clipboard* Create() { - g_test_base = new ViewsTestBaseNoTest(); - g_test_base->SetUp(); - - return Clipboard::GetForCurrentThread(); - } - - static void Destroy(Clipboard* clipboard) { - g_test_base->TearDown(); - g_test_base = nullptr; - } -}; - -class MusClipboardTestName { - public: - template <typename T> - static std::string GetName(int index) { - return "MusClipboardTest"; - } -}; - -using TypesToTest = PlatformClipboardTraits; -using NamesOfTypesToTest = MusClipboardTestName; - -} // namespace ui - -#include "ui/base/clipboard/clipboard_test_template.h"
diff --git a/ui/views/mus/cursor_manager_owner.cc b/ui/views/mus/cursor_manager_owner.cc deleted file mode 100644 index 69356a4..0000000 --- a/ui/views/mus/cursor_manager_owner.cc +++ /dev/null
@@ -1,87 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/cursor_manager_owner.h" - -#include <memory> - -#include "ui/aura/client/cursor_client.h" -#include "ui/aura/mus/window_port_mus.h" -#include "ui/base/cursor/cursor.h" -#include "ui/wm/core/cursor_manager.h" -#include "ui/wm/core/native_cursor_manager.h" -#include "ui/wm/core/native_cursor_manager_delegate.h" - -namespace views { - -namespace { - -class NativeCursorManagerMus : public wm::NativeCursorManager { - public: - explicit NativeCursorManagerMus(aura::Window* window) : window_(window) {} - ~NativeCursorManagerMus() override = default; - - private: - // wm::NativeCursorManager: - void SetDisplay(const display::Display& display, - wm::NativeCursorManagerDelegate* delegate) override { - // We ignore this entirely, as cursor are set on the client. - } - void SetCursor(ui::Cursor cursor, - wm::NativeCursorManagerDelegate* delegate) override { - aura::WindowPortMus::Get(window_)->SetCursor(cursor); - delegate->CommitCursor(cursor); - } - - void SetVisibility(bool visible, - wm::NativeCursorManagerDelegate* delegate) override { - delegate->CommitVisibility(visible); - - if (visible) { - SetCursor(delegate->GetCursor(), delegate); - } else { - aura::WindowPortMus::Get(window_)->SetCursor( - ui::Cursor(ui::CursorType::kNone)); - } - } - void SetCursorSize(ui::CursorSize cursor_size, - wm::NativeCursorManagerDelegate* delegate) override { - // TODO(erg): For now, ignore the difference between SET_NORMAL and - // SET_LARGE here. This feels like a thing that mus should decide instead. - // - // Also, it's NOTIMPLEMENTED() in the desktop version!? Including not - // acknowledging the call in the delegate. - NOTIMPLEMENTED(); - } - void SetMouseEventsEnabled( - bool enabled, - wm::NativeCursorManagerDelegate* delegate) override { - // TODO(erg): How do we actually implement this? - // - // Mouse event dispatch is potentially done in a different process, - // definitely in a different mojo service. Each app is fairly locked down. - delegate->CommitMouseEventsEnabled(enabled); - NOTIMPLEMENTED(); - } - - aura::Window* window_; - - DISALLOW_COPY_AND_ASSIGN(NativeCursorManagerMus); -}; - -} // namespace - -CursorManagerOwner::CursorManagerOwner(aura::Window* window) - : cursor_manager_(std::make_unique<wm::CursorManager>( - std::make_unique<NativeCursorManagerMus>(window))) { - tracker_.Add(window); - aura::client::SetCursorClient(window, cursor_manager_.get()); -} - -CursorManagerOwner::~CursorManagerOwner() { - if (!tracker_.windows().empty()) - aura::client::SetCursorClient(tracker_.Pop(), nullptr); -} - -} // namespace views
diff --git a/ui/views/mus/cursor_manager_owner.h b/ui/views/mus/cursor_manager_owner.h deleted file mode 100644 index ece09198..0000000 --- a/ui/views/mus/cursor_manager_owner.h +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_MUS_CURSOR_MANAGER_OWNER_H_ -#define UI_VIEWS_MUS_CURSOR_MANAGER_OWNER_H_ - -#include <memory> - -#include "ui/aura/window_tracker.h" -#include "ui/views/mus/mus_export.h" - -namespace aura { -class Window; -} - -namespace wm { -class CursorManager; -} - -namespace views { - -// This class owns the cursor manager which can communicate with the window -// server and keeps it as the cursor-client for the specified window as far as -// this class lives. -class VIEWS_MUS_EXPORT CursorManagerOwner { - public: - explicit CursorManagerOwner(aura::Window* window); - ~CursorManagerOwner(); - - private: - aura::WindowTracker tracker_; - std::unique_ptr<wm::CursorManager> cursor_manager_; - - DISALLOW_COPY_AND_ASSIGN(CursorManagerOwner); -}; - -} // namespace views - -#endif // UI_VIEWS_MUS_CURSOR_MANAGER_OWNER_H_
diff --git a/ui/views/mus/desktop_window_tree_host_mus.cc b/ui/views/mus/desktop_window_tree_host_mus.cc deleted file mode 100644 index d41f83c..0000000 --- a/ui/views/mus/desktop_window_tree_host_mus.cc +++ /dev/null
@@ -1,1068 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/desktop_window_tree_host_mus.h" - -#include "base/bind.h" -#include "base/run_loop.h" -#include "base/threading/thread_task_runner_handle.h" -#include "ui/aura/client/aura_constants.h" -#include "ui/aura/client/capture_client.h" -#include "ui/aura/client/drag_drop_client.h" -#include "ui/aura/client/focus_client.h" -#include "ui/aura/client/transient_window_client.h" -#include "ui/aura/env.h" -#include "ui/aura/mus/focus_synchronizer.h" -#include "ui/aura/mus/window_mus.h" -#include "ui/aura/mus/window_tree_client.h" -#include "ui/aura/mus/window_tree_host_mus.h" -#include "ui/aura/mus/window_tree_host_mus_init_params.h" -#include "ui/aura/window.h" -#include "ui/aura/window_tracker.h" -#include "ui/base/hit_test.h" -#include "ui/display/screen.h" -#include "ui/events/gestures/gesture_recognizer.h" -#include "ui/gfx/geometry/dip_util.h" -#include "ui/gfx/geometry/vector2d_conversions.h" -#include "ui/gfx/image/image_skia_operations.h" -#include "ui/views/corewm/tooltip_aura.h" -#include "ui/views/mus/cursor_manager_owner.h" -#include "ui/views/mus/mus_client.h" -#include "ui/views/mus/mus_property_mirror.h" -#include "ui/views/mus/screen_position_client_mus.h" -#include "ui/views/mus/window_manager_frame_values.h" -#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" -#include "ui/views/widget/desktop_aura/desktop_screen_position_client.h" -#include "ui/views/widget/native_widget_aura.h" -#include "ui/views/widget/widget_delegate.h" -#include "ui/wm/core/window_util.h" -#include "ui/wm/public/activation_client.h" - -namespace views { - -namespace { - -// As the window manager renderers the non-client decorations this class does -// very little but honor kTopViewInset. -class ClientSideNonClientFrameView : public NonClientFrameView, - public aura::WindowObserver { - public: - explicit ClientSideNonClientFrameView(Widget* widget) : widget_(widget) { - observed_.Add(window()); - } - ~ClientSideNonClientFrameView() override = default; - - private: - gfx::Insets GetClientInsets() const { - const int top_inset = window()->GetProperty(aura::client::kTopViewInset); - return gfx::Insets(top_inset, 0, 0, 0); - } - - // View: - const char* GetClassName() const override { - return "ClientSideNonClientFrameView"; - } - - // NonClientFrameView: - gfx::Rect GetBoundsForClientView() const override { - gfx::Rect result(GetLocalBounds()); - if (widget_->IsFullscreen()) - return result; - result.Inset(GetClientInsets()); - return result; - } - gfx::Rect GetWindowBoundsForClientBounds( - const gfx::Rect& client_bounds) const override { - if (widget_->IsFullscreen()) - return client_bounds; - - gfx::Rect outset_bounds = client_bounds; - outset_bounds.Inset(-GetClientInsets()); - return outset_bounds; - } - int NonClientHitTest(const gfx::Point& point) override { return HTNOWHERE; } - void GetWindowMask(const gfx::Size& size, SkPath* window_mask) override { - // The window manager provides the shape; do nothing. - } - void ResetWindowControls() override { - // TODO(sky): push to wm? - } - - // These have no implementation. The Window Manager handles the actual - // rendering of the icon/title. See NonClientFrameViewMash. The values - // associated with these methods are pushed to the server by the way of - // NativeWidgetMus functions. - void UpdateWindowIcon() override {} - void UpdateWindowTitle() override {} - void SizeConstraintsChanged() override {} - - gfx::Size CalculatePreferredSize() const override { - return widget_->non_client_view() - ->GetWindowBoundsForClientBounds( - gfx::Rect(widget_->client_view()->GetPreferredSize())) - .size(); - } - gfx::Size GetMinimumSize() const override { - return widget_->non_client_view() - ->GetWindowBoundsForClientBounds( - gfx::Rect(widget_->client_view()->GetMinimumSize())) - .size(); - } - gfx::Size GetMaximumSize() const override { - gfx::Size max_size = widget_->client_view()->GetMaximumSize(); - gfx::Size converted_size = - widget_->non_client_view() - ->GetWindowBoundsForClientBounds(gfx::Rect(max_size)) - .size(); - return gfx::Size(max_size.width() == 0 ? 0 : converted_size.width(), - max_size.height() == 0 ? 0 : converted_size.height()); - } - - // aura::WindowObserver: - void OnWindowDestroying(aura::Window* window) override { - observed_.Remove(window); - } - - void OnWindowPropertyChanged(aura::Window* window, - const void* key, - intptr_t old) override { - if (key == aura::client::kTopViewInset) - InvalidateLayout(); - } - - aura::Window* window() const { - return widget_->GetNativeWindow()->GetRootWindow(); - } - - Widget* widget_; - ScopedObserver<aura::Window, aura::WindowObserver> observed_{this}; - - DISALLOW_COPY_AND_ASSIGN(ClientSideNonClientFrameView); -}; - -void OnMoveLoopEnd(bool* out_success, - base::OnceClosure quit_closure, - bool in_success) { - *out_success = in_success; - std::move(quit_closure).Run(); -} - -} // namespace - -// WindowObserver installed on DesktopWindowTreeHostMus::window(). Mostly -// forwards interesting events to DesktopWindowTreeHostMus. To avoid having -// DesktopWindowTreeHostMus be a WindowObserver on two windows (which is mildly -// error prone), this helper class is used. -class DesktopWindowTreeHostMus::WindowTreeHostWindowObserver - : public aura::WindowObserver { - public: - explicit WindowTreeHostWindowObserver(DesktopWindowTreeHostMus* host) - : host_(host) { - host->window()->AddObserver(this); - } - ~WindowTreeHostWindowObserver() override { - host_->window()->RemoveObserver(this); - } - - void set_is_waiting_for_restore(bool value) { - is_waiting_for_restore_ = value; - } - bool is_waiting_for_restore() const { return is_waiting_for_restore_; } - - // aura::WindowObserver: - void OnWindowVisibilityChanged(aura::Window* window, bool visible) override { - if (window == host_->window()) - host_->OnWindowTreeHostWindowVisibilityChanged(visible); - } - void OnWindowPropertyChanged(aura::Window* window, - const void* key, - intptr_t old) override { - if (key == aura::client::kShowStateKey) - is_waiting_for_restore_ = false; - } - void OnResizeLoopStarted(aura::Window* window) override { - host_->native_widget_delegate_->OnNativeWidgetBeginUserBoundsChange(); - } - void OnResizeLoopEnded(aura::Window* window) override { - host_->native_widget_delegate_->OnNativeWidgetEndUserBoundsChange(); - } - - private: - DesktopWindowTreeHostMus* host_; - - // True while waiting for the show state to change. - bool is_waiting_for_restore_ = false; - - DISALLOW_COPY_AND_ASSIGN(WindowTreeHostWindowObserver); -}; - -DesktopWindowTreeHostMus::DesktopWindowTreeHostMus( - aura::WindowTreeHostMusInitParams init_params, - internal::NativeWidgetDelegate* native_widget_delegate, - DesktopNativeWidgetAura* desktop_native_widget_aura) - : aura::WindowTreeHostMus(std::move(init_params)), - native_widget_delegate_(native_widget_delegate), - desktop_native_widget_aura_(desktop_native_widget_aura), - close_widget_factory_(this) { - MusClient::Get()->AddObserver(this); - MusClient::Get()->window_tree_client()->focus_synchronizer()->AddObserver( - this); - content_window()->AddObserver(this); - // DesktopNativeWidgetAura registers the association between |content_window_| - // and Widget, but code may also want to go from the root (window()) to the - // Widget. This call enables that. - NativeWidgetAura::RegisterNativeWidgetForWindow(desktop_native_widget_aura, - window()); - - window_tree_host_window_observer_ = - std::make_unique<WindowTreeHostWindowObserver>(this); - // TODO: use display id and bounds if available, likely need to pass in - // InitParams for that. -} - -DesktopWindowTreeHostMus::~DesktopWindowTreeHostMus() { - window_tree_host_window_observer_.reset(); - - content_window()->RemoveObserver(this); - MusClient::Get()->RemoveObserver(this); - MusClient::Get()->window_tree_client()->focus_synchronizer()->RemoveObserver( - this); - desktop_native_widget_aura_->OnDesktopWindowTreeHostDestroyed(this); -} - -void DesktopWindowTreeHostMus::SendClientAreaToServer() { - if (!ShouldSendClientAreaToServer()) - return; - - NonClientView* non_client_view = - native_widget_delegate_->AsWidget()->non_client_view(); - if (!non_client_view || !non_client_view->client_view()) - return; - - View* client_view = non_client_view->client_view(); - if (!observed_client_view_.IsObserving(client_view)) - observed_client_view_.Add(client_view); - - const gfx::Rect client_area_rect(non_client_view->client_view()->bounds()); - SetClientArea( - gfx::Insets( - client_area_rect.y(), client_area_rect.x(), - non_client_view->bounds().height() - client_area_rect.bottom(), - non_client_view->bounds().width() - client_area_rect.right()), - std::vector<gfx::Rect>()); -} - -bool DesktopWindowTreeHostMus::IsFocusClientInstalledOnFocusSynchronizer() - const { - return MusClient::Get() - ->window_tree_client() - ->focus_synchronizer() - ->active_focus_client() == aura::client::GetFocusClient(window()); -} - -float DesktopWindowTreeHostMus::GetScaleFactor() const { - // TODO(sky): GetDisplayNearestWindow() should take a const aura::Window*. - return display::Screen::GetScreen() - ->GetDisplayNearestWindow(const_cast<aura::Window*>(window())) - .device_scale_factor(); -} - -bool DesktopWindowTreeHostMus::IsWaitingForRestoreToComplete() const { - return window_tree_host_window_observer_->is_waiting_for_restore(); -} - -bool DesktopWindowTreeHostMus::ShouldSendClientAreaToServer() const { - if (!auto_update_client_area_) - return false; - - return desktop_native_widget_aura_->widget_type() == - Widget::InitParams::TYPE_WINDOW; -} - -void DesktopWindowTreeHostMus::RestoreToPreminimizedState() { - DCHECK(IsMinimized()); - window_tree_host_window_observer_->set_is_waiting_for_restore(true); - base::AutoReset<bool> setter(&is_updating_window_visibility_, true); - window()->Show(); - if (compositor()) - compositor()->SetVisible(true); -} - -void DesktopWindowTreeHostMus::OnWindowTreeHostWindowVisibilityChanged( - bool visible) { - if (is_updating_window_visibility_) - return; - - // Call Show()/Hide() so that the visibility state is mirrored correctly. This - // function makes it so that calling Show()/Hide() on window() is the same as - // calling Show()/Hide() on the Widget. - base::AutoReset<bool> setter(&is_updating_window_visibility_, true); - if (visible) - Show(ui::SHOW_STATE_INACTIVE, gfx::Rect()); - else - Hide(); -} - -void DesktopWindowTreeHostMus::UpdateMinAndMaxSize() { - gfx::Size min_size = content_window()->delegate()->GetMinimumSize(); - gfx::Size max_size = content_window()->delegate()->GetMaximumSize(); - if (min_size_ == min_size && max_size_ == max_size) - return; - min_size_ = min_size; - max_size_ = max_size; - // Setting the property to |window()| to propagate those properties to the - // window server. - if (min_size_ == gfx::Size()) - window()->ClearProperty(aura::client::kMinimumSize); - else - window()->SetProperty(aura::client::kMinimumSize, new gfx::Size(min_size_)); - if (max_size_ == gfx::Size()) - window()->ClearProperty(aura::client::kMaximumSize); - else - window()->SetProperty(aura::client::kMaximumSize, new gfx::Size(max_size_)); -} - -void DesktopWindowTreeHostMus::Init(const Widget::InitParams& params) { - const bool translucent = - MusClient::ShouldMakeWidgetWindowsTranslucent(params); - content_window()->SetTransparent(translucent); - window()->SetTransparent(translucent); - - // The window manager may provide the initial show state, for example for - // Chrome OS lock screen windows. https://crbug.com/899055 - if (params.show_state != ui::SHOW_STATE_DEFAULT) - window()->SetProperty(aura::client::kShowStateKey, params.show_state); - - if (!params.bounds.IsEmpty()) { - // Init the scale now (before InitHost below), it is used by SetBoundsInDIP. - IntializeDeviceScaleFactor(GetDisplay().device_scale_factor()); - SetBoundsInDIP(params.bounds); - } - - // If the standard frame is not used, the frame area (rendered by the client) - // should be handled by the client, so it shouldn't update the client area - // by itself. See https://crbug.com/935338. - auto_update_client_area_ = !params.remove_standard_frame; - - cursor_manager_owner_ = std::make_unique<CursorManagerOwner>(window()); - InitHost(); - - NativeWidgetAura::SetShadowElevationFromInitParams(window(), params); - - // Widget's |InitParams::parent| has different meanings depending on the - // NativeWidgetPrivate implementation that the Widget creates (each Widget - // creates a NativeWidgetPrivate). When DesktopNativeWidgetAura is used as - // the NativeWidgetPrivate implementation, |InitParams::parent| means the - // entirety of the contents of the new Widget should be stacked above the - // entirety of the contents of the Widget for |InitParams::parent|, and - // the new Widget should be deleted when the Widget for - // |InitParams::parent| is deleted. Aura and mus provide support for - // transient windows, which provides both the stacking and ownership needed to - // support |InitParams::parent|. - // - // DesktopNativeWidgetAura internally creates two aura::Windows (one by - // WindowTreeHost, the other in |DesktopNativeWidgetAura::content_window_|). - // To have the entirety of the contents of the Widget appear on top of the - // entirety of the contents of another Widget, the stacking is done on the - // WindowTreeHost's window. For these reasons, the following code uses the - // Window associated with the WindowTreeHost of the |params.parent|. - // - // Views/Aura provide support for child-modal windows. Child-modal windows - // are windows that are modal to their transient parent. Because this code - // implements |InitParams::parent| in terms of transient parents, it means - // it is not possible to support both |InitParams::parent| as well as a - // child-modal window. This is *only* an issue if a Widget that uses a - // DesktopNativeWidgetAura needs to be child-modal to another window. At - // the current time NativeWidgetAura is always used for child-modal windows, - // so this isn't an issue. - // - // If we end up needing to use DesktopNativeWidgetAura for child-modal - // Widgets then we need something different. Possibilities include: - // . Have mus ignore child-modal windows and instead implement child-modal - // entirely in the client (this is what we do on Windows). To get this - // right likely means we need the ability to disable windows (see - // HWNDMessageHandler::InitModalType() for how Windows OS does this). - // . Implement |InitParams::parent| using a different (new) API. - if (params.parent && params.parent->GetHost()) { - aura::client::GetTransientWindowClient()->AddTransientChild( - params.parent->GetHost()->window(), window()); - } - - if (!params.accept_events) - window()->SetEventTargetingPolicy(ws::mojom::EventTargetingPolicy::NONE); -} - -void DesktopWindowTreeHostMus::OnNativeWidgetCreated( - const Widget::InitParams& params) { - if (params.parent && params.parent->GetHost()) { - parent_ = static_cast<DesktopWindowTreeHostMus*>(params.parent->GetHost()); - parent_->children_.insert(this); - } - native_widget_delegate_->OnNativeWidgetCreated(); -} - -void DesktopWindowTreeHostMus::OnActiveWindowChanged(bool active) { - // This function is called when there is a change in the active window the - // FocusClient for window() is associated with. This needs to potentially - // propagate to mus (the change may originate locally, not from mus). - // Propagating to the server is done by resetting the ActiveFocusClient. - if (active && !IsFocusClientInstalledOnFocusSynchronizer()) { - MusClient::Get() - ->window_tree_client() - ->focus_synchronizer() - ->SetActiveFocusClient(aura::client::GetFocusClient(window()), - window()); - } else if (!active && IsFocusClientInstalledOnFocusSynchronizer()) { - MusClient::Get() - ->window_tree_client() - ->focus_synchronizer() - ->SetActiveFocusClient(nullptr, nullptr); - } -} - -void DesktopWindowTreeHostMus::OnWidgetInitDone() { - // Because of construction order it's possible the bounds have changed before - // the NonClientView was created, which means we may not have sent the - // client-area and hit-test-mask. - SendClientAreaToServer(); - - MusClient::Get()->OnCaptureClientSet( - aura::client::GetCaptureClient(window())); -} - -std::unique_ptr<corewm::Tooltip> DesktopWindowTreeHostMus::CreateTooltip() { - return std::make_unique<corewm::TooltipAura>(); -} - -std::unique_ptr<aura::client::DragDropClient> -DesktopWindowTreeHostMus::CreateDragDropClient( - DesktopNativeCursorManager* cursor_manager) { - // aura-mus handles installing a DragDropClient. - return nullptr; -} - -std::unique_ptr<aura::client::ScreenPositionClient> -DesktopWindowTreeHostMus::CreateScreenPositionClient() { - return std::make_unique<ScreenPositionClientMus>(this); -} - -void DesktopWindowTreeHostMus::Close() { - if (close_widget_factory_.HasWeakPtrs()) - return; - - // Even though we don't close immediately, we need to hide immediately - // (otherwise events may be processed, which is unexpected). - Hide(); - - // This has to happen *after* Hide() above, otherwise animations won't work. - content_window()->Hide(); - - // Close doesn't delete this immediately, as 'this' may still be on the stack - // resulting in possible crashes when the stack unwindes. - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(&DesktopWindowTreeHostMus::CloseNow, - close_widget_factory_.GetWeakPtr())); -} - -void DesktopWindowTreeHostMus::CloseNow() { - MusClient::Get()->OnCaptureClientUnset( - aura::client::GetCaptureClient(window())); - - native_widget_delegate_->OnNativeWidgetDestroying(); - - // If we have children, close them. Use a copy for iteration because they'll - // remove themselves from |children_|. - std::set<DesktopWindowTreeHostMus*> children_copy = children_; - for (DesktopWindowTreeHostMus* child : children_copy) - child->CloseNow(); - DCHECK(children_.empty()); - - if (parent_) { - parent_->children_.erase(this); - parent_ = nullptr; - } - - DestroyCompositor(); - desktop_native_widget_aura_->OnHostClosed(); -} - -aura::WindowTreeHost* DesktopWindowTreeHostMus::AsWindowTreeHost() { - return this; -} - -void DesktopWindowTreeHostMus::Show(ui::WindowShowState show_state, - const gfx::Rect& restore_bounds) { - // Only notify if the visibility is really changing. - const bool notify_visibility_change = - is_updating_window_visibility_ || !IsVisible(); - if (notify_visibility_change) - native_widget_delegate_->OnNativeWidgetVisibilityChanging(true); - - // NOTE: this code is called from Widget::Show() (no args). Widget::Show() - // supplies ui::SHOW_STATE_DEFAULT as the |show_state| after the first call. - // If SHOW_STATE_DEFAULT is supplied, and the Window is currently minimized, - // the window should be restored to its preminimized state. - - if (show_state == ui::SHOW_STATE_MAXIMIZED && !restore_bounds.IsEmpty()) { - window()->SetProperty(aura::client::kRestoreBoundsKey, - new gfx::Rect(restore_bounds)); - } - if (show_state == ui::SHOW_STATE_MAXIMIZED || - show_state == ui::SHOW_STATE_FULLSCREEN) { - window()->SetProperty(aura::client::kShowStateKey, show_state); - window_tree_host_window_observer_->set_is_waiting_for_restore(false); - } else if (show_state == ui::SHOW_STATE_DEFAULT && IsMinimized()) { - RestoreToPreminimizedState(); - } else if (show_state == ui::SHOW_STATE_MINIMIZED && !IsMinimized()) { - Minimize(); - } - // DesktopWindowTreeHostMus is unique in that it calls window()->Show() here. - // All other implementations call window()->Show() from the constructor. This - // is necessary as window()'s visibility is mirrored in the server, on other - // platforms it's the visibility of the AcceleratedWidget that matters and - // dictates what is actually drawn on screen. - { - base::AutoReset<bool> setter(&is_updating_window_visibility_, true); - window()->Show(); - } - if (compositor()) - compositor()->SetVisible(true); - - // |content_window_| is the Window that will be focused by way of Activate(). - // Ensure |content_window_| is visible before the call to Activate(), - // otherwise focus goes to window(). - content_window()->Show(); - - if (show_state != ui::SHOW_STATE_MINIMIZED) - UpdateMinAndMaxSize(); - - if (notify_visibility_change) - native_widget_delegate_->OnNativeWidgetVisibilityChanged(true); - - if (native_widget_delegate_->CanActivate()) { - if (show_state != ui::SHOW_STATE_INACTIVE && - show_state != ui::SHOW_STATE_MINIMIZED) { - Activate(); - } - - // SetInitialFocus() should be always be called, even for - // SHOW_STATE_INACTIVE. If the window has to stay inactive, the method will - // do the right thing. - // Activate() might fail if the window is non-activatable. In this case, we - // should pass SHOW_STATE_INACTIVE to SetInitialFocus() to stop the initial - // focused view from getting focused. See crbug.com/515594 for example. - native_widget_delegate_->SetInitialFocus( - IsActive() ? show_state : ui::SHOW_STATE_INACTIVE); - } -} - -bool DesktopWindowTreeHostMus::IsVisible() const { - // Go through the DesktopNativeWidgetAura::IsVisible() for checking - // visibility of the parent as it has additional checks beyond checking the - // aura::Window. - return window()->IsVisible() && - (!parent_ || - static_cast<const internal::NativeWidgetPrivate*>( - parent_->desktop_native_widget_aura_) - ->IsVisible()); -} - -void DesktopWindowTreeHostMus::SetSize(const gfx::Size& size) { - // Use bounds_in_dip(), as the origin of window() is always at (0, 0). - gfx::Rect screen_bounds = bounds_in_dip(); - screen_bounds.set_size(size); - SetBoundsInDIP(screen_bounds); -} - -void DesktopWindowTreeHostMus::StackAbove(aura::Window* relative) { - // Windows and X11 check for |relative| being nullptr and fail silently. It - // also looks like |relative| is usually multiple children deep in the root - // window, which we must pass instead. - if (relative && relative->GetRootWindow()) - WindowTreeHostMus::StackAbove(relative->GetRootWindow()); -} - -void DesktopWindowTreeHostMus::StackAtTop() { - // Request to the server to stack our current mus window at the top. Our - // window() is a root, and we can't reach up past it so we can't just request - // a Reorder(), which is what we'd do to reorder our own subwindows. - WindowTreeHostMus::StackAtTop(); -} - -void DesktopWindowTreeHostMus::CenterWindow(const gfx::Size& size) { - gfx::Rect bounds_to_center_in = GetWorkAreaBoundsInScreen(); - - // If there is a transient parent and it fits |size|, then center over it. - if (wm::GetTransientParent(content_window())) { - gfx::Rect transient_parent_bounds = - wm::GetTransientParent(content_window())->GetBoundsInScreen(); - if (transient_parent_bounds.height() >= size.height() && - transient_parent_bounds.width() >= size.width()) { - bounds_to_center_in = transient_parent_bounds; - } - } - - gfx::Rect resulting_bounds(bounds_to_center_in); - resulting_bounds.ClampToCenteredSize(size); - SetBoundsInDIP(resulting_bounds); -} - -void DesktopWindowTreeHostMus::GetWindowPlacement( - gfx::Rect* bounds, - ui::WindowShowState* show_state) const { - // Implementation matches that of NativeWidgetAura. - *bounds = GetRestoredBounds(); - if (IsWaitingForRestoreToComplete()) { - // The real state is not known, use ui::SHOW_STATE_NORMAL to avoid saving - // the minimized state. - *show_state = ui::SHOW_STATE_NORMAL; - } else { - *show_state = window()->GetProperty(aura::client::kShowStateKey); - } -} - -gfx::Rect DesktopWindowTreeHostMus::GetWindowBoundsInScreen() const { - return bounds_in_dip(); -} - -gfx::Rect DesktopWindowTreeHostMus::GetClientAreaBoundsInScreen() const { - // View-to-screen coordinate system transformations depend on this returning - // the full window bounds, for example View::ConvertPointToScreen(). - return GetWindowBoundsInScreen(); -} - -gfx::Rect DesktopWindowTreeHostMus::GetRestoredBounds() const { - // Restored bounds should only be relevant if the window is minimized, - // maximized, or fullscreen. However, in some places the code expects - // GetRestoredBounds() to return the current window bounds if the window is - // not in either state. - if (IsMinimized() || IsMaximized() || IsFullscreen()) { - // Restore bounds are in screen coordinates, no need to convert. - gfx::Rect* restore_bounds = - window()->GetProperty(aura::client::kRestoreBoundsKey); - if (restore_bounds) - return *restore_bounds; - } - return GetWindowBoundsInScreen(); -} - -std::string DesktopWindowTreeHostMus::GetWorkspace() const { - // Only used on x11. - return std::string(); -} - -gfx::Rect DesktopWindowTreeHostMus::GetWorkAreaBoundsInScreen() const { - return GetDisplay().work_area(); -} - -void DesktopWindowTreeHostMus::SetShape( - std::unique_ptr<Widget::ShapeRects> native_shape) { - MusClient::Get()->window_tree_client()->SetShape( - aura::WindowMus::Get(window()), std::move(native_shape)); -} - -void DesktopWindowTreeHostMus::Activate() { - if (!IsVisible() && !IsMinimized()) - return; - - // Activate() is expected to restore a minimized window. - if (IsMinimized()) - RestoreToPreminimizedState(); - - // This should result in OnActiveFocusClientChanged() being called, which - // triggers a call to DesktopNativeWidgetAura::HandleActivationChanged(), - // which focuses the right window. - MusClient::Get() - ->window_tree_client() - ->focus_synchronizer() - ->SetActiveFocusClient(aura::client::GetFocusClient(window()), window()); - if (is_active_) - window()->SetProperty(aura::client::kDrawAttentionKey, false); -} - -void DesktopWindowTreeHostMus::Deactivate() { - if (!is_active_) - return; - - // Reset the active focus client, which will trigger resetting active status. - // This is done so that we deactivate immediately. - DCHECK(IsFocusClientInstalledOnFocusSynchronizer()); - MusClient::Get() - ->window_tree_client() - ->focus_synchronizer() - ->SetActiveFocusClient(nullptr, nullptr); - DCHECK(!is_active_); - - // Then ask the window manager to deactivate, which effectively means pick - // another window to activate. - DeactivateWindow(); -} - -bool DesktopWindowTreeHostMus::IsActive() const { - return is_active_; -} - -void DesktopWindowTreeHostMus::Maximize() { - window()->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); -} - -void DesktopWindowTreeHostMus::Minimize() { - window()->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED); - - // When minimized, this should no longer be active. - if (IsFocusClientInstalledOnFocusSynchronizer()) { - MusClient::Get() - ->window_tree_client() - ->focus_synchronizer() - ->SetActiveFocusClient(nullptr, nullptr); - } -} - -void DesktopWindowTreeHostMus::Restore() { - window()->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); -} - -bool DesktopWindowTreeHostMus::IsMaximized() const { - return window()->GetProperty(aura::client::kShowStateKey) == - ui::SHOW_STATE_MAXIMIZED; -} - -bool DesktopWindowTreeHostMus::IsMinimized() const { - return window()->GetProperty(aura::client::kShowStateKey) == - ui::SHOW_STATE_MINIMIZED && - !IsWaitingForRestoreToComplete(); -} - -bool DesktopWindowTreeHostMus::HasCapture() const { - // Capture state is held by DesktopNativeWidgetAura::content_window_. - // DesktopNativeWidgetAura::HasCapture() calls content_window_->HasCapture(), - // and this. That means this function can always return true. - return true; -} - -void DesktopWindowTreeHostMus::SetAlwaysOnTop(bool always_on_top) { - window()->SetProperty(aura::client::kAlwaysOnTopKey, always_on_top); -} - -bool DesktopWindowTreeHostMus::IsAlwaysOnTop() const { - return window()->GetProperty(aura::client::kAlwaysOnTopKey); -} - -void DesktopWindowTreeHostMus::SetVisibleOnAllWorkspaces(bool always_visible) { - // Not applicable to chromeos. -} - -bool DesktopWindowTreeHostMus::IsVisibleOnAllWorkspaces() const { - return false; -} - -bool DesktopWindowTreeHostMus::SetWindowTitle(const base::string16& title) { - WidgetDelegate* widget_delegate = - native_widget_delegate_->AsWidget()->widget_delegate(); - const bool show = widget_delegate && widget_delegate->ShouldShowWindowTitle(); - if (window()->GetTitle() == title && - window()->GetProperty(aura::client::kTitleShownKey) == show) { - return false; - } - window()->SetProperty(aura::client::kTitleShownKey, show); - window()->SetTitle(title); - return true; -} - -void DesktopWindowTreeHostMus::ClearNativeFocus() { - aura::client::FocusClient* client = aura::client::GetFocusClient(window()); - if (client && window()->Contains(client->GetFocusedWindow())) - client->ResetFocusWithinActiveWindow(window()); -} - -Widget::MoveLoopResult DesktopWindowTreeHostMus::RunMoveLoop( - const gfx::Vector2d& drag_offset, - Widget::MoveLoopSource source, - Widget::MoveLoopEscapeBehavior escape_behavior) { - base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); - - ws::mojom::MoveLoopSource mus_source = - source == Widget::MOVE_LOOP_SOURCE_MOUSE - ? ws::mojom::MoveLoopSource::MOUSE - : ws::mojom::MoveLoopSource::TOUCH; - - bool success = false; - // Don't use display::Screen::GetCursorScreenPoint() -- that's incorrect for - // touch events. Rather the cursor location can be computed from window's - // location with drag_offset. - gfx::Point cursor_location = window()->GetBoundsInScreen().origin() + - gfx::ToFlooredVector2d(drag_offset); - WindowTreeHostMus::PerformWindowMove( - content_window(), mus_source, cursor_location, HTCAPTION, - base::BindOnce(&OnMoveLoopEnd, &success, run_loop.QuitClosure())); - - run_loop.Run(); - - return success ? Widget::MOVE_LOOP_SUCCESSFUL : Widget::MOVE_LOOP_CANCELED; -} - -void DesktopWindowTreeHostMus::EndMoveLoop() { - WindowTreeHostMus::CancelWindowMove(); -} - -void DesktopWindowTreeHostMus::SetVisibilityChangedAnimationsEnabled( - bool value) { - window()->SetProperty(aura::client::kAnimationsDisabledKey, !value); -} - -NonClientFrameView* DesktopWindowTreeHostMus::CreateNonClientFrameView() { - if (!ShouldSendClientAreaToServer()) - return nullptr; - - // Initialize kTopViewInset to a default value. Further updates will come - // from Ash. This is necessary so that during app window creation, - // GetWindowBoundsForClientBounds() can calculate correctly. - SetTopViewInsetToDefault(); - return new ClientSideNonClientFrameView(native_widget_delegate_->AsWidget()); -} - -bool DesktopWindowTreeHostMus::ShouldUseNativeFrame() const { - return false; -} - -bool DesktopWindowTreeHostMus::ShouldWindowContentsBeTransparent() const { - return false; -} - -void DesktopWindowTreeHostMus::FrameTypeChanged() { - native_widget_delegate_->AsWidget()->ThemeChanged(); -} - -void DesktopWindowTreeHostMus::SetFullscreen(bool fullscreen) { - if (IsFullscreen() == fullscreen) - return; // Nothing to do. - - // Retrieve restore bounds before leaving fullscreen. - gfx::Rect restore_bounds; - if (!fullscreen) - restore_bounds = GetRestoredBounds(); - - // Change the fullscreen state. - wm::SetWindowFullscreen(window(), fullscreen); - - // Preset bounds with heuristic size to provide synchronous bounds change - // after the switch to/from fullscreen. - if (fullscreen) { - window()->SetProperty(aura::client::kRestoreBoundsKey, - new gfx::Rect(GetWindowBoundsInScreen())); - SetBoundsInDIP(GetDisplay().bounds()); - } else { - SetTopViewInsetToDefault(); - SetBoundsInDIP(restore_bounds); - } -} - -bool DesktopWindowTreeHostMus::IsFullscreen() const { - return window()->GetProperty(aura::client::kShowStateKey) == - ui::SHOW_STATE_FULLSCREEN; -} - -void DesktopWindowTreeHostMus::SetOpacity(float opacity) { - WindowTreeHostMus::SetOpacity(opacity); -} - -void DesktopWindowTreeHostMus::SetAspectRatio(const gfx::SizeF& aspect_ratio) { - window()->SetProperty(aura::client::kAspectRatio, - new gfx::SizeF(aspect_ratio)); -} - -void DesktopWindowTreeHostMus::SetWindowIcons(const gfx::ImageSkia& window_icon, - const gfx::ImageSkia& app_icon) {} - -void DesktopWindowTreeHostMus::InitModalType(ui::ModalType modal_type) { - // See comment in Init() related to |InitParams::parent| as to why this DCHECK - // is here. - DCHECK_NE(modal_type, ui::MODAL_TYPE_CHILD); - window()->SetProperty(aura::client::kModalKey, modal_type); -} - -void DesktopWindowTreeHostMus::FlashFrame(bool flash_frame) { - window()->SetProperty(aura::client::kDrawAttentionKey, flash_frame); -} - -bool DesktopWindowTreeHostMus::IsAnimatingClosed() const { - return false; -} - -bool DesktopWindowTreeHostMus::IsTranslucentWindowOpacitySupported() const { - return true; -} - -void DesktopWindowTreeHostMus::SizeConstraintsChanged() { - int32_t behavior = ws::mojom::kResizeBehaviorNone; - Widget* widget = native_widget_delegate_->AsWidget(); - if (widget->widget_delegate()) - behavior = widget->widget_delegate()->GetResizeBehavior(); - window()->SetProperty(aura::client::kResizeBehaviorKey, behavior); - UpdateMinAndMaxSize(); -} - -bool DesktopWindowTreeHostMus::ShouldUpdateWindowTransparency() const { - // Needed so the window manager can render the client decorations. - return false; -} - -bool DesktopWindowTreeHostMus::ShouldUseDesktopNativeCursorManager() const { - // We manage the cursor ourself. - return false; -} - -bool DesktopWindowTreeHostMus::ShouldCreateVisibilityController() const { - // Window manager takes care of all top-level window animations. - return false; -} - -void DesktopWindowTreeHostMus::SetBoundsInDIP(const gfx::Rect& bounds_in_dip) { - // Do not use ConvertRectToPixel, enclosing rects cause problems. - SetBounds(bounds_in_dip, viz::LocalSurfaceIdAllocation()); -} - -void DesktopWindowTreeHostMus::OnCanActivateChanged() { - MusClient::Get()->window_tree_client()->SetCanFocus( - window(), native_widget_delegate_->CanActivate()); -} - -void DesktopWindowTreeHostMus::OnWindowManagerFrameValuesChanged() { - NonClientView* non_client_view = - native_widget_delegate_->AsWidget()->non_client_view(); - if (non_client_view) { - non_client_view->InvalidateLayout(); - non_client_view->SchedulePaint(); - } - - SendClientAreaToServer(); -} - -void DesktopWindowTreeHostMus::OnActiveFocusClientChanged( - aura::client::FocusClient* focus_client, - aura::Window* focus_client_root) { - if (focus_client_root == this->window()) { - is_active_ = true; - desktop_native_widget_aura_->HandleActivationChanged(true); - } else if (is_active_) { - is_active_ = false; - desktop_native_widget_aura_->HandleActivationChanged(false); - } -} - -void DesktopWindowTreeHostMus::OnWindowPropertyChanged(aura::Window* window, - const void* key, - intptr_t old) { - DCHECK_EQ(window, content_window()); - DCHECK(!window->GetRootWindow() || this->window() == window->GetRootWindow()); - if (!this->window()) - return; - - // Allow mus clients to mirror widget window properties to their root windows. - MusPropertyMirror* property_mirror = MusClient::Get()->mus_property_mirror(); - if (property_mirror) { - property_mirror->MirrorPropertyFromWidgetWindowToRootWindow( - window, this->window(), key); - } -} - -void DesktopWindowTreeHostMus::ShowImpl() { - // This code path is hit when the server initiated the change. In such a case - // the window should not be made active. If the server wants the window to be - // active, it will make the window active. - Show(ui::SHOW_STATE_INACTIVE, gfx::Rect()); -} - -void DesktopWindowTreeHostMus::HideImpl() { - // If |is_updating_window_visibility_| is true, this is being called in - // response to window()'s visibility changing, in which case we need to - // continue on to complete processing of the hide. - if (!IsVisible() && !is_updating_window_visibility_) - return; - - native_widget_delegate_->OnNativeWidgetVisibilityChanging(false); - { - base::AutoReset<bool> setter(&is_updating_window_visibility_, true); - WindowTreeHostMus::HideImpl(); - } - native_widget_delegate_->OnNativeWidgetVisibilityChanged(false); - - // When hiding we can't possibly be active any more. Reset the FocusClient, - // which effectively triggers giving up focus (and activation). Mus will - // eventually generate a focus event, but that's async. This should be done - // after the window gets hidden actually, since some code (like - // WindowActivityWatcher) assumes closing window is already invisible when the - // focus is lost. See https://crbug.com/896080. - if (IsFocusClientInstalledOnFocusSynchronizer()) { - MusClient::Get() - ->window_tree_client() - ->focus_synchronizer() - ->SetActiveFocusClient(nullptr, nullptr); - } -} - -void DesktopWindowTreeHostMus::SetBounds( - const gfx::Rect& bounds, - const viz::LocalSurfaceIdAllocation& local_surface_id_allocation) { - gfx::Rect final_bounds = bounds; - // If the server initiated the bounds change, then we need to honor it. - if (!is_server_setting_bounds() && bounds_in_dip().size() != bounds.size()) { - gfx::Size size = bounds.size(); - size.SetToMax(native_widget_delegate_->GetMinimumSize()); - const gfx::Size max_size = native_widget_delegate_->GetMaximumSize(); - if (!max_size.IsEmpty()) - size.SetToMin(max_size); - final_bounds.set_size(size); - UpdateMinAndMaxSize(); - } - WindowTreeHostMus::SetBounds(final_bounds, local_surface_id_allocation); -} - -void DesktopWindowTreeHostMus::SetBoundsInPixels( - const gfx::Rect& bounds_in_pixels, - const viz::LocalSurfaceIdAllocation& local_surface_id_allocation) { - // NOTE: in typical usage SetBounds() is called and not this, but as - // WindowTreeHost exposes SetBoundsInPixels() this function may be called too. - // If the server initiated the bounds change, then we need to honor it. - gfx::Rect final_bounds_in_pixels = bounds_in_pixels; - if (!is_server_setting_bounds() && - GetBoundsInPixels().size() != bounds_in_pixels.size()) { - gfx::Size size = bounds_in_pixels.size(); - size.SetToMax(gfx::ConvertSizeToPixel( - GetScaleFactor(), native_widget_delegate_->GetMinimumSize())); - const gfx::Size max_size_in_pixels = gfx::ConvertSizeToPixel( - GetScaleFactor(), native_widget_delegate_->GetMaximumSize()); - if (!max_size_in_pixels.IsEmpty()) - size.SetToMin(max_size_in_pixels); - final_bounds_in_pixels.set_size(size); - UpdateMinAndMaxSize(); - } - WindowTreeHostMus::SetBoundsInPixels(final_bounds_in_pixels, - local_surface_id_allocation); -} - -void DesktopWindowTreeHostMus::OnViewBoundsChanged(View* observed_view) { - DCHECK_EQ( - observed_view, - native_widget_delegate_->AsWidget()->non_client_view()->client_view()); - - SendClientAreaToServer(); -} - -void DesktopWindowTreeHostMus::OnViewIsDeleting(View* observed_view) { - observed_client_view_.Remove(observed_view); -} - -void DesktopWindowTreeHostMus::SetTopViewInsetToDefault() { - const auto& values = WindowManagerFrameValues::instance(); - window()->SetProperty(aura::client::kTopViewInset, - IsMaximized() ? values.maximized_insets.top() - : values.normal_insets.top()); -} - -aura::Window* DesktopWindowTreeHostMus::content_window() { - return desktop_native_widget_aura_->content_window(); -} - -} // namespace views
diff --git a/ui/views/mus/desktop_window_tree_host_mus.h b/ui/views/mus/desktop_window_tree_host_mus.h deleted file mode 100644 index 1246f2d2..0000000 --- a/ui/views/mus/desktop_window_tree_host_mus.h +++ /dev/null
@@ -1,224 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_MUS_DESKTOP_WINDOW_TREE_HOST_MUS_H_ -#define UI_VIEWS_MUS_DESKTOP_WINDOW_TREE_HOST_MUS_H_ - -#include <memory> -#include <set> - -#include "base/macros.h" -#include "base/scoped_observer.h" -#include "ui/aura/mus/focus_synchronizer_observer.h" -#include "ui/aura/mus/window_tree_host_mus.h" -#include "ui/aura/window_observer.h" -#include "ui/views/mus/mus_client_observer.h" -#include "ui/views/mus/mus_export.h" -#include "ui/views/view_observer.h" -#include "ui/views/widget/desktop_aura/desktop_window_tree_host.h" -#include "ui/views/widget/widget.h" - -namespace views { - -class CursorManagerOwner; - -class VIEWS_MUS_EXPORT DesktopWindowTreeHostMus - : public DesktopWindowTreeHost, - public MusClientObserver, - public aura::FocusSynchronizerObserver, - public aura::WindowObserver, - public aura::WindowTreeHostMus, - public views::ViewObserver { - public: - DesktopWindowTreeHostMus( - aura::WindowTreeHostMusInitParams init_params, - internal::NativeWidgetDelegate* native_widget_delegate, - DesktopNativeWidgetAura* desktop_native_widget_aura); - ~DesktopWindowTreeHostMus() override; - - // Called when the window was deleted on the server. - void ServerDestroyedWindow() { CloseNow(); } - - private: - class WindowTreeHostWindowObserver; - - void SendClientAreaToServer(); - - // Returns true if the FocusClient associated with our window is installed on - // the FocusSynchronizer. - bool IsFocusClientInstalledOnFocusSynchronizer() const; - - // Helper function to get the scale factor. - float GetScaleFactor() const; - - // Returns true if the client area should be set on this. - bool ShouldSendClientAreaToServer() const; - - bool IsWaitingForRestoreToComplete() const; - - // Restores the window to its pre-minimized state. There are two paths to - // unminimizing/restoring a window: - // . Implicitly by calling Show()/Activate(). In this scenario the expectation - // is the Widget returns to its pre-minimized state. - // DesktopWindowTreeHostMus does *not* cache the pre-minimized state, only - // the server knows it. - // . By calling Restore(). Restore sets the state to normal, circumventing - // the pre-minimized state in the server. This mirrors what NativeWidgetAura - // does. - // This function handles the first case. As DesktopWindowTreeHostMus doesn't - // know the new state, an observer is added that tracks when the show state - // changes. While waiting, IsMinimized() returns false. - void RestoreToPreminimizedState(); - - // Called when window()'s visibility changes to |visible|. This is called from - // WindowObserver::OnWindowVisibilityChanged(). - void OnWindowTreeHostWindowVisibilityChanged(bool visible); - - // Checks the minimum and the maximum size and notifies to the window service. - void UpdateMinAndMaxSize(); - - // DesktopWindowTreeHost: - void Init(const Widget::InitParams& params) override; - void OnNativeWidgetCreated(const Widget::InitParams& params) override; - void OnActiveWindowChanged(bool active) override; - void OnWidgetInitDone() override; - std::unique_ptr<corewm::Tooltip> CreateTooltip() override; - std::unique_ptr<aura::client::DragDropClient> CreateDragDropClient( - DesktopNativeCursorManager* cursor_manager) override; - std::unique_ptr<aura::client::ScreenPositionClient> - CreateScreenPositionClient() override; - void Close() override; - void CloseNow() override; - aura::WindowTreeHost* AsWindowTreeHost() override; - void Show(ui::WindowShowState show_state, - const gfx::Rect& restore_bounds) override; - bool IsVisible() const override; - void SetSize(const gfx::Size& size) override; - void StackAbove(aura::Window* window) override; - void StackAtTop() override; - void CenterWindow(const gfx::Size& size) override; - void GetWindowPlacement(gfx::Rect* bounds, - ui::WindowShowState* show_state) const override; - gfx::Rect GetWindowBoundsInScreen() const override; - gfx::Rect GetClientAreaBoundsInScreen() const override; - gfx::Rect GetRestoredBounds() const override; - std::string GetWorkspace() const override; - gfx::Rect GetWorkAreaBoundsInScreen() const override; - void SetShape(std::unique_ptr<Widget::ShapeRects> native_shape) override; - void Activate() override; - void Deactivate() override; - bool IsActive() const override; - void Maximize() override; - void Minimize() override; - void Restore() override; - bool IsMaximized() const override; - bool IsMinimized() const override; - bool HasCapture() const override; - void SetAlwaysOnTop(bool always_on_top) override; - bool IsAlwaysOnTop() const override; - void SetVisibleOnAllWorkspaces(bool always_visible) override; - bool IsVisibleOnAllWorkspaces() const override; - bool SetWindowTitle(const base::string16& title) override; - void ClearNativeFocus() override; - Widget::MoveLoopResult RunMoveLoop( - const gfx::Vector2d& drag_offset, - Widget::MoveLoopSource source, - Widget::MoveLoopEscapeBehavior escape_behavior) override; - void EndMoveLoop() override; - void SetVisibilityChangedAnimationsEnabled(bool value) override; - NonClientFrameView* CreateNonClientFrameView() override; - bool ShouldUseNativeFrame() const override; - bool ShouldWindowContentsBeTransparent() const override; - void FrameTypeChanged() override; - void SetFullscreen(bool fullscreen) override; - bool IsFullscreen() const override; - void SetOpacity(float opacity) override; - void SetAspectRatio(const gfx::SizeF& aspect_ratio) override; - void SetWindowIcons(const gfx::ImageSkia& window_icon, - const gfx::ImageSkia& app_icon) override; - void InitModalType(ui::ModalType modal_type) override; - void FlashFrame(bool flash_frame) override; - bool IsAnimatingClosed() const override; - bool IsTranslucentWindowOpacitySupported() const override; - void SizeConstraintsChanged() override; - bool ShouldUpdateWindowTransparency() const override; - bool ShouldUseDesktopNativeCursorManager() const override; - bool ShouldCreateVisibilityController() const override; - void SetBoundsInDIP(const gfx::Rect& bounds_in_dip) override; - void OnCanActivateChanged() override; - - // MusClientObserver: - void OnWindowManagerFrameValuesChanged() override; - - // aura::FocusSynchronizerObserver: - void OnActiveFocusClientChanged(aura::client::FocusClient* focus_client, - aura::Window* focus_client_root) override; - - // aura::WindowObserver: - void OnWindowPropertyChanged(aura::Window* window, - const void* key, - intptr_t old) override; - - // aura::WindowTreeHostMus: - void ShowImpl() override; - void HideImpl() override; - void SetBounds(const gfx::Rect& bounds_in_pixels, - const viz::LocalSurfaceIdAllocation& - local_surface_id_allocation) override; - void SetBoundsInPixels(const gfx::Rect& bounds_in_pixels, - const viz::LocalSurfaceIdAllocation& - local_surface_id_allocation) override; - - // views::ViewObserver: - void OnViewBoundsChanged(views::View* observed_view) override; - void OnViewIsDeleting(View* observed_view) override; - - // Sets kTopViewInset to the default value as a heuristic to assist with - // reducing the number of bounds changes during window creation or - // entering/exiting fullscreen. - void SetTopViewInsetToDefault(); - - // Accessor for DesktopNativeWidgetAura::content_window(). - aura::Window* content_window(); - - internal::NativeWidgetDelegate* native_widget_delegate_; - - DesktopNativeWidgetAura* desktop_native_widget_aura_; - - // We can optionally have a parent which can order us to close, or own - // children who we're responsible for closing when we CloseNow(). - DesktopWindowTreeHostMus* parent_ = nullptr; - std::set<DesktopWindowTreeHostMus*> children_; - - bool is_active_ = false; - - std::unique_ptr<CursorManagerOwner> cursor_manager_owner_; - - bool auto_update_client_area_ = true; - - // Observes changes to the ClientView. Used to update the client area in the - // server. - ScopedObserver<views::View, views::ViewObserver> observed_client_view_{this}; - - // If true, |this| is changing the visibility of window(), or is processing - // a change in the visibility of window(). - bool is_updating_window_visibility_ = false; - - // The maximum size and the minimum size of the window. - gfx::Size max_size_; - gfx::Size min_size_; - - // aura::WindowObserver on window(). - std::unique_ptr<WindowTreeHostWindowObserver> - window_tree_host_window_observer_; - - // Used so that Close() isn't immediate. - base::WeakPtrFactory<DesktopWindowTreeHostMus> close_widget_factory_; - - DISALLOW_COPY_AND_ASSIGN(DesktopWindowTreeHostMus); -}; - -} // namespace views - -#endif // UI_VIEWS_MUS_DESKTOP_WINDOW_TREE_HOST_MUS_H_
diff --git a/ui/views/mus/desktop_window_tree_host_mus_unittest.cc b/ui/views/mus/desktop_window_tree_host_mus_unittest.cc deleted file mode 100644 index efdb2e1..0000000 --- a/ui/views/mus/desktop_window_tree_host_mus_unittest.cc +++ /dev/null
@@ -1,1105 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/desktop_window_tree_host_mus.h" - -#include "base/bind.h" -#include "base/command_line.h" -#include "base/strings/utf_string_conversions.h" -#include "base/test/bind_test_util.h" -#include "services/ws/test_ws/test_ws.mojom-test-utils.h" -#include "services/ws/test_ws/test_ws.mojom.h" -#include "ui/aura/client/aura_constants.h" -#include "ui/aura/client/cursor_client.h" -#include "ui/aura/client/focus_client.h" -#include "ui/aura/client/transient_window_client.h" -#include "ui/aura/env.h" -#include "ui/aura/mus/capture_synchronizer.h" -#include "ui/aura/mus/focus_synchronizer.h" -#include "ui/aura/mus/in_flight_change.h" -#include "ui/aura/mus/window_mus.h" -#include "ui/aura/mus/window_tree_client.h" -#include "ui/aura/mus/window_tree_client_test_observer.h" -#include "ui/aura/mus/window_tree_host_mus.h" -#include "ui/aura/test/mus/change_completion_waiter.h" -#include "ui/aura/test/mus/test_window_tree.h" -#include "ui/aura/test/mus/window_tree_client_test_api.h" -#include "ui/aura/window.h" -#include "ui/display/display_switches.h" -#include "ui/events/base_event_utils.h" -#include "ui/events/event.h" -#include "ui/gfx/geometry/dip_util.h" -#include "ui/views/mus/mus_client.h" -#include "ui/views/mus/mus_client_test_api.h" -#include "ui/views/mus/screen_mus.h" -#include "ui/views/mus/window_manager_frame_values.h" -#include "ui/views/test/native_widget_factory.h" -#include "ui/views/test/views_test_base.h" -#include "ui/views/widget/widget.h" -#include "ui/views/widget/widget_delegate.h" -#include "ui/views/widget/widget_observer.h" -#include "ui/wm/core/shadow_types.h" -#include "ui/wm/core/transient_window_manager.h" -#include "ui/wm/public/activation_client.h" - -namespace views { - -class DesktopWindowTreeHostMusTest : public ViewsTestBase, - public WidgetObserver { - public: - DesktopWindowTreeHostMusTest() = default; - ~DesktopWindowTreeHostMusTest() override = default; - - // ViewsTestBase: - void SetUp() override { - set_native_widget_type(NativeWidgetType::kDesktop); - ViewsTestBase::SetUp(); - } - - // Creates a test widget. Takes ownership of |delegate|. - std::unique_ptr<Widget> CreateWidget(WidgetDelegate* delegate = nullptr, - aura::Window* parent = nullptr) { - std::unique_ptr<Widget> widget = std::make_unique<Widget>(); - Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW); - params.delegate = delegate; - params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - params.bounds = gfx::Rect(0, 1, 111, 123); - params.parent = parent; - widget->Init(params); - widget->AddObserver(this); - return widget; - } - - const Widget* widget_activated() const { return widget_activated_; } - const Widget* widget_deactivated() const { return widget_deactivated_; } - - private: - void OnWidgetActivationChanged(Widget* widget, bool active) override { - if (active) { - widget_activated_ = widget; - } else { - if (widget_activated_ == widget) - widget_activated_ = nullptr; - widget_deactivated_ = widget; - } - } - - Widget* widget_activated_ = nullptr; - Widget* widget_deactivated_ = nullptr; - - DISALLOW_COPY_AND_ASSIGN(DesktopWindowTreeHostMusTest); -}; - -class ExpectsNullCursorClientDuringTearDown : public aura::WindowObserver { - public: - explicit ExpectsNullCursorClientDuringTearDown(aura::Window* window) - : window_(window) { - window_->AddObserver(this); - } - - ~ExpectsNullCursorClientDuringTearDown() override { EXPECT_FALSE(window_); } - - private: - // aura::WindowObserver: - void OnWindowRemovingFromRootWindow(aura::Window* window, - aura::Window* new_root) override { - aura::client::CursorClient* cursor_client = - aura::client::GetCursorClient(window->GetRootWindow()); - EXPECT_FALSE(cursor_client); - window_->RemoveObserver(this); - window_ = nullptr; - } - - aura::Window* window_; - DISALLOW_COPY_AND_ASSIGN(ExpectsNullCursorClientDuringTearDown); -}; - -// Tests that the window service can set the initial show state for a window. -// https://crbug.com/899055 -TEST_F(DesktopWindowTreeHostMusTest, ShowStateFromWindowService) { - // Wait for the window created by - // aura::TestScreen::CreateHostForPrimaryDisplay() lest it be the one that is - // impacted by MaximizeNextWindow(). - aura::test::WaitForAllChangesToComplete(); - - // Configure the window service to maximize the next top-level window. - test_ws::mojom::TestWsPtr test_ws_ptr; - MusClient::Get()->window_tree_client()->connector()->BindInterface( - test_ws::mojom::kServiceName, &test_ws_ptr); - test_ws::mojom::TestWsAsyncWaiter wait_for(test_ws_ptr.get()); - wait_for.MaximizeNextWindow(); - - // Create a widget with the default show state. - Widget widget; - Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW); - params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - params.bounds = gfx::Rect(0, 0, 100, 100); - EXPECT_EQ(ui::SHOW_STATE_DEFAULT, params.show_state); - widget.Init(params); - aura::test::WaitForAllChangesToComplete(); - - // Window service provided the show state. - EXPECT_TRUE(widget.IsMaximized()); -} - -TEST_F(DesktopWindowTreeHostMusTest, Visibility) { - std::unique_ptr<Widget> widget(CreateWidget()); - EXPECT_FALSE(widget->IsVisible()); - EXPECT_FALSE(widget->GetNativeView()->IsVisible()); - // It's important the parent is also hidden as this value is sent to the - // server. - EXPECT_FALSE(widget->GetNativeView()->parent()->IsVisible()); - widget->Show(); - EXPECT_TRUE(widget->IsVisible()); - EXPECT_TRUE(widget->GetNativeView()->IsVisible()); - EXPECT_TRUE(widget->GetNativeView()->parent()->IsVisible()); - widget->Hide(); - EXPECT_FALSE(widget->IsVisible()); - EXPECT_FALSE(widget->GetNativeView()->IsVisible()); - EXPECT_FALSE(widget->GetNativeView()->parent()->IsVisible()); -} - -TEST_F(DesktopWindowTreeHostMusTest, Capture) { - std::unique_ptr<Widget> widget1(CreateWidget()); - widget1->Show(); - EXPECT_FALSE(widget1->HasCapture()); - - std::unique_ptr<Widget> widget2(CreateWidget()); - widget2->Show(); - EXPECT_FALSE(widget2->HasCapture()); - - widget1->SetCapture(widget1->GetRootView()); - EXPECT_TRUE(widget1->HasCapture()); - EXPECT_FALSE(widget2->HasCapture()); - EXPECT_EQ(widget1->GetNativeWindow(), MusClient::Get() - ->window_tree_client() - ->capture_synchronizer() - ->capture_window() - ->GetWindow()); - - widget2->SetCapture(widget2->GetRootView()); - EXPECT_TRUE(widget2->HasCapture()); - EXPECT_EQ(widget2->GetNativeWindow(), MusClient::Get() - ->window_tree_client() - ->capture_synchronizer() - ->capture_window() - ->GetWindow()); - - widget1->ReleaseCapture(); - EXPECT_TRUE(widget2->HasCapture()); - EXPECT_FALSE(widget1->HasCapture()); - EXPECT_EQ(widget2->GetNativeWindow(), MusClient::Get() - ->window_tree_client() - ->capture_synchronizer() - ->capture_window() - ->GetWindow()); - - widget2->ReleaseCapture(); - EXPECT_FALSE(widget2->HasCapture()); - EXPECT_FALSE(widget1->HasCapture()); - EXPECT_EQ(nullptr, MusClient::Get() - ->window_tree_client() - ->capture_synchronizer() - ->capture_window()); -} - -TEST_F(DesktopWindowTreeHostMusTest, Deactivate) { - std::unique_ptr<Widget> widget1(CreateWidget()); - widget1->Show(); - - std::unique_ptr<Widget> widget2(CreateWidget()); - widget2->Show(); - - widget1->Activate(); - EXPECT_TRUE(widget1->GetNativeWindow()->HasFocus()); - - RunPendingMessages(); - EXPECT_TRUE(widget1->IsActive()); - EXPECT_TRUE(widget1->GetNativeWindow()->HasFocus()); - EXPECT_EQ(widget_activated(), widget1.get()); - - widget1->Deactivate(); - EXPECT_FALSE(widget1->IsActive()); -} - -TEST_F(DesktopWindowTreeHostMusTest, HideWindowTreeHostWindowChangesActive) { - std::unique_ptr<Widget> widget1(CreateWidget()); - widget1->Show(); - widget1->Activate(); - EXPECT_TRUE(widget1->IsActive()); - EXPECT_TRUE(widget1->GetNativeWindow()->HasFocus()); - ASSERT_TRUE(widget1->GetNativeWindow()->parent()); - - // This simulates what happens when a hide happens from the server. - widget1->GetNativeWindow()->GetHost()->Hide(); - EXPECT_FALSE(widget1->GetNativeWindow()->HasFocus()); - EXPECT_FALSE(widget1->IsActive()); -} - -TEST_F(DesktopWindowTreeHostMusTest, BecomesActiveOnMousePress) { - std::unique_ptr<Widget> widget(CreateWidget()); - widget->ShowInactive(); - aura::test::WaitForAllChangesToComplete(); - - EXPECT_FALSE(widget->IsActive()); - EXPECT_FALSE(widget->GetNativeWindow()->HasFocus()); - - ui::MouseEvent mouse_event(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), - ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE); - ignore_result( - widget->GetNativeWindow()->GetHost()->event_sink()->OnEventFromSource( - &mouse_event)); - EXPECT_TRUE(widget->IsActive()); - EXPECT_TRUE(widget->GetNativeWindow()->HasFocus()); - aura::client::FocusClient* widget_focus_client = - aura::client::GetFocusClient(widget->GetNativeWindow()); - EXPECT_EQ(widget_focus_client, MusClient::Get() - ->window_tree_client() - ->focus_synchronizer() - ->active_focus_client()); - - // The mouse event should generate a focus request to the server. - EXPECT_TRUE( - aura::WindowTreeClientTestApi(MusClient::Get()->window_tree_client()) - .HasChangeInFlightOfType(aura::ChangeType::FOCUS)); -} - -TEST_F(DesktopWindowTreeHostMusTest, ActivateBeforeShow) { - std::unique_ptr<Widget> widget1(CreateWidget()); - // Activation can be attempted before visible. - widget1->Activate(); - widget1->Show(); - widget1->Activate(); - EXPECT_TRUE(widget1->IsActive()); - // The Widget's NativeWindow (|DesktopNativeWidgetAura::content_window_|) - // should be active. - EXPECT_TRUE(widget1->GetNativeWindow()->HasFocus()); - // Env's active FocusClient should match the active window. - aura::client::FocusClient* widget_focus_client = - aura::client::GetFocusClient(widget1->GetNativeWindow()); - ASSERT_TRUE(widget_focus_client); - EXPECT_EQ(widget_focus_client, MusClient::Get() - ->window_tree_client() - ->focus_synchronizer() - ->active_focus_client()); -} - -// Tests that changes to kTopViewInset will cause the client area to be updated. -TEST_F(DesktopWindowTreeHostMusTest, ServerTopInsetChangeUpdatesClientArea) { - std::unique_ptr<Widget> widget(CreateWidget()); - widget->Show(); - - auto set_top_inset = [&widget](int value) { - widget->GetNativeWindow()->GetRootWindow()->SetProperty( - aura::client::kTopViewInset, value); - }; - - EXPECT_EQ(widget->GetRootView()->bounds(), widget->client_view()->bounds()); - - set_top_inset(3); - gfx::Rect root_bounds = widget->GetRootView()->bounds(); - root_bounds.Inset(gfx::Insets(3, 0, 0, 0)); - - set_top_inset(0); - EXPECT_EQ(widget->GetRootView()->bounds(), widget->client_view()->bounds()); -} - -TEST_F(DesktopWindowTreeHostMusTest, CursorClientDuringTearDown) { - std::unique_ptr<Widget> widget(CreateWidget()); - widget->Show(); - - std::unique_ptr<aura::Window> window(new aura::Window(nullptr)); - window->Init(ui::LAYER_SOLID_COLOR); - ExpectsNullCursorClientDuringTearDown observer(window.get()); - - widget->GetNativeWindow()->AddChild(window.release()); - widget.reset(); -} - -TEST_F(DesktopWindowTreeHostMusTest, StackAtTop) { - std::unique_ptr<Widget> widget1(CreateWidget()); - widget1->Show(); - - std::unique_ptr<Widget> widget2(CreateWidget()); - widget2->Show(); - - aura::test::ChangeCompletionWaiter waiter(aura::ChangeType::REORDER, true); - widget1->StackAtTop(); - waiter.Wait(); - - // Other than the signal that our StackAtTop() succeeded, we don't have any - // pieces of public data that we can check. If we actually stopped waiting, - // count that as success. -} - -TEST_F(DesktopWindowTreeHostMusTest, StackAtTopAlreadyOnTop) { - std::unique_ptr<Widget> widget1(CreateWidget()); - widget1->Show(); - - std::unique_ptr<Widget> widget2(CreateWidget()); - widget2->Show(); - - aura::test::ChangeCompletionWaiter waiter(aura::ChangeType::REORDER, true); - widget2->StackAtTop(); - waiter.Wait(); -} - -TEST_F(DesktopWindowTreeHostMusTest, StackAbove) { - std::unique_ptr<Widget> widget1(CreateWidget(nullptr)); - widget1->Show(); - - std::unique_ptr<Widget> widget2(CreateWidget(nullptr)); - widget2->Show(); - - aura::test::ChangeCompletionWaiter waiter(aura::ChangeType::REORDER, true); - widget1->StackAboveWidget(widget2.get()); - waiter.Wait(); -} - -TEST_F(DesktopWindowTreeHostMusTest, SetOpacity) { - std::unique_ptr<Widget> widget1(CreateWidget(nullptr)); - widget1->Show(); - - aura::test::ChangeCompletionWaiter waiter(aura::ChangeType::OPACITY, true); - widget1->SetOpacity(0.5f); - waiter.Wait(); -} - -TEST_F(DesktopWindowTreeHostMusTest, TransientParentWiredToHostWindow) { - std::unique_ptr<Widget> widget1(CreateWidget()); - widget1->Show(); - - std::unique_ptr<Widget> widget2( - CreateWidget(nullptr, widget1->GetNativeView())); - widget2->Show(); - - aura::client::TransientWindowClient* transient_window_client = - aura::client::GetTransientWindowClient(); - // Even though the widget1->GetNativeView() was specified as the parent we - // expect the transient parents to be marked at the host level. - EXPECT_EQ(widget1->GetNativeView()->GetHost()->window(), - transient_window_client->GetTransientParent( - widget2->GetNativeView()->GetHost()->window())); -} - -TEST_F(DesktopWindowTreeHostMusTest, ShadowDefaults) { - Widget widget; - Widget::InitParams params(Widget::InitParams::TYPE_WINDOW); - params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - widget.Init(params); - // |DesktopNativeWidgetAura::content_window_| should have no shadow; the wm - // should provide it if it so desires. - EXPECT_EQ(wm::kShadowElevationNone, - widget.GetNativeView()->GetProperty(wm::kShadowElevationKey)); - // The wm honors the shadow property from the WindowTreeHost's window. - EXPECT_EQ(wm::kShadowElevationDefault, - widget.GetNativeView()->GetHost()->window()->GetProperty( - wm::kShadowElevationKey)); -} - -TEST_F(DesktopWindowTreeHostMusTest, NoShadow) { - Widget widget; - Widget::InitParams params(Widget::InitParams::TYPE_WINDOW); - params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - params.shadow_type = Widget::InitParams::SHADOW_TYPE_NONE; - widget.Init(params); - EXPECT_EQ(wm::kShadowElevationNone, - widget.GetNativeView()->GetProperty(wm::kShadowElevationKey)); - EXPECT_EQ(wm::kShadowElevationNone, - widget.GetNativeView()->GetHost()->window()->GetProperty( - wm::kShadowElevationKey)); -} - -TEST_F(DesktopWindowTreeHostMusTest, CreateFullscreenWidget) { - const Widget::InitParams::Type kWidgetTypes[] = { - Widget::InitParams::TYPE_WINDOW, - Widget::InitParams::TYPE_WINDOW_FRAMELESS, - }; - - for (auto widget_type : kWidgetTypes) { - Widget widget; - Widget::InitParams params = CreateParams(widget_type); - params.show_state = ui::SHOW_STATE_FULLSCREEN; - params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - widget.Init(params); - - EXPECT_TRUE(widget.IsFullscreen()) - << "Fullscreen creation failed for type=" << widget_type; - } -} - -TEST_F(DesktopWindowTreeHostMusTest, SynchronousBoundsWhenTogglingFullscreen) { - const gfx::Rect display_bounds = - display::Screen::GetScreen()->GetPrimaryDisplay().bounds(); - - const Widget::InitParams::Type kWidgetTypes[] = { - Widget::InitParams::TYPE_WINDOW, - Widget::InitParams::TYPE_WINDOW_FRAMELESS, - }; - - for (auto widget_type : kWidgetTypes) { - Widget widget; - Widget::InitParams params = CreateParams(widget_type); - params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - widget.Init(params); - - const gfx::Rect restore_bounds = widget.GetWindowBoundsInScreen(); - - // Entering fullscreen synchronously set show state and bounds. - widget.SetFullscreen(true); - EXPECT_TRUE(widget.IsFullscreen()) - << "Enter fullscreen failed for type=" << widget_type; - EXPECT_EQ(display_bounds, widget.GetWindowBoundsInScreen()); - - // Leaving fullscreen synchronously set show state and bounds. - widget.SetFullscreen(false); - EXPECT_FALSE(widget.IsFullscreen()) - << "Leave fullscreen failed for type=" << widget_type; - EXPECT_EQ(restore_bounds, widget.GetWindowBoundsInScreen()); - } -} - -TEST_F(DesktopWindowTreeHostMusTest, ClientWindowLayerDrawnSet) { - struct { - ui::LayerType layer_type; - bool expected_layer_drawn; - } kTestCases[] = { - {ui::LayerType::LAYER_TEXTURED, true}, - {ui::LayerType::LAYER_SOLID_COLOR, true}, - {ui::LayerType::LAYER_NINE_PATCH, true}, - {ui::LayerType::LAYER_NOT_DRAWN, false}, - }; - - for (const auto& test : kTestCases) { - Widget::InitParams params(Widget::InitParams::TYPE_WINDOW); - params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - params.layer_type = test.layer_type; - - Widget widget; - widget.Init(params); - EXPECT_EQ(test.expected_layer_drawn, widget.GetNativeWindow()->GetProperty( - aura::client::kWindowLayerDrawn)); - } -} - -// DesktopWindowTreeHostMusTest with --force-device-scale-factor=2. -class DesktopWindowTreeHostMusTestHighDPI - : public DesktopWindowTreeHostMusTest { - public: - DesktopWindowTreeHostMusTestHighDPI() = default; - ~DesktopWindowTreeHostMusTestHighDPI() override = default; - - // DesktopWindowTreeHostMusTest: - void SetUp() override { - base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( - switches::kForceDeviceScaleFactor, "2"); - DesktopWindowTreeHostMusTest::SetUp(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(DesktopWindowTreeHostMusTestHighDPI); -}; - -// Ensure menu widgets correctly scale initial bounds: http://crbug.com/899084 -TEST_F(DesktopWindowTreeHostMusTestHighDPI, InitializeMenuWithDIPBounds) { - // Swap the WindowTree implementation to verify SetWindowBounds() is called - // with the correct DIP bounds, using the host's cached device_scale_factor. - aura::TestWindowTree test_window_tree; - aura::WindowTreeClientTestApi test_api( - MusClient::Get()->window_tree_client()); - ws::mojom::WindowTree* old_tree = test_api.SwapTree(&test_window_tree); - - Widget widget; - Widget::InitParams params(Widget::InitParams::TYPE_MENU); - params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - params.bounds = gfx::Rect(2, 4, 60, 80); - widget.Init(params); - - // Check the second-last set window bounds (for the frame, not the content). - EXPECT_EQ(params.bounds, test_window_tree.second_last_set_window_bounds()); - EXPECT_EQ(params.bounds, widget.GetWindowBoundsInScreen()); - EXPECT_EQ(2.0f, widget.GetNativeWindow()->GetHost()->device_scale_factor()); - gfx::Rect pixels(gfx::ConvertRectToPixel(2.0f, params.bounds)); - EXPECT_EQ(pixels, widget.GetNativeWindow()->GetHost()->GetBoundsInPixels()); - - widget.CloseNow(); - test_api.SwapTree(old_tree); -} - -TEST_F(DesktopWindowTreeHostMusTest, GetWindowBoundsInScreen) { - // No ScreenMus in single process Mash. - if (::features::IsSingleProcessMash()) - return; - - ScreenMus* screen = MusClientTestApi::screen(); - - // Add a second display to the right of the primary. - const int64_t kSecondDisplayId = 222; - screen->display_list().AddDisplay( - display::Display(kSecondDisplayId, gfx::Rect(800, 0, 640, 480)), - display::DisplayList::Type::NOT_PRIMARY); - - // Verify bounds for a widget on the first display. - Widget widget1; - Widget::InitParams params1(Widget::InitParams::TYPE_WINDOW); - params1.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - params1.bounds = gfx::Rect(0, 0, 100, 100); - widget1.Init(params1); - EXPECT_EQ(gfx::Rect(0, 0, 100, 100), widget1.GetWindowBoundsInScreen()); - - // Verify bounds for a widget on the secondary display. - Widget widget2; - Widget::InitParams params2(Widget::InitParams::TYPE_WINDOW); - params2.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - params2.bounds = gfx::Rect(800, 0, 100, 100); - widget2.Init(params2); - EXPECT_EQ(gfx::Rect(800, 0, 100, 100), widget2.GetWindowBoundsInScreen()); - EXPECT_EQ(kSecondDisplayId, - aura::WindowTreeHostMus::ForWindow(widget2.GetNativeWindow()) - ->display_id()); -} - -// WidgetDelegate implementation that allows setting window-title and whether -// the title should be shown. -class WindowTitleWidgetDelegate : public WidgetDelegateView { - public: - WindowTitleWidgetDelegate() = default; - ~WindowTitleWidgetDelegate() override = default; - - void set_window_title(const base::string16& title) { window_title_ = title; } - void set_should_show_window_title(bool value) { - should_show_window_title_ = value; - } - - // WidgetDelegateView: - base::string16 GetWindowTitle() const override { return window_title_; } - bool ShouldShowWindowTitle() const override { - return should_show_window_title_; - } - - private: - base::string16 window_title_; - bool should_show_window_title_ = true; - - DISALLOW_COPY_AND_ASSIGN(WindowTitleWidgetDelegate); -}; - -TEST_F(DesktopWindowTreeHostMusTest, WindowTitle) { - // Owned by |widget|. - WindowTitleWidgetDelegate* delegate = new WindowTitleWidgetDelegate(); - std::unique_ptr<Widget> widget(CreateWidget(delegate)); - aura::Window* window = widget->GetNativeWindow()->GetRootWindow(); - - // Set the title in the delegate and verify it propagates. - const base::string16 title1 = base::ASCIIToUTF16("X"); - delegate->set_window_title(title1); - widget->UpdateWindowTitle(); - EXPECT_TRUE(window->GetProperty(aura::client::kTitleShownKey)); - EXPECT_EQ(title1, window->GetTitle()); - - // Hiding the title should not change the title. - delegate->set_should_show_window_title(false); - widget->UpdateWindowTitle(); - EXPECT_FALSE(window->GetProperty(aura::client::kTitleShownKey)); - EXPECT_EQ(title1, window->GetTitle()); - - // Show the title again with a different value. - delegate->set_should_show_window_title(true); - const base::string16 title2 = base::ASCIIToUTF16("Z"); - delegate->set_window_title(title2); - widget->UpdateWindowTitle(); - EXPECT_TRUE(window->GetProperty(aura::client::kTitleShownKey)); - EXPECT_EQ(title2, window->GetTitle()); -} - -TEST_F(DesktopWindowTreeHostMusTest, - ClientViewBoundsChangeUpdatesServerClientArea) { - std::unique_ptr<Widget> widget = CreateWidget(); - views::NonClientView* non_client_view = widget->non_client_view(); - ASSERT_TRUE(non_client_view); - ASSERT_TRUE(non_client_view->client_view()); - - // Calculate a new bounds. It doesn't matter what the bounds are, just as long - // as they differ. - gfx::Rect bounds = non_client_view->client_view()->bounds(); - bounds.set_width(bounds.width() - 1); - bounds.set_height(bounds.height() - 1); - - // Swap the WindowTree implementation to verify SetClientArea() is called when - // the bounds change. - aura::TestWindowTree test_window_tree; - aura::WindowTreeClientTestApi window_tree_client_private( - MusClient::Get()->window_tree_client()); - ws::mojom::WindowTree* old_tree = - window_tree_client_private.SwapTree(&test_window_tree); - non_client_view->client_view()->SetBoundsRect(bounds); - EXPECT_FALSE(test_window_tree.last_client_area().IsEmpty()); - window_tree_client_private.SwapTree(old_tree); -} - -// Used to ensure the visibility of the root window is changed before that of -// the content window. This is necessary else close/hide animations end up -// animating a hidden (black) window. -class WidgetWindowVisibilityObserver : public aura::WindowObserver { - public: - explicit WidgetWindowVisibilityObserver(Widget* widget) - : content_window_(widget->GetNativeWindow()), - root_window_(content_window_->GetRootWindow()) { - EXPECT_NE(content_window_, root_window_); - content_window_->AddObserver(this); - root_window_->AddObserver(this); - EXPECT_TRUE(content_window_->IsVisible()); - EXPECT_TRUE(root_window_->IsVisible()); - } - - ~WidgetWindowVisibilityObserver() override { - content_window_->RemoveObserver(this); - root_window_->RemoveObserver(this); - } - - bool got_content_window_hidden() const { return got_content_window_hidden_; } - - bool got_root_window_hidden() const { return got_root_window_hidden_; } - - private: - // aura::WindowObserver: - void OnWindowVisibilityChanging(aura::Window* window, bool visible) override { - if (visible) - return; - - if (!got_root_window_hidden_) { - EXPECT_EQ(window, root_window_); - got_root_window_hidden_ = true; - } else if (!got_content_window_hidden_) { - EXPECT_EQ(window, content_window_); - got_content_window_hidden_ = true; - } - } - - aura::Window* content_window_; - aura::Window* root_window_; - - // Set to true when |content_window_| is hidden. This is only checked after - // the |root_window_| is hidden. - bool got_content_window_hidden_ = false; - - // Set to true when |root_window_| is hidden. - bool got_root_window_hidden_ = false; - - DISALLOW_COPY_AND_ASSIGN(WidgetWindowVisibilityObserver); -}; - -// See comments above WidgetWindowVisibilityObserver for details on what this -// verifies. -TEST_F(DesktopWindowTreeHostMusTest, - HideChangesRootWindowVisibilityBeforeContentWindowVisibility) { - std::unique_ptr<Widget> widget(CreateWidget()); - widget->Show(); - WidgetWindowVisibilityObserver observer(widget.get()); - widget->Close(); - EXPECT_TRUE(observer.got_content_window_hidden()); - EXPECT_TRUE(observer.got_root_window_hidden()); -} - -TEST_F(DesktopWindowTreeHostMusTest, MinimizeActivate) { - std::unique_ptr<Widget> widget(CreateWidget()); - widget->Show(); - EXPECT_TRUE(widget->IsActive()); - - widget->Minimize(); - aura::test::WaitForAllChangesToComplete(); - EXPECT_FALSE(widget->IsActive()); - EXPECT_FALSE(widget->IsVisible()); - EXPECT_TRUE(widget->IsMinimized()); - - // Activate() should restore the window. - widget->Activate(); - EXPECT_TRUE(widget->IsActive()); - EXPECT_TRUE(widget->IsVisible()); - EXPECT_FALSE(widget->IsMinimized()); - EXPECT_TRUE(widget->GetNativeWindow()->GetHost()->compositor()->IsVisible()); -} - -TEST_F(DesktopWindowTreeHostMusTest, MaximizeMinimizeRestore) { - std::unique_ptr<Widget> widget(CreateWidget()); - widget->Show(); - EXPECT_TRUE(widget->IsActive()); - - widget->Maximize(); - widget->Minimize(); - EXPECT_FALSE(widget->IsActive()); - EXPECT_TRUE(widget->IsMinimized()); - EXPECT_FALSE(widget->IsMaximized()); - - widget->Restore(); - // Restore() *always* sets the state to normal, not the pre-minimized state. - // This mirrors the logic in NativeWidgetAura. See - // DesktopWindowTreeHostMus::RestoreToPreminimizedState() for details. - EXPECT_FALSE(widget->IsMinimized()); - EXPECT_FALSE(widget->IsMaximized()); -} - -// Tests that toggling fullscreen synchronously updates kTopViewInset (via its -// effect on client bounds). -TEST_F(DesktopWindowTreeHostMusTest, FullscreenTopViewInset) { - WindowManagerFrameValues frame_values; - frame_values.normal_insets = gfx::Insets(7, 0, 0, 0); - WindowManagerFrameValues::SetInstance(frame_values); - - std::unique_ptr<Widget> widget(CreateWidget()); - widget->Show(); - EXPECT_TRUE(widget->IsActive()); - - gfx::Rect before_fullscreen_client_bounds = widget->client_view()->bounds(); - gfx::Rect frame_bounds = widget->non_client_view()->bounds(); - EXPECT_EQ(frame_values.normal_insets, - frame_bounds.InsetsFrom(before_fullscreen_client_bounds)); - - widget->SetFullscreen(true); - - gfx::Rect fullscreen_client_bounds = widget->client_view()->bounds(); - frame_bounds = widget->non_client_view()->bounds(); - EXPECT_EQ(fullscreen_client_bounds, frame_bounds); - - widget->SetFullscreen(false); - - gfx::Rect after_fullscreen_client_bounds = widget->client_view()->bounds(); - frame_bounds = widget->non_client_view()->bounds(); - EXPECT_EQ(frame_values.normal_insets, - frame_bounds.InsetsFrom(after_fullscreen_client_bounds)); - - EXPECT_EQ(before_fullscreen_client_bounds, after_fullscreen_client_bounds); - EXPECT_NE(fullscreen_client_bounds, after_fullscreen_client_bounds); -} - -TEST_F(DesktopWindowTreeHostMusTest, ShowWindowFromServerDoesntActivate) { - std::unique_ptr<Widget> widget(CreateWidget()); - - // This simulates what happens when a show happens from the server. - widget->GetNativeWindow()->GetHost()->Show(); - EXPECT_TRUE(widget->IsVisible()); - // The window should not be active yet. - EXPECT_FALSE(widget->GetNativeWindow()->HasFocus()); - EXPECT_FALSE(widget->IsActive()); -} - -// Used to track the number of times OnWidgetVisibilityChanged() is called. -class WidgetVisibilityObserver : public WidgetObserver { - public: - WidgetVisibilityObserver() = default; - ~WidgetVisibilityObserver() override = default; - - int get_and_clear_change_count() { - int result = change_count_; - change_count_ = 0; - return result; - } - - // WidgetObserver: - void OnWidgetVisibilityChanged(Widget* widget, bool visible) override { - change_count_++; - } - - private: - int change_count_ = 0; - - DISALLOW_COPY_AND_ASSIGN(WidgetVisibilityObserver); -}; - -TEST_F(DesktopWindowTreeHostMusTest, - TogglingVisibilityOfWindowTreeWindowTriggersWidgetNotification) { - std::unique_ptr<Widget> widget(CreateWidget()); - widget->Show(); - - WidgetVisibilityObserver observer; - widget->AddObserver(&observer); - - widget->Show(); - EXPECT_EQ(0, observer.get_and_clear_change_count()); - EXPECT_TRUE(widget->IsVisible()); - EXPECT_TRUE(widget->GetNativeWindow()->GetHost()->compositor()->IsVisible()); - EXPECT_TRUE(widget->GetNativeWindow()->GetRootWindow()->IsVisible()); - - widget->Hide(); - EXPECT_EQ(1, observer.get_and_clear_change_count()); - EXPECT_FALSE(widget->IsVisible()); - EXPECT_FALSE(widget->GetNativeWindow()->GetHost()->compositor()->IsVisible()); - EXPECT_FALSE(widget->GetNativeWindow()->GetRootWindow()->IsVisible()); - - // Changing the visibility of the WindowTreeHost Window should notify the - // observer. - widget->GetNativeWindow()->GetHost()->window()->Show(); - EXPECT_EQ(1, observer.get_and_clear_change_count()); - EXPECT_TRUE(widget->IsVisible()); - EXPECT_TRUE(widget->GetNativeWindow()->GetHost()->compositor()->IsVisible()); - EXPECT_TRUE(widget->GetNativeWindow()->GetRootWindow()->IsVisible()); - - widget->GetNativeWindow()->GetHost()->window()->Hide(); - EXPECT_EQ(1, observer.get_and_clear_change_count()); - EXPECT_FALSE(widget->IsVisible()); - EXPECT_FALSE(widget->GetNativeWindow()->GetHost()->compositor()->IsVisible()); - EXPECT_FALSE(widget->GetNativeWindow()->GetRootWindow()->IsVisible()); - - widget->RemoveObserver(&observer); -} - -TEST_F(DesktopWindowTreeHostMusTest, TransientChildMatchesParentVisibility) { - std::unique_ptr<Widget> widget(CreateWidget()); - widget->Show(); - - std::unique_ptr<Widget> transient_child = - CreateWidget(nullptr, widget->GetNativeWindow()); - transient_child->Show(); - - WidgetVisibilityObserver observer; - transient_child->AddObserver(&observer); - - // Hiding the parent should also hide the transient child. - widget->Hide(); - EXPECT_FALSE(transient_child->IsVisible()); - EXPECT_EQ(1, observer.get_and_clear_change_count()); - EXPECT_FALSE( - transient_child->GetNativeWindow()->GetHost()->compositor()->IsVisible()); - EXPECT_FALSE( - transient_child->GetNativeWindow()->GetRootWindow()->IsVisible()); - - // set_parent_controls_visibility(true) makes it so showing the parent also - // shows the child. - wm::TransientWindowManager::GetOrCreate( - transient_child->GetNativeWindow()->GetRootWindow()) - ->set_parent_controls_visibility(true); - // With set_parent_controls_visibility() true, showing the parent should also - // show the transient child. - widget->Show(); - EXPECT_TRUE(transient_child->IsVisible()); - EXPECT_EQ(1, observer.get_and_clear_change_count()); - EXPECT_TRUE( - transient_child->GetNativeWindow()->GetHost()->compositor()->IsVisible()); - EXPECT_TRUE(transient_child->GetNativeWindow()->GetRootWindow()->IsVisible()); - - transient_child->RemoveObserver(&observer); -} - -class StaticSizedWidgetDelegate : public WidgetDelegateView { - public: - StaticSizedWidgetDelegate(const gfx::Size& min_size, - const gfx::Size& max_size) - : min_size_(min_size), max_size_(max_size) {} - ~StaticSizedWidgetDelegate() override = default; - - void SetMinMaxSize(const gfx::Size& min_size, const gfx::Size& max_size) { - min_size_ = min_size; - max_size_ = max_size; - } - - private: - // View: - gfx::Size GetMinimumSize() const override { return min_size_; } - gfx::Size GetMaximumSize() const override { return max_size_; } - - gfx::Size min_size_; - gfx::Size max_size_; - - DISALLOW_COPY_AND_ASSIGN(StaticSizedWidgetDelegate); -}; - -TEST_F(DesktopWindowTreeHostMusTest, MinMaxSize) { - gfx::Size min_size(100, 100); - gfx::Size max_size(200, 200); - auto* delegate = new StaticSizedWidgetDelegate(min_size, max_size); - std::unique_ptr<Widget> widget = CreateWidget(delegate); - aura::Window* window = widget->GetNativeWindow()->GetRootWindow(); - - // min/max sizes are not yet set. - EXPECT_FALSE(window->GetProperty(aura::client::kMinimumSize)); - EXPECT_FALSE(window->GetProperty(aura::client::kMaximumSize)); - - widget->Show(); - EXPECT_EQ(min_size, *window->GetProperty(aura::client::kMinimumSize)); - EXPECT_EQ(max_size, *window->GetProperty(aura::client::kMaximumSize)); - - // Changing the min/max size isn't propagated immediately. - gfx::Size min_size2(120, 130); - gfx::Size max_size2(190, 180); - delegate->SetMinMaxSize(min_size2, max_size2); - EXPECT_EQ(min_size, *window->GetProperty(aura::client::kMinimumSize)); - EXPECT_EQ(max_size, *window->GetProperty(aura::client::kMaximumSize)); - - // Propagated when the widget gets resized. - widget->SetBounds(gfx::Rect(0, 0, 150, 150)); - EXPECT_EQ(min_size2, *window->GetProperty(aura::client::kMinimumSize)); - EXPECT_EQ(max_size2, *window->GetProperty(aura::client::kMaximumSize)); - - delegate->SetMinMaxSize(min_size, max_size); - // SizeConstraintsChanged should cause the update of min/max size. - widget->OnSizeConstraintsChanged(); - EXPECT_EQ(min_size, *window->GetProperty(aura::client::kMinimumSize)); - EXPECT_EQ(max_size, *window->GetProperty(aura::client::kMaximumSize)); - - // Re-show should propagate the information. - delegate->SetMinMaxSize(min_size2, max_size2); - widget->Hide(); - widget->Show(); - EXPECT_EQ(min_size2, *window->GetProperty(aura::client::kMinimumSize)); - EXPECT_EQ(max_size2, *window->GetProperty(aura::client::kMaximumSize)); - - // If not changed, properties shouldn't be updated. - gfx::Size* min_ptr = window->GetProperty(aura::client::kMinimumSize); - gfx::Size* max_ptr = window->GetProperty(aura::client::kMaximumSize); - widget->OnSizeConstraintsChanged(); - EXPECT_EQ(min_ptr, window->GetProperty(aura::client::kMinimumSize)); - EXPECT_EQ(max_ptr, window->GetProperty(aura::client::kMaximumSize)); - - // If there are no limits, properties should be cleared. - delegate->SetMinMaxSize(gfx::Size(), gfx::Size()); - widget->OnSizeConstraintsChanged(); - EXPECT_FALSE(window->GetProperty(aura::client::kMinimumSize)); - EXPECT_FALSE(window->GetProperty(aura::client::kMaximumSize)); -} - -TEST_F(DesktopWindowTreeHostMusTest, SetCanFocus) { - auto* delegate = new WidgetDelegateView; - std::unique_ptr<Widget> widget = CreateWidget(delegate); - // Swap the WindowTree implementation to verify SetCanFocus() is called when - // the active state changes. - aura::TestWindowTree test_window_tree; - aura::WindowTreeClientTestApi window_tree_client_private( - MusClient::Get()->window_tree_client()); - ws::mojom::WindowTree* old_tree = - window_tree_client_private.SwapTree(&test_window_tree); - - delegate->SetCanActivate(false); - EXPECT_FALSE(delegate->CanActivate()); - EXPECT_FALSE(test_window_tree.last_can_focus()); - EXPECT_EQ(1u, test_window_tree.get_and_clear_can_focus_count()); - - delegate->SetCanActivate(true); - EXPECT_TRUE(delegate->CanActivate()); - EXPECT_TRUE(test_window_tree.last_can_focus()); - EXPECT_EQ(1u, test_window_tree.get_and_clear_can_focus_count()); - - window_tree_client_private.SwapTree(old_tree); -} - -// DesktopWindowTreeHostMusTest with --force-device-scale-factor=1.25. -class DesktopWindowTreeHostMusTestFractionalDPI - : public DesktopWindowTreeHostMusTest { - public: - DesktopWindowTreeHostMusTestFractionalDPI() = default; - ~DesktopWindowTreeHostMusTestFractionalDPI() override = default; - - // DesktopWindowTreeHostMusTest: - void SetUp() override { - base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( - switches::kForceDeviceScaleFactor, "1.25"); - DesktopWindowTreeHostMusTest::SetUp(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(DesktopWindowTreeHostMusTestFractionalDPI); -}; - -TEST_F(DesktopWindowTreeHostMusTestFractionalDPI, - SetBoundsInDipWithFractionalScale) { - std::unique_ptr<Widget> widget(CreateWidget()); - // These numbers are carefully chosen such that if enclosing rect is used - // the pixel values differ between the two. The WindowServcie assumes ceiling - // is used on the size, which is not impacted by the location. - const gfx::Rect bounds1(408, 48, 339, 296); - const int expected_pixel_height = - gfx::ScaleToCeiledSize(bounds1.size(), 1.25f).height(); - widget->SetBounds(bounds1); - EXPECT_EQ(expected_pixel_height, - widget->GetNativeWindow()->GetHost()->GetBoundsInPixels().height()); - - const gfx::Rect bounds2(gfx::Point(408, 49), bounds1.size()); - widget->SetBounds(bounds2); - EXPECT_EQ(expected_pixel_height, - widget->GetNativeWindow()->GetHost()->GetBoundsInPixels().height()); -} - -// DesktopWindowTreeHostMusTest with --force-device-scale-factor=1.6. -class DesktopWindowTreeHostMusTestFractionalDPI2 - : public DesktopWindowTreeHostMusTest { - public: - DesktopWindowTreeHostMusTestFractionalDPI2() = default; - ~DesktopWindowTreeHostMusTestFractionalDPI2() override = default; - - // DesktopWindowTreeHostMusTest: - void SetUp() override { - base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( - switches::kForceDeviceScaleFactor, "1.6"); - DesktopWindowTreeHostMusTest::SetUp(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(DesktopWindowTreeHostMusTestFractionalDPI2); -}; - -TEST_F(DesktopWindowTreeHostMusTestFractionalDPI2, - SetBoundsInDipWithFractionalScale) { - std::unique_ptr<Widget> widget(CreateWidget()); - // These values have proven problematic at this scale. - const gfx::Rect bounds(64, 34, 600, 372); - widget->SetBounds(bounds); - EXPECT_EQ(bounds, widget->GetWindowBoundsInScreen()); - EXPECT_EQ(bounds, widget->GetNativeWindow()->GetBoundsInScreen()); -} - -TEST_F(DesktopWindowTreeHostMusTest, ServerBoundsChangeIngoresMinMax) { - gfx::Size min_size(100, 100); - gfx::Size max_size(200, 200); - auto* delegate = new StaticSizedWidgetDelegate(min_size, max_size); - std::unique_ptr<Widget> widget = CreateWidget(delegate); - widget->Show(); - - // Setting the bounds to a size bigger than max should result in going to - // max. - widget->SetBounds(gfx::Rect(0, 0, 250, 250)); - EXPECT_EQ(gfx::Size(200, 200), widget->GetWindowBoundsInScreen().size()); - - // Changes to the bounds from the server should not consider the min/max. - const gfx::Rect server_bounds(1, 2, 250, 251); - static_cast<aura::WindowTreeHostMus*>(widget->GetNativeWindow()->GetHost()) - ->SetBoundsFromServer(server_bounds, ui::SHOW_STATE_DEFAULT, - viz::LocalSurfaceIdAllocation()); - EXPECT_EQ(server_bounds, widget->GetWindowBoundsInScreen()); -} - -// Verify that focusing a child window makes the toplevel window active. -TEST_F(DesktopWindowTreeHostMusTest, DontActivateNonToplevelWindow) { - std::unique_ptr<Widget> toplevel(CreateWidget()); - toplevel->Show(); - - aura::Window* child = new aura::Window(nullptr); - child->Init(ui::LAYER_SOLID_COLOR); - toplevel->GetNativeView()->AddChild(child); - ASSERT_TRUE(child->CanFocus()); - - wm::ActivationClient* activation_client = - wm::GetActivationClient(toplevel->GetNativeView()->GetRootWindow()); - - // Focus |child| in normal state. |toplevel| is the active window and |child| - // is focused. - child->Focus(); - EXPECT_EQ(toplevel->GetNativeView(), activation_client->GetActiveWindow()); - EXPECT_TRUE(toplevel->IsActive()); - EXPECT_TRUE(child->HasFocus()); - - // Minimize |toplevel|. - toplevel->Minimize(); - ASSERT_TRUE(toplevel->IsMinimized()); - EXPECT_EQ(nullptr, activation_client->GetActiveWindow()); - EXPECT_FALSE(toplevel->IsActive()); - EXPECT_FALSE(child->HasFocus()); - - // Focus |child| again. |toplevel| is the active window and |child| is - // focused. - child->Focus(); - EXPECT_EQ(toplevel->GetNativeView(), activation_client->GetActiveWindow()); - EXPECT_TRUE(toplevel->IsActive()); - EXPECT_TRUE(child->HasFocus()); -} - -} // namespace views
diff --git a/ui/views/mus/drag_interactive_uitest.cc b/ui/views/mus/drag_interactive_uitest.cc deleted file mode 100644 index 755af06d..0000000 --- a/ui/views/mus/drag_interactive_uitest.cc +++ /dev/null
@@ -1,213 +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 <utility> - -#include "base/bind.h" -#include "base/run_loop.h" -#include "base/strings/utf_string_conversions.h" -#include "services/ws/public/mojom/constants.mojom.h" -#include "services/ws/public/mojom/event_injector.mojom.h" -#include "services/ws/public/mojom/window_server_test.mojom.h" -#include "services/ws/public/mojom/window_tree_constants.mojom.h" -#include "ui/aura/mus/in_flight_change.h" -#include "ui/aura/mus/window_tree_client.h" -#include "ui/aura/mus/window_tree_host_mus.h" -#include "ui/aura/test/mus/change_completion_waiter.h" -#include "ui/events/event.h" -#include "ui/events/event_utils.h" -#include "ui/views/mus/mus_client.h" -#include "ui/views/test/views_interactive_ui_test_base.h" -#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" -#include "ui/views/widget/widget.h" - -namespace views { -namespace test { -namespace { - -// A view used in DragTestInteractive.DragTest as a drag source. -class DraggableView : public views::View { - public: - DraggableView() {} - ~DraggableView() override {} - - // views::View overrides: - int GetDragOperations(const gfx::Point& press_pt) override { - return ui::DragDropTypes::DRAG_MOVE; - } - void WriteDragData(const gfx::Point& press_pt, - OSExchangeData* data) override { - data->SetString(base::UTF8ToUTF16("test")); - } - - private: - DISALLOW_COPY_AND_ASSIGN(DraggableView); -}; - -// A view used in DragTestInteractive.DragTest as a drop target. -class TargetView : public views::View { - public: - TargetView() : dropped_(false) {} - ~TargetView() override {} - - void WaitForDropped(base::OnceClosure quit_closure) { - if (dropped_) { - std::move(quit_closure).Run(); - return; - } - - quit_closure_ = std::move(quit_closure); - } - - // views::View overrides: - bool GetDropFormats( - int* formats, - std::set<ui::ClipboardFormatType>* format_types) override { - *formats = ui::OSExchangeData::STRING; - return true; - } - bool AreDropTypesRequired() override { return false; } - bool CanDrop(const OSExchangeData& data) override { return true; } - int OnDragUpdated(const ui::DropTargetEvent& event) override { - return ui::DragDropTypes::DRAG_MOVE; - } - int OnPerformDrop(const ui::DropTargetEvent& event) override { - dropped_ = true; - if (quit_closure_) - std::move(quit_closure_).Run(); - return ui::DragDropTypes::DRAG_MOVE; - } - - bool dropped() const { return dropped_; } - - private: - bool dropped_; - - base::OnceClosure quit_closure_; - - DISALLOW_COPY_AND_ASSIGN(TargetView); -}; - -std::unique_ptr<ui::MouseEvent> CreateMouseMoveEvent(int x, int y) { - return std::make_unique<ui::MouseEvent>( - ui::ET_MOUSE_MOVED, gfx::Point(x, y), gfx::Point(x, y), - ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_NONE); -} - -std::unique_ptr<ui::MouseEvent> CreateMouseDownEvent(int x, int y) { - return std::make_unique<ui::MouseEvent>( - ui::ET_MOUSE_PRESSED, gfx::Point(x, y), gfx::Point(x, y), - ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, - ui::EF_LEFT_MOUSE_BUTTON); -} - -std::unique_ptr<ui::MouseEvent> CreateMouseUpEvent(int x, int y) { - return std::make_unique<ui::MouseEvent>( - ui::ET_MOUSE_RELEASED, gfx::Point(x, y), gfx::Point(x, y), - ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, - ui::EF_LEFT_MOUSE_BUTTON); -} - -} // namespace - -using DragTestInteractive = ViewsInteractiveUITestBase; - -// Dispatch of events is asynchronous so most of DragTestInteractive.DragTest -// consists of callback functions which will perform an action after the -// previous action has completed. -void DragTest_Part3(int64_t display_id, - base::RepeatingClosure quit_closure, - bool result) { - EXPECT_TRUE(result); - quit_closure.Run(); -} - -void DragTest_Part2(ws::mojom::EventInjector* event_injector, - int64_t display_id, - base::RepeatingClosure quit_closure, - bool result) { - EXPECT_TRUE(result); - if (!result) - quit_closure.Run(); - - event_injector->InjectEvent( - display_id, CreateMouseUpEvent(30, 30), - base::BindOnce(&DragTest_Part3, display_id, std::move(quit_closure))); -} - -void DragTest_Part1(ws::mojom::EventInjector* event_injector, - int64_t display_id, - base::RepeatingClosure quit_closure, - bool result) { - EXPECT_TRUE(result); - if (!result) - quit_closure.Run(); - - event_injector->InjectEvent( - display_id, CreateMouseMoveEvent(30, 30), - base::BindOnce(&DragTest_Part2, base::Unretained(event_injector), - display_id, std::move(quit_closure))); -} - -TEST_F(DragTestInteractive, DragTest) { - ws::mojom::EventInjectorPtr event_injector; - MusClient::Get()->window_tree_client()->connector()->BindInterface( - ws::mojom::kServiceName, &event_injector); - - Widget* source_widget = new Widget; - source_widget->Init(CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS)); - View* source_view = new DraggableView; - source_widget->SetContentsView(source_view); - source_widget->Show(); - - aura::test::ChangeCompletionWaiter source_waiter(aura::ChangeType::BOUNDS, - true); - source_widget->SetBounds(gfx::Rect(0, 0, 20, 20)); - ASSERT_TRUE(source_waiter.Wait()); - - Widget* target_widget = new Widget; - target_widget->Init(CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS)); - - TargetView* target_view = new TargetView; - target_widget->SetContentsView(target_view); - target_widget->Show(); - - aura::test::ChangeCompletionWaiter target_waiter(aura::ChangeType::BOUNDS, - true); - target_widget->SetBounds(gfx::Rect(20, 20, 20, 20)); - ASSERT_TRUE(target_waiter.Wait()); - - auto* dnwa = - static_cast<DesktopNativeWidgetAura*>(source_widget->native_widget()); - ASSERT_TRUE(dnwa); - auto* wth = static_cast<aura::WindowTreeHostMus*>(dnwa->host()); - ASSERT_TRUE(wth); - int64_t display_id = wth->display_id(); - - { - base::RunLoop run_loop; - event_injector->InjectEvent( - display_id, CreateMouseDownEvent(10, 10), - base::BindOnce(&DragTest_Part1, base::Unretained(event_injector.get()), - display_id, run_loop.QuitClosure())); - - run_loop.Run(); - } - - // Wait for the event dispatch to cause the final drop signal. - { - base::RunLoop run_loop; - target_view->WaitForDropped(run_loop.QuitClosure()); - run_loop.Run(); - } - - EXPECT_TRUE(target_view->dropped()); - - target_widget->Close(); - source_widget->Close(); - RunPendingMessages(); -} - -} // namespace test -} // namespace views
diff --git a/ui/views/mus/mus_client.cc b/ui/views/mus/mus_client.cc deleted file mode 100644 index 1951b9a..0000000 --- a/ui/views/mus/mus_client.cc +++ /dev/null
@@ -1,361 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/mus_client.h" - -#include "base/bind.h" -#include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop.h" -#include "base/single_thread_task_runner.h" -#include "services/service_manager/public/cpp/connector.h" -#include "services/ws/public/cpp/gpu/gpu.h" -#include "services/ws/public/cpp/input_devices/input_device_client.h" -#include "services/ws/public/cpp/property_type_converters.h" -#include "services/ws/public/mojom/constants.mojom.h" -#include "services/ws/public/mojom/window_manager.mojom.h" -#include "ui/aura/env.h" -#include "ui/aura/mus/capture_synchronizer.h" -#include "ui/aura/mus/mus_context_factory.h" -#include "ui/aura/mus/property_converter.h" -#include "ui/aura/mus/window_tree_client.h" -#include "ui/aura/mus/window_tree_host_mus.h" -#include "ui/aura/mus/window_tree_host_mus_init_params.h" -#include "ui/aura/window.h" -#include "ui/aura/window_tree_host.h" -#include "ui/base/mojo/clipboard_client.h" -#include "ui/views/mus/aura_init.h" -#include "ui/views/mus/desktop_window_tree_host_mus.h" -#include "ui/views/mus/mus_property_mirror.h" -#include "ui/views/mus/screen_mus.h" -#include "ui/views/views_delegate.h" -#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" -#include "ui/views/widget/widget_delegate.h" -#include "ui/wm/core/shadow_types.h" -#include "ui/wm/core/wm_state.h" - -// Widget::InitParams::Type must match that of ws::mojom::WindowType. -#define WINDOW_TYPES_MATCH(NAME) \ - static_assert( \ - static_cast<int32_t>(views::Widget::InitParams::TYPE_##NAME) == \ - static_cast<int32_t>(ws::mojom::WindowType::NAME), \ - "Window type constants must match") - -WINDOW_TYPES_MATCH(WINDOW); -WINDOW_TYPES_MATCH(WINDOW_FRAMELESS); -WINDOW_TYPES_MATCH(CONTROL); -WINDOW_TYPES_MATCH(POPUP); -WINDOW_TYPES_MATCH(MENU); -WINDOW_TYPES_MATCH(TOOLTIP); -WINDOW_TYPES_MATCH(BUBBLE); -WINDOW_TYPES_MATCH(DRAG); -// ws::mojom::WindowType::UNKNOWN does not correspond to a value in -// Widget::InitParams::Type. - -namespace views { - -// static -MusClient* MusClient::instance_ = nullptr; - -MusClient::InitParams::InitParams() = default; - -MusClient::InitParams::~InitParams() = default; - -MusClient::MusClient(const InitParams& params) : identity_(params.identity) { - DCHECK(!instance_); - DCHECK(aura::Env::GetInstance()); - instance_ = this; - - property_converter_ = std::make_unique<aura::PropertyConverter>(); - property_converter_->RegisterPrimitiveProperty( - ::wm::kShadowElevationKey, - ws::mojom::WindowManager::kShadowElevation_Property, - aura::PropertyConverter::CreateAcceptAnyValueCallback()); - - if (params.create_wm_state) - wm_state_ = std::make_unique<wm::WMState>(); - - service_manager::Connector* connector = params.connector; - - if (!params.window_tree_client) { - // If this process is running in the WindowService, then discardable memory - // should have already been created. - const bool create_discardable_memory = !params.running_in_ws_process; - owned_window_tree_client_ = - aura::WindowTreeClient::CreateForWindowTreeFactory( - connector, this, create_discardable_memory, - std::move(params.io_task_runner)); - window_tree_client_ = owned_window_tree_client_.get(); - aura::Env::GetInstance()->SetWindowTreeClient(window_tree_client_); - } else { - window_tree_client_ = params.window_tree_client; - } - - if (connector && !params.running_in_ws_process) { - input_device_client_ = std::make_unique<ws::InputDeviceClient>(); - ws::mojom::InputDeviceServerPtr input_device_server; - connector->BindInterface(ws::mojom::kServiceName, &input_device_server); - input_device_client_->Connect(std::move(input_device_server)); - - screen_ = std::make_unique<ScreenMus>(this); - display::Screen::SetScreenInstance(screen_.get()); - - // NOTE: this deadlocks if |running_in_ws_process| is true (because the main - // thread is running the WindowService). - window_tree_client_->WaitForDisplays(); - - ui::mojom::ClipboardHostPtr clipboard_host_ptr; - connector->BindInterface(ws::mojom::kServiceName, &clipboard_host_ptr); - ui::Clipboard::SetClipboardForCurrentThread( - std::make_unique<ui::ClipboardClient>(std::move(clipboard_host_ptr))); - } - - ViewsDelegate::GetInstance()->set_native_widget_factory(base::BindRepeating( - &MusClient::CreateNativeWidget, base::Unretained(this))); - ViewsDelegate::GetInstance()->set_desktop_window_tree_host_factory( - base::BindRepeating(&MusClient::CreateDesktopWindowTreeHost, - base::Unretained(this))); -} - -MusClient::~MusClient() { - // ~WindowTreeClient calls back to us (we're its delegate), destroy it while - // we are still valid. - owned_window_tree_client_.reset(); - window_tree_client_ = nullptr; - ui::Clipboard::DestroyClipboardForCurrentThread(); - - if (ViewsDelegate::GetInstance()) { - ViewsDelegate::GetInstance()->set_native_widget_factory( - ViewsDelegate::NativeWidgetFactory()); - ViewsDelegate::GetInstance()->set_desktop_window_tree_host_factory( - ViewsDelegate::DesktopWindowTreeHostFactory()); - } - - if (screen_) { - display::Screen::SetScreenInstance(nullptr); - screen_.reset(); - } - - DCHECK_EQ(instance_, this); - instance_ = nullptr; - DCHECK(aura::Env::GetInstance()); -} - -// static -bool MusClient::ShouldCreateDesktopNativeWidgetAura( - const Widget::InitParams& init_params) { - const bool from_window_service = - (init_params.context && - init_params.context->env()->mode() == aura::Env::Mode::LOCAL) || - (init_params.parent && - init_params.parent->env()->mode() == aura::Env::Mode::LOCAL); - // |from_window_service| is true if the aura::Env has a mode of LOCAL. If - // the mode is LOCAL there are two envs, one used by the window service - // (LOCAL), and the other for non-window-service code. Windows created with - // LOCAL should use NativeWidgetAura (which happens if false is returned - // here). - if (from_window_service) - return false; - - // TYPE_CONTROL and child widgets require a NativeWidgetAura. - return init_params.type != Widget::InitParams::TYPE_CONTROL && - !init_params.child; -} - -// static -bool MusClient::ShouldMakeWidgetWindowsTranslucent( - const Widget::InitParams& params) { - // |TYPE_WINDOW| is forced to translucent so that the window manager - // can draw the client decorations. - return params.opacity == Widget::InitParams::TRANSLUCENT_WINDOW || - params.type == Widget::InitParams::TYPE_WINDOW; -} - -// static -std::map<std::string, std::vector<uint8_t>> -MusClient::ConfigurePropertiesFromParams( - const Widget::InitParams& init_params) { - using PrimitiveType = aura::PropertyConverter::PrimitiveType; - using WindowManager = ws::mojom::WindowManager; - using TransportType = std::vector<uint8_t>; - - std::map<std::string, TransportType> properties = init_params.mus_properties; - - // Widget::InitParams::Type matches ws::mojom::WindowType. - properties[WindowManager::kWindowType_InitProperty] = - mojo::ConvertTo<TransportType>(static_cast<int32_t>(init_params.type)); - - properties[WindowManager::kFocusable_InitProperty] = - mojo::ConvertTo<TransportType>(init_params.CanActivate()); - - properties[WindowManager::kTranslucent_InitProperty] = - mojo::ConvertTo<TransportType>( - ShouldMakeWidgetWindowsTranslucent(init_params)); - - if (!init_params.bounds.IsEmpty()) { - properties[WindowManager::kBounds_InitProperty] = - mojo::ConvertTo<TransportType>(init_params.bounds); - } - - if (!init_params.name.empty()) { - properties[WindowManager::kName_Property] = - mojo::ConvertTo<TransportType>(init_params.name); - } - - properties[WindowManager::kAlwaysOnTop_Property] = - mojo::ConvertTo<TransportType>( - static_cast<PrimitiveType>(init_params.keep_on_top)); - - properties[WindowManager::kClientProvidesFrame_InitProperty] = - mojo::ConvertTo<TransportType>(init_params.remove_standard_frame); - - if (init_params.corner_radius) { - properties[WindowManager::kWindowCornerRadius_Property] = - mojo::ConvertTo<TransportType>( - static_cast<PrimitiveType>(*init_params.corner_radius)); - } - - if (!Widget::RequiresNonClientView(init_params.type)) - return properties; - - if (init_params.delegate) { - if (properties.count(WindowManager::kResizeBehavior_Property) == 0) { - properties[WindowManager::kResizeBehavior_Property] = - mojo::ConvertTo<TransportType>(static_cast<PrimitiveType>( - init_params.delegate->GetResizeBehavior())); - } - - if (init_params.delegate->ShouldShowWindowTitle()) { - properties[WindowManager::kWindowTitleShown_Property] = - mojo::ConvertTo<TransportType>(static_cast<PrimitiveType>( - init_params.delegate->ShouldShowWindowTitle())); - } - - if (!init_params.delegate->GetWindowTitle().empty()) { - properties[WindowManager::kWindowTitle_Property] = - mojo::ConvertTo<TransportType>( - init_params.delegate->GetWindowTitle()); - } - } - - return properties; -} - -NativeWidget* MusClient::CreateNativeWidget( - const Widget::InitParams& init_params, - internal::NativeWidgetDelegate* delegate) { - if (!ShouldCreateDesktopNativeWidgetAura(init_params)) { - // A null return value results in creating NativeWidgetAura. - return nullptr; - } - - DesktopNativeWidgetAura* native_widget = - new DesktopNativeWidgetAura(delegate); - if (init_params.desktop_window_tree_host) { - native_widget->SetDesktopWindowTreeHost( - base::WrapUnique(init_params.desktop_window_tree_host)); - } else { - native_widget->SetDesktopWindowTreeHost( - CreateDesktopWindowTreeHost(init_params, delegate, native_widget)); - } - return native_widget; -} - -void MusClient::OnCaptureClientSet( - aura::client::CaptureClient* capture_client) { - window_tree_client_->capture_synchronizer()->AttachToCaptureClient( - capture_client); -} - -void MusClient::OnCaptureClientUnset( - aura::client::CaptureClient* capture_client) { - window_tree_client_->capture_synchronizer()->DetachFromCaptureClient( - capture_client); -} - -void MusClient::AddObserver(MusClientObserver* observer) { - observer_list_.AddObserver(observer); -} - -void MusClient::RemoveObserver(MusClientObserver* observer) { - observer_list_.RemoveObserver(observer); -} - -void MusClient::SetMusPropertyMirror( - std::unique_ptr<MusPropertyMirror> mirror) { - mus_property_mirror_ = std::move(mirror); -} - -void MusClient::CloseAllWidgets() { - for (aura::Window* root : window_tree_client_->GetRoots()) { - Widget* widget = Widget::GetWidgetForNativeView(root); - if (widget) - widget->CloseNow(); - } -} - -std::unique_ptr<DesktopWindowTreeHost> MusClient::CreateDesktopWindowTreeHost( - const Widget::InitParams& init_params, - internal::NativeWidgetDelegate* delegate, - DesktopNativeWidgetAura* desktop_native_widget_aura) { - std::map<std::string, std::vector<uint8_t>> mus_properties = - ConfigurePropertiesFromParams(init_params); - aura::WindowTreeHostMusInitParams window_tree_host_init_params = - aura::CreateInitParamsForTopLevel(MusClient::Get()->window_tree_client(), - std::move(mus_properties)); - return std::make_unique<DesktopWindowTreeHostMus>( - std::move(window_tree_host_init_params), delegate, - desktop_native_widget_aura); -} - -void MusClient::OnEmbed( - std::unique_ptr<aura::WindowTreeHostMus> window_tree_host) { - NOTREACHED(); -} - -void MusClient::OnLostConnection(aura::WindowTreeClient* client) { - // Better to crash than to be left in a broken state. - IMMEDIATE_CRASH(); -} - -void MusClient::OnEmbedRootDestroyed( - aura::WindowTreeHostMus* window_tree_host) { - static_cast<DesktopWindowTreeHostMus*>(window_tree_host) - ->ServerDestroyedWindow(); -} - -void MusClient::OnDisplaysChanged( - std::vector<ws::mojom::WsDisplayPtr> ws_displays, - int64_t primary_display_id, - int64_t internal_display_id, - int64_t display_id_for_new_windows) { - if (screen_) { - screen_->OnDisplaysChanged(std::move(ws_displays), primary_display_id, - internal_display_id, display_id_for_new_windows); - } -} - -void MusClient::OnWindowManagerFrameValuesChanged() { - for (auto& observer : observer_list_) - observer.OnWindowManagerFrameValuesChanged(); -} - -aura::PropertyConverter* MusClient::GetPropertyConverter() { - return property_converter_.get(); -} - -aura::Window* MusClient::GetWindowAtScreenPoint(const gfx::Point& point) { - for (aura::Window* root : window_tree_client_->GetRoots()) { - aura::WindowTreeHost* window_tree_host = root->GetHost(); - if (!window_tree_host) - continue; - // TODO: this likely gets z-order wrong. http://crbug.com/663606. - gfx::Point relative_point(point); - window_tree_host->ConvertScreenInPixelsToDIP(&relative_point); - if (gfx::Rect(root->bounds().size()).Contains(relative_point)) - return root->GetEventHandlerForPoint(relative_point); - } - return nullptr; -} - -} // namespace views
diff --git a/ui/views/mus/mus_client.h b/ui/views/mus/mus_client.h deleted file mode 100644 index aa5441d..0000000 --- a/ui/views/mus/mus_client.h +++ /dev/null
@@ -1,190 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_MUS_MUS_CLIENT_H_ -#define UI_VIEWS_MUS_MUS_CLIENT_H_ - -#include <stdint.h> - -#include <map> -#include <string> -#include <vector> - -#include "base/macros.h" -#include "services/service_manager/public/cpp/identity.h" -#include "ui/aura/client/capture_client.h" -#include "ui/aura/mus/window_tree_client_delegate.h" -#include "ui/views/mus/mus_export.h" -#include "ui/views/mus/screen_mus_delegate.h" -#include "ui/views/widget/widget.h" - -namespace aura { -class PropertyConverter; -class Window; -class WindowTreeClient; -} - -namespace base { -class SingleThreadTaskRunner; -} - -namespace service_manager { -class Connector; -} - -namespace wm { -class WMState; -} - -namespace ws { -class InputDeviceClient; -} - -namespace views { - -class DesktopNativeWidgetAura; -class MusClientObserver; -class MusPropertyMirror; -class ScreenMus; - -namespace internal { -class NativeWidgetDelegate; -} - -// MusClient establishes a connection to mus and sets up necessary state so that -// aura and views target mus. This class is useful for typical clients, not the -// WindowManager. Most clients don't create this directly, rather use AuraInit. -class VIEWS_MUS_EXPORT MusClient : public aura::WindowTreeClientDelegate, - public ScreenMusDelegate { - public: - struct VIEWS_MUS_EXPORT InitParams { - InitParams(); - ~InitParams(); - - // Production code should provide |connector|, |identity|, and an - // |io_task_runner| if the process already has one. Test code may skip these - // parameters (e.g. a unit test that does not need to connect to the window - // service does not need to provide a connector). - service_manager::Connector* connector = nullptr; - service_manager::Identity identity; - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner = nullptr; - - // Create a wm::WMState. Some processes (e.g. the browser) may already - // have one. - bool create_wm_state = true; - - // If provided, MusClient will not create the WindowTreeClient. Not owned. - // Must outlive MusClient. - aura::WindowTreeClient* window_tree_client = nullptr; - - // Set to true if the WindowService is running in the same process and on - // the same thread as MusClient. - bool running_in_ws_process = false; - }; - - // Most clients should use AuraInit, which creates a MusClient. - explicit MusClient(const InitParams& params); - ~MusClient() override; - - static MusClient* Get() { return instance_; } - static bool Exists() { return instance_ != nullptr; } - - // Returns true if a DesktopNativeWidgetAura should be created given the - // specified params. If this returns false a NativeWidgetAura should be - // created. - static bool ShouldCreateDesktopNativeWidgetAura( - const Widget::InitParams& init_params); - - // Returns true if the windows backing the Widget should be made translucent. - static bool ShouldMakeWidgetWindowsTranslucent( - const Widget::InitParams& params); - - // Returns the properties to supply to mus when creating a window. - static std::map<std::string, std::vector<uint8_t>> - ConfigurePropertiesFromParams(const Widget::InitParams& init_params); - - aura::PropertyConverter* property_converter() { - return property_converter_.get(); - } - - aura::WindowTreeClient* window_tree_client() { return window_tree_client_; } - - // Creates DesktopNativeWidgetAura with DesktopWindowTreeHostMus. This is - // set as the factory function used for creating NativeWidgets when a - // NativeWidget has not been explicitly set. - NativeWidget* CreateNativeWidget(const Widget::InitParams& init_params, - internal::NativeWidgetDelegate* delegate); - - // Called when the capture client has been set or unset for a window. - void OnCaptureClientSet(aura::client::CaptureClient* capture_client); - void OnCaptureClientUnset(aura::client::CaptureClient* capture_client); - - void AddObserver(MusClientObserver* observer); - void RemoveObserver(MusClientObserver* observer); - - void SetMusPropertyMirror(std::unique_ptr<MusPropertyMirror> mirror); - MusPropertyMirror* mus_property_mirror() { - return mus_property_mirror_.get(); - } - - // Close all widgets this client knows. - void CloseAllWidgets(); - - private: - friend class AuraInit; - friend class MusClientTestApi; - - // Creates a DesktopWindowTreeHostMus. This is set as the factory function - // ViewsDelegate such that if DesktopNativeWidgetAura is created without a - // DesktopWindowTreeHost this is created. - std::unique_ptr<DesktopWindowTreeHost> CreateDesktopWindowTreeHost( - const Widget::InitParams& init_params, - internal::NativeWidgetDelegate* delegate, - DesktopNativeWidgetAura* desktop_native_widget_aura); - - // aura::WindowTreeClientDelegate: - void OnEmbed( - std::unique_ptr<aura::WindowTreeHostMus> window_tree_host) override; - void OnLostConnection(aura::WindowTreeClient* client) override; - void OnEmbedRootDestroyed(aura::WindowTreeHostMus* window_tree_host) override; - aura::PropertyConverter* GetPropertyConverter() override; - void OnDisplaysChanged(std::vector<ws::mojom::WsDisplayPtr> ws_displays, - int64_t primary_display_id, - int64_t internal_display_id, - int64_t display_id_for_new_windows) override; - - // ScreenMusDelegate: - void OnWindowManagerFrameValuesChanged() override; - aura::Window* GetWindowAtScreenPoint(const gfx::Point& point) override; - - static MusClient* instance_; - - service_manager::Identity identity_; - - base::ObserverList<MusClientObserver>::Unchecked observer_list_; - - // NOTE: this may be null (creation is based on argument supplied to - // constructor). - std::unique_ptr<wm::WMState> wm_state_; - - std::unique_ptr<ScreenMus> screen_; - - std::unique_ptr<aura::PropertyConverter> property_converter_; - std::unique_ptr<MusPropertyMirror> mus_property_mirror_; - - // Non-null if MusClient created the WindowTreeClient. - std::unique_ptr<aura::WindowTreeClient> owned_window_tree_client_; - - // Never null. - aura::WindowTreeClient* window_tree_client_; - - // Gives services transparent remote access the InputDeviceManager. - std::unique_ptr<ws::InputDeviceClient> input_device_client_; - - DISALLOW_COPY_AND_ASSIGN(MusClient); -}; - -} // namespace views - -#endif // UI_VIEWS_MUS_MUS_CLIENT_H_
diff --git a/ui/views/mus/mus_client_observer.h b/ui/views/mus/mus_client_observer.h deleted file mode 100644 index e680fc1..0000000 --- a/ui/views/mus/mus_client_observer.h +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_MUS_MUS_CLIENT_OBSERVER_H_ -#define UI_VIEWS_MUS_MUS_CLIENT_OBSERVER_H_ - -#include "ui/views/mus/mus_export.h" - -namespace views { - -// Allows individual DesktopWindowTreeHostsMus to observe MusClient events. -class VIEWS_MUS_EXPORT MusClientObserver { - public: - // Notification that windows should update per window values from the - // WindowManagerFrameValues. - virtual void OnWindowManagerFrameValuesChanged() = 0; - - protected: - virtual ~MusClientObserver() = default; -}; - -} // namespace views - -#endif // UI_VIEWS_MUS_MUS_CLIENT_OBSERVER_H_
diff --git a/ui/views/mus/mus_client_test_api.h b/ui/views/mus/mus_client_test_api.h deleted file mode 100644 index 2b311c6..0000000 --- a/ui/views/mus/mus_client_test_api.h +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_MUS_MUS_CLIENT_TEST_API_H_ -#define UI_VIEWS_MUS_MUS_CLIENT_TEST_API_H_ - -#include "base/macros.h" -#include "ui/views/mus/mus_client.h" - -namespace views { - -class MusClientTestApi { - public: - static ScreenMus* screen() { return MusClient::Get()->screen_.get(); } - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(MusClientTestApi); -}; - -} // namespace views - -#endif // UI_VIEWS_MUS_MUS_CLIENT_TEST_API_H_
diff --git a/ui/views/mus/mus_export.h b/ui/views/mus/mus_export.h deleted file mode 100644 index 9d5ff8b..0000000 --- a/ui/views/mus/mus_export.h +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright (c) 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_MUS_MUS_EXPORT_H_ -#define UI_VIEWS_MUS_MUS_EXPORT_H_ - -// Defines VIEWS_EXPORT so that functionality implemented by the Views module -// can be exported to consumers. - -#if defined(COMPONENT_BUILD) -#if defined(WIN32) - -#if defined(VIEWS_MUS_IMPLEMENTATION) -#define VIEWS_MUS_EXPORT __declspec(dllexport) -#else -#define VIEWS_MUS_EXPORT __declspec(dllimport) -#endif // defined(VIEWS_MUS_IMPLEMENTATION) - -#else // defined(WIN32) -#if defined(VIEWS_MUS_IMPLEMENTATION) -#define VIEWS_MUS_EXPORT __attribute__((visibility("default"))) -#else -#define VIEWS_MUS_EXPORT -#endif -#endif - -#else // defined(COMPONENT_BUILD) -#define VIEWS_MUS_EXPORT -#endif - -#endif // UI_VIEWS_MUS_MUS_EXPORT_H_
diff --git a/ui/views/mus/mus_property_mirror.h b/ui/views/mus/mus_property_mirror.h deleted file mode 100644 index da8389e2..0000000 --- a/ui/views/mus/mus_property_mirror.h +++ /dev/null
@@ -1,34 +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 UI_VIEWS_MUS_MUS_PROPERTY_MIRROR_H_ -#define UI_VIEWS_MUS_MUS_PROPERTY_MIRROR_H_ - -#include "ui/views/mus/mus_export.h" - -namespace aura { -class Window; -} - -namespace views { - -// Facilitates copying mus client window properties to their mash frame windows. -class VIEWS_MUS_EXPORT MusPropertyMirror { - public: - virtual ~MusPropertyMirror() = default; - - // Called when a property with the given |key| has changed for |window|. - // |window| is what mus clients get when calling |widget->GetNativeWindow()|. - // |root_window| is the top-level window representing the widget that is owned - // by the window manager and that the window manager observes for changes. - // Various ash features rely on property values of mus clients' root windows. - virtual void MirrorPropertyFromWidgetWindowToRootWindow( - aura::Window* window, - aura::Window* root_window, - const void* key) = 0; -}; - -} // namespace views - -#endif // UI_VIEWS_MUS_MUS_PROPERTY_MIRROR_H_
diff --git a/ui/views/mus/mus_views_delegate.cc b/ui/views/mus/mus_views_delegate.cc deleted file mode 100644 index 55e5a77..0000000 --- a/ui/views/mus/mus_views_delegate.cc +++ /dev/null
@@ -1,15 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/mus_views_delegate.h" - -#include "ui/views/mus/mus_client.h" - -namespace views { - -MusViewsDelegate::MusViewsDelegate() = default; - -MusViewsDelegate::~MusViewsDelegate() = default; - -} // namespace views
diff --git a/ui/views/mus/mus_views_delegate.h b/ui/views/mus/mus_views_delegate.h deleted file mode 100644 index d74ac42..0000000 --- a/ui/views/mus/mus_views_delegate.h +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_MUS_MUS_VIEWS_DELEGATE_H_ -#define UI_VIEWS_MUS_MUS_VIEWS_DELEGATE_H_ - -#include "base/macros.h" -#include "ui/views/layout/layout_provider.h" -#include "ui/views/mus/mus_export.h" -#include "ui/views/views_delegate.h" - -namespace views { - -// TODO(jamescook): Move the LayoutProvider and delete this class. -class VIEWS_MUS_EXPORT MusViewsDelegate : public ViewsDelegate { - public: - MusViewsDelegate(); - ~MusViewsDelegate() override; - - private: - LayoutProvider layout_provider_; - - DISALLOW_COPY_AND_ASSIGN(MusViewsDelegate); -}; - -} // namespace views - -#endif // UI_VIEWS_MUS_MUS_VIEWS_DELEGATE_H_
diff --git a/ui/views/mus/remote_view/BUILD.gn b/ui/views/mus/remote_view/BUILD.gn deleted file mode 100644 index 30f482b..0000000 --- a/ui/views/mus/remote_view/BUILD.gn +++ /dev/null
@@ -1,72 +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. - -source_set("remote_view_host") { - sources = [ - "remote_view_host.cc", - "remote_view_host.h", - ] - - public_deps = [ - "//base", - "//ui/aura", - "//ui/views", - ] - - deps = [] - if (is_chromeos) { - deps += [ "//ui/wm" ] - } -} - -source_set("remote_view_provider") { - sources = [ - "remote_view_provider.cc", - "remote_view_provider.h", - ] - - deps = [ - "//base", - "//ui/aura", - "//ui/views", - "//ui/views/mus", - ] -} - -source_set("test_support") { - testonly = true - - sources = [ - "remote_view_provider_test_api.cc", - "remote_view_provider_test_api.h", - ] - - deps = [ - ":remote_view_provider", - "//base", - ] -} - -source_set("tests") { - testonly = true - - sources = [ - "remote_view_host_unittest.cc", - "remote_view_provider_unittest.cc", - ] - - deps = [ - ":remote_view_host", - ":remote_view_provider", - ":test_support", - "//base", - "//base/test:test_support", - "//testing/gtest", - "//ui/aura", - "//ui/aura:test_support", - "//ui/base", - "//ui/views", - "//ui/views/mus", - ] -}
diff --git a/ui/views/mus/remote_view/README.md b/ui/views/mus/remote_view/README.md deleted file mode 100644 index 391437e..0000000 --- a/ui/views/mus/remote_view/README.md +++ /dev/null
@@ -1,55 +0,0 @@ -This directory contains helper classes to embed a `Window`. - -## `RemoteViewProvider` - -`RemoteViewProvider` wraps the work needed to provide a `Window` to another -(remote) client. Typical usage is to create an instance of it with the window to -provide to the remote client. - -e.g. -``` - ... - - // Step 1: Prepares for embedding after |window_for_remote_client_| is ready. - void StartEmbed() { - remote_view_provider_ = - std::make_unique<views::RemoteViewProvider>(window_for_remote_client_); - remote_view_client->GetEmbedToken(base::BindOnce( - &EmbeddedClient::OnGotEmbedToken, base::Unretained(this))); - } - - void OnGotEmbedToken(const base::UnguessableToken& token) { - // Step 2: Pass |token| to the embedder. - } - - // A Window to to provide to the remote client. - aura::Window* window_for_remote_client_; - - // Helper to prepare |window_for_remote_client_| for embedding. - std::unique_ptr<views::RemoteViewProvider> remote_view_provider_; - - ... -``` - -## `RemoteViewHost` - -`RemoteViewHost` wraps the work on the embedder side and is a `NativeViewHost` -that embeds the window from the `RemoteViewProvider`. `RemoveViewHost` is a -`View` that you add to your existing `View` hierarchy. - -e.g. -``` - class EmbedderView : public views::View { - public: - ... - // Creates a RemoteViewHost using |token| from the embedded client. - void AddEmbeddedView(const base::UnguessableToken& token) { - // Ownership will be passed to the view hierarchy in AddChildView. - views::RemoteViewHost* remote_view_host = new RemoteViewHost(); - remote_view_host->EmbedUsingToken(token, base::DoNothing()); - AddChildView(remote_view_host); - } - ... - }; -``` -
diff --git a/ui/views/mus/remote_view/remote_view_host.cc b/ui/views/mus/remote_view/remote_view_host.cc deleted file mode 100644 index 6060200..0000000 --- a/ui/views/mus/remote_view/remote_view_host.cc +++ /dev/null
@@ -1,74 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/remote_view/remote_view_host.h" - -#include <utility> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/logging.h" -#include "ui/aura/client/aura_constants.h" -#include "ui/aura/env.h" -#include "ui/aura/mus/window_port_mus.h" - -#if defined(OS_CHROMEOS) -#include "ui/wm/core/ime_util_chromeos.h" -#endif - -namespace views { - -RemoteViewHost::RemoteViewHost() - : embedding_root_(std::make_unique<aura::Window>(nullptr)) { - embedding_root_->set_owned_by_parent(false); - embedding_root_->SetName("RemoteViewHostWindow"); - embedding_root_->SetType(aura::client::WINDOW_TYPE_CONTROL); - embedding_root_->Init(ui::LAYER_NOT_DRAWN); - -#if defined(OS_CHROMEOS) - helper_ = - std::make_unique<wm::EnsureWindowNotInRectHelper>(embedding_root_.get()); -#endif -} - -RemoteViewHost::~RemoteViewHost() = default; - -void RemoteViewHost::EmbedUsingToken(const base::UnguessableToken& embed_token, - int embed_flags, - EmbedCallback callback) { - // Only works with mus. - DCHECK_EQ(aura::Env::Mode::MUS, aura::Env::GetInstance()->mode()); - - embed_token_ = embed_token; - embed_flags_ = embed_flags; - embed_callback_ = std::move(callback); - - if (GetWidget()) - EmbedImpl(); -} - -void RemoteViewHost::EmbedImpl() { - DCHECK(IsEmbedPending()); - aura::WindowPortMus::Get(embedding_root_.get()) - ->EmbedUsingToken(embed_token_, embed_flags_, - base::BindOnce(&RemoteViewHost::OnEmbedResult, - weak_ptr_factory_.GetWeakPtr())); -} - -void RemoteViewHost::OnEmbedResult(bool success) { - LOG_IF(ERROR, !success) << "Failed to embed, token=" << embed_token_; - embed_token_ = {}; - if (embed_callback_) - std::move(embed_callback_).Run(success); -} - -void RemoteViewHost::AddedToWidget() { - if (native_view()) - return; - Attach(embedding_root_.get()); - if (IsEmbedPending()) - EmbedImpl(); -} - -} // namespace views
diff --git a/ui/views/mus/remote_view/remote_view_host.h b/ui/views/mus/remote_view/remote_view_host.h deleted file mode 100644 index dac1c9d9..0000000 --- a/ui/views/mus/remote_view/remote_view_host.h +++ /dev/null
@@ -1,70 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_MUS_REMOTE_VIEW_REMOTE_VIEW_HOST_H_ -#define UI_VIEWS_MUS_REMOTE_VIEW_REMOTE_VIEW_HOST_H_ - -#include <memory> - -#include "base/callback_forward.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/unguessable_token.h" -#include "ui/aura/window.h" -#include "ui/views/controls/native/native_view_host.h" - -namespace wm { -class EnsureWindowNotInRectHelper; -} - -namespace views { - -// A view at the embedder side to embed an aura::Window from another window -// tree. Note this only works with mus. -class RemoteViewHost : public views::NativeViewHost { - public: - RemoteViewHost(); - ~RemoteViewHost() override; - - // Embeds the remote contents after this view is added to a widget. - // |embed_token| is the token obtained from the WindowTree embed API - // (ScheduleEmbed/ForExistingClient). |embed_flags| are the embedding flags - // (see window_tree_constants.mojom). |callback| is an optional callback - // invoked with the embed result. - // Note that |callback| should not be used to add the view to a widget because - // the actual embedding only happens after the view is added. - using EmbedCallback = base::OnceCallback<void(bool success)>; - void EmbedUsingToken(const base::UnguessableToken& embed_token, - int embed_flags, - EmbedCallback callback); - - private: - bool IsEmbedPending() const { return !embed_token_.is_empty(); } - - // Creates the embedding aura::Window and attach to it. - void EmbedImpl(); - - // Invoked after the embed operation. - void OnEmbedResult(bool success); - - // views::NativeViewHost: - void AddedToWidget() override; - - base::UnguessableToken embed_token_; - int embed_flags_ = 0; - EmbedCallback embed_callback_; - - const std::unique_ptr<aura::Window> embedding_root_; -#if defined(OS_CHROMEOS) - std::unique_ptr<wm::EnsureWindowNotInRectHelper> helper_; -#endif - - base::WeakPtrFactory<RemoteViewHost> weak_ptr_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(RemoteViewHost); -}; - -} // namespace views - -#endif // UI_VIEWS_MUS_REMOTE_VIEW_REMOTE_VIEW_HOST_H_
diff --git a/ui/views/mus/remote_view/remote_view_host_unittest.cc b/ui/views/mus/remote_view/remote_view_host_unittest.cc deleted file mode 100644 index 616e943..0000000 --- a/ui/views/mus/remote_view/remote_view_host_unittest.cc +++ /dev/null
@@ -1,158 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/remote_view/remote_view_host.h" - -#include <memory> -#include <utility> - -#include "base/bind.h" -#include "base/macros.h" -#include "base/run_loop.h" -#include "base/unguessable_token.h" -#include "ui/aura/test/aura_test_base.h" -#include "ui/aura/test/mus/test_window_tree.h" -#include "ui/gfx/geometry/rect.h" -#include "ui/views/widget/widget.h" -#include "ui/views/widget/widget_delegate.h" - -namespace views { - -namespace { - -// Embeds using |token| and waits for it. Returns true if embed succeeds. -bool Embed(RemoteViewHost* host, const base::UnguessableToken& token) { - base::RunLoop run_loop; - bool embed_result = false; - host->EmbedUsingToken( - token, 0u /* no flags */, - base::BindOnce( - [](base::RunLoop* run_loop, bool* result, bool success) { - *result = success; - run_loop->Quit(); - }, - &run_loop, &embed_result)); - run_loop.Run(); - return embed_result; -} - -} // namespace - -class RemoteViewHostTest : public aura::test::AuraTestBase { - public: - RemoteViewHostTest() = default; - ~RemoteViewHostTest() override = default; - - // aura::test::AuraTestBase - void SetUp() override { - env_ = aura::Env::CreateInstance(); - EnableMusWithTestWindowTree(); - AuraTestBase::SetUp(); - } - - void TearDown() override { - AuraTestBase::TearDown(); - env_.reset(); - } - - // Creates a widget to host |contents|. - std::unique_ptr<views::Widget> CreateTestWidget(views::View* contents) { - std::unique_ptr<views::Widget> widget = std::make_unique<views::Widget>(); - views::Widget::InitParams params; - params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS; - params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - params.bounds = gfx::Rect(0, 0, 100, 100); - params.context = root_window(); - widget->Init(params); - widget->SetContentsView(contents); - - return widget; - } - - // Helper callback invoked during embed to simulate adding to widget during - // embed operation. - void CreateTestWidgetWhileEmbeddingHelper( - base::RunLoop* run_loop, - views::View* contents, - std::unique_ptr<views::Widget>* widget, - bool success) { - ASSERT_TRUE(success); - *widget = CreateTestWidget(contents); - run_loop->Quit(); - } - - private: - std::unique_ptr<aura::Env> env_; - - DISALLOW_COPY_AND_ASSIGN(RemoteViewHostTest); -}; - -// Tests that the embed operation fails with an unknown token. -TEST_F(RemoteViewHostTest, BadEmbed) { - const base::UnguessableToken unknown_token = base::UnguessableToken::Create(); - - // Ownership will be passed to |widget| later. - RemoteViewHost* host = new RemoteViewHost(); - std::unique_ptr<views::Widget> widget = CreateTestWidget(host); - EXPECT_TRUE(host->native_view()); - - // Embed fails with unknown token. - EXPECT_FALSE(Embed(host, unknown_token)); - - // |host| is still attached despite the Embed failure. - EXPECT_TRUE(host->native_view()); -} - -// Tests when RemoveViewHost is added to a widget before embedding. -TEST_F(RemoteViewHostTest, AddToWidgetBeforeEmbed) { - const base::UnguessableToken token = base::UnguessableToken::Create(); - window_tree()->AddScheduledEmbedToken(token); - - // Ownership will be passed to |widget| later. - RemoteViewHost* host = new RemoteViewHost(); - - // |host| is not attached until the widget is created. - EXPECT_FALSE(host->native_view()); - std::unique_ptr<views::Widget> widget = CreateTestWidget(host); - EXPECT_TRUE(host->native_view()); - - // Embed succeeds. - EXPECT_TRUE(Embed(host, token)); - - // |host| is still attached to the embedding window. - EXPECT_TRUE(host->native_view()); -} - -// Tests when RemoveViewHost is added to a widget after embedding. -TEST_F(RemoteViewHostTest, AddToWidgetAfterEmbed) { - const base::UnguessableToken token = base::UnguessableToken::Create(); - window_tree()->AddScheduledEmbedToken(token); - - // Ownership will be passed to |widget| later. - RemoteViewHost* host = new RemoteViewHost(); - - // Request embedding but it will be deferred until added to a widget. - base::RunLoop run_loop; - bool embed_result = false; - host->EmbedUsingToken( - token, 0u /* no flags */, - base::BindOnce( - [](base::RunLoop* run_loop, bool* result, bool success) { - *result = success; - run_loop->Quit(); - }, - &run_loop, &embed_result)); - - // |host| is not attached before adding to a widget. - EXPECT_FALSE(host->native_view()); - - // Add to a widget and wait for embed to finish. - std::unique_ptr<views::Widget> widget = CreateTestWidget(host); - run_loop.Run(); - - // |host| is attached after added to a widget. - EXPECT_TRUE(host->native_view()); -} - -} // namespace views
diff --git a/ui/views/mus/remote_view/remote_view_provider.cc b/ui/views/mus/remote_view/remote_view_provider.cc deleted file mode 100644 index 2b8d9d5..0000000 --- a/ui/views/mus/remote_view/remote_view_provider.cc +++ /dev/null
@@ -1,161 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/remote_view/remote_view_provider.h" - -#include <utility> - -#include "base/bind.h" -#include "base/logging.h" -#include "base/scoped_observer.h" -#include "ui/aura/mus/embed_root.h" -#include "ui/aura/mus/window_tree_client.h" -#include "ui/aura/window.h" -#include "ui/aura/window_observer.h" -#include "ui/gfx/geometry/size.h" -#include "ui/views/mus/cursor_manager_owner.h" -#include "ui/views/mus/mus_client.h" -#include "ui/views/mus/screen_position_client_mus.h" -#include "ui/views/widget/desktop_aura/desktop_screen_position_client.h" - -namespace views { - -// static -aura::WindowTreeClient* RemoteViewProvider::window_tree_client_for_test = - nullptr; - -// Observes a window and invokes a callback when the window is destroyed. -class RemoteViewProvider::EmbeddedWindowObserver : public aura::WindowObserver { - public: - EmbeddedWindowObserver(aura::Window* window, base::OnceClosure on_destroyed) - : window_observer_(this), on_destroyed_(std::move(on_destroyed)) { - window_observer_.Add(window); - } - ~EmbeddedWindowObserver() override = default; - - // aura::WindowObserver: - void OnWindowDestroyed(aura::Window* window) override { - DCHECK(!on_destroyed_.is_null()); - - window_observer_.RemoveAll(); - std::move(on_destroyed_).Run(); - } - - private: - ScopedObserver<aura::Window, EmbeddedWindowObserver> window_observer_; - base::OnceClosure on_destroyed_; - - DISALLOW_COPY_AND_ASSIGN(EmbeddedWindowObserver); -}; - -// Observes a window and invokes a callback when the window size changes. -class RemoteViewProvider::EmbeddingWindowObserver - : public aura::WindowObserver { - public: - using SizeChangedCallback = base::RepeatingCallback<void(const gfx::Size&)>; - EmbeddingWindowObserver(aura::Window* window, SizeChangedCallback callback) - : window_observer_(this), on_size_changed_(std::move(callback)) { - window_observer_.Add(window); - } - ~EmbeddingWindowObserver() override = default; - - // aura::WindowObserver: - void OnWindowBoundsChanged(aura::Window* window, - const gfx::Rect& old_bounds, - const gfx::Rect& new_bounds, - ui::PropertyChangeReason reason) override { - on_size_changed_.Run(new_bounds.size()); - } - void OnWindowDestroyed(aura::Window* window) override { - window_observer_.RemoveAll(); - } - - private: - ScopedObserver<aura::Window, EmbeddingWindowObserver> window_observer_; - SizeChangedCallback on_size_changed_; - - DISALLOW_COPY_AND_ASSIGN(EmbeddingWindowObserver); -}; - -RemoteViewProvider::RemoteViewProvider(aura::Window* embedded) - : embedded_(embedded) { - DCHECK(embedded_); - embedded_window_observer_ = std::make_unique<EmbeddedWindowObserver>( - embedded_, base::BindOnce(&RemoteViewProvider::OnEmbeddedWindowDestroyed, - base::Unretained(this))); -} - -RemoteViewProvider::~RemoteViewProvider() = default; - -void RemoteViewProvider::GetEmbedToken(GetEmbedTokenCallback callback) { - DCHECK(embedded_); - - if (embed_root_) { - std::move(callback).Run(embed_root_->token()); - return; - } - - DCHECK(get_embed_token_callback_.is_null()); - get_embed_token_callback_ = std::move(callback); - - aura::WindowTreeClient* window_tree_client = window_tree_client_for_test; - if (!window_tree_client) { - DCHECK(views::MusClient::Exists()); - window_tree_client = views::MusClient::Get()->window_tree_client(); - } - - embed_root_ = window_tree_client->CreateEmbedRoot(this); -} - -void RemoteViewProvider::SetCallbacks(OnEmbedCallback on_embed, - OnUnembedCallback on_unembed) { - on_embed_callback_ = std::move(on_embed); - on_unembed_callback_ = std::move(on_unembed); -} - -void RemoteViewProvider::OnEmbeddedWindowDestroyed() { - embedded_ = nullptr; -} - -void RemoteViewProvider::OnEmbeddingWindowResized(const gfx::Size& size) { - // |embedded_| is owned by external code. Bail if it is destroyed while being - // embedded. - if (!embedded_) - return; - embedded_->SetBounds(gfx::Rect(size)); -} - -void RemoteViewProvider::OnEmbedTokenAvailable( - const base::UnguessableToken& token) { - if (get_embed_token_callback_) - std::move(get_embed_token_callback_).Run(token); -} - -void RemoteViewProvider::OnEmbed(aura::Window* window) { - DCHECK(embedded_); - - screen_position_client_ = std::make_unique<ScreenPositionClientMus>( - embed_root_->window_tree_host()); - embedding_window_observer_ = std::make_unique<EmbeddingWindowObserver>( - window, base::BindRepeating(&RemoteViewProvider::OnEmbeddingWindowResized, - base::Unretained(this))); - cursor_manager_owner_ = std::make_unique<CursorManagerOwner>(window); - OnEmbeddingWindowResized(window->bounds().size()); - window->AddChild(embedded_); - - if (on_embed_callback_) - on_embed_callback_.Run(window); -} - -void RemoteViewProvider::OnUnembed() { - screen_position_client_.reset(); - embedding_window_observer_.reset(); - cursor_manager_owner_.reset(); - embed_root_.reset(); - - if (on_unembed_callback_) - on_unembed_callback_.Run(); -} - -} // namespace views
diff --git a/ui/views/mus/remote_view/remote_view_provider.h b/ui/views/mus/remote_view/remote_view_provider.h deleted file mode 100644 index c50e893..0000000 --- a/ui/views/mus/remote_view/remote_view_provider.h +++ /dev/null
@@ -1,106 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_MUS_REMOTE_VIEW_REMOTE_VIEW_PROVIDER_H_ -#define UI_VIEWS_MUS_REMOTE_VIEW_REMOTE_VIEW_PROVIDER_H_ - -#include <memory> - -#include "base/callback.h" -#include "base/macros.h" -#include "base/unguessable_token.h" -#include "ui/aura/mus/embed_root_delegate.h" - -namespace aura { -class EmbedRoot; -class Window; -class WindowTreeClient; -} // namespace aura - -namespace gfx { -class Size; -} - -namespace views { - -class CursorManagerOwner; -class DesktopScreenPositionClient; - -namespace test { -class RemoteViewProviderTestApi; -} - -// Creates an EmbedRoot for an embedded aura::Window on the client side and -// updates the embedded window size when the embedder changes size. For example, -// allows app list in ash to embed web-based "answer cards" that are rendered -// by the browser. Note this works only with mus. -class RemoteViewProvider : public aura::EmbedRootDelegate { - public: - explicit RemoteViewProvider(aura::Window* embedded); - ~RemoteViewProvider() override; - - static void SetWindowTreeClientForTest(aura::WindowTreeClient* tree_client); - - // Gets the embed token. An embed token is obtained from one of WindowTree's - // schedule embed calls (ScheduleEmbed or ScheduleEmbedForExistingClient). An - // embedder calls EmbedUsingToken using the token to embed desired contents. - // The embed token here is from an aura::EmbedRoot that uses - // ScheduleEmbedForExistingClient for embedding part of an existing - // WindowTreeClient. |callback| is invoked when the token is available. - using GetEmbedTokenCallback = - base::OnceCallback<void(const base::UnguessableToken& token)>; - void GetEmbedToken(GetEmbedTokenCallback callback); - - // Optional callbacks to be invoked when embed or unembed happens. - using OnEmbedCallback = base::RepeatingCallback<void(aura::Window* embedder)>; - using OnUnembedCallback = base::RepeatingClosure; - void SetCallbacks(OnEmbedCallback on_embed, OnUnembedCallback on_unembed); - - private: - friend class test::RemoteViewProviderTestApi; - - class EmbeddedWindowObserver; - class EmbeddingWindowObserver; - - // Invoked when |embedded_| is destroyed. - void OnEmbeddedWindowDestroyed(); - - // Invoked when embedder changes size. - void OnEmbeddingWindowResized(const gfx::Size& size); - - // aura::EmbedRootDelegate: - void OnEmbedTokenAvailable(const base::UnguessableToken& token) override; - void OnEmbed(aura::Window* window) override; - void OnUnembed() override; - - // An aura::Window to be embedded. Not owned. - aura::Window* embedded_; - - std::unique_ptr<aura::EmbedRoot> embed_root_; - GetEmbedTokenCallback get_embed_token_callback_; - OnEmbedCallback on_embed_callback_; - OnUnembedCallback on_unembed_callback_; - - // An aura::WindowTreeClient for test. Use RemoteViewProviderTestApi to set - // it. - static aura::WindowTreeClient* window_tree_client_for_test; - - // Observes the |embedded_| and clears it when it is gone. - std::unique_ptr<EmbeddedWindowObserver> embedded_window_observer_; - - // Observes the embeddding window provided by embedder. - std::unique_ptr<EmbeddingWindowObserver> embedding_window_observer_; - - // Installed on the WindowTreeHost's window. Installing this makes - // aura::Window::GetBoundsInScreen() work for any descendants. - std::unique_ptr<DesktopScreenPositionClient> screen_position_client_; - - std::unique_ptr<CursorManagerOwner> cursor_manager_owner_; - - DISALLOW_COPY_AND_ASSIGN(RemoteViewProvider); -}; - -} // namespace views - -#endif // UI_VIEWS_MUS_REMOTE_VIEW_REMOTE_VIEW_PROVIDER_H_
diff --git a/ui/views/mus/remote_view/remote_view_provider_test_api.cc b/ui/views/mus/remote_view/remote_view_provider_test_api.cc deleted file mode 100644 index c3668ba2..0000000 --- a/ui/views/mus/remote_view/remote_view_provider_test_api.cc +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/remote_view/remote_view_provider_test_api.h" - -#include "ui/views/mus/remote_view/remote_view_provider.h" - -namespace views { -namespace test { - -void RemoteViewProviderTestApi::SetWindowTreeClient( - aura::WindowTreeClient* window_tree_client) { - RemoteViewProvider::window_tree_client_for_test = window_tree_client; -} - -} // namespace test -} // namespace views
diff --git a/ui/views/mus/remote_view/remote_view_provider_test_api.h b/ui/views/mus/remote_view/remote_view_provider_test_api.h deleted file mode 100644 index 49212fa..0000000 --- a/ui/views/mus/remote_view/remote_view_provider_test_api.h +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_MUS_REMOTE_VIEW_REMOTE_VIEW_PROVIDER_TEST_API_H_ -#define UI_VIEWS_MUS_REMOTE_VIEW_REMOTE_VIEW_PROVIDER_TEST_API_H_ - -#include "base/macros.h" - -namespace aura { -class WindowTreeClient; -} - -namespace views { -namespace test { - -class RemoteViewProviderTestApi { - public: - // Sets an aura::WindowTreeClient to use with RemoteViewProvider. - static void SetWindowTreeClient(aura::WindowTreeClient* window_tree_client); - - private: - DISALLOW_COPY_AND_ASSIGN(RemoteViewProviderTestApi); -}; - -} // namespace test -} // namespace views - -#endif // UI_VIEWS_MUS_REMOTE_VIEW_REMOTE_VIEW_PROVIDER_TEST_API_H_
diff --git a/ui/views/mus/remote_view/remote_view_provider_unittest.cc b/ui/views/mus/remote_view/remote_view_provider_unittest.cc deleted file mode 100644 index 3c08574..0000000 --- a/ui/views/mus/remote_view/remote_view_provider_unittest.cc +++ /dev/null
@@ -1,240 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/remote_view/remote_view_provider.h" - -#include <memory> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/macros.h" -#include "base/run_loop.h" -#include "base/test/bind_test_util.h" -#include "base/unguessable_token.h" -#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h" -#include "ui/aura/client/cursor_client.h" -#include "ui/aura/client/focus_change_observer.h" -#include "ui/aura/mus/window_mus.h" -#include "ui/aura/test/aura_test_base.h" -#include "ui/aura/test/mus/test_window_tree.h" -#include "ui/aura/window.h" -#include "ui/aura/window_tracker.h" -#include "ui/aura/window_tree_host.h" -#include "ui/gfx/geometry/rect.h" -#include "ui/views/mus/remote_view/remote_view_provider_test_api.h" - -namespace views { - -class TestFocusChangeObserver : public aura::client::FocusChangeObserver { - public: - explicit TestFocusChangeObserver(aura::Window* window) : window_(window) { - aura::client::SetFocusChangeObserver(window_, this); - } - ~TestFocusChangeObserver() override { - aura::client::SetFocusChangeObserver(window_, nullptr); - } - - // aura::client::FocusChangeObserver: - void OnWindowFocused(aura::Window* gained_focus, - aura::Window* lost_focus) override { - on_window_focused_called_ = true; - } - - bool on_window_focused_called() const { return on_window_focused_called_; } - - private: - aura::Window* const window_; - bool on_window_focused_called_ = false; - - DISALLOW_COPY_AND_ASSIGN(TestFocusChangeObserver); -}; - -class RemoteViewProviderTest : public aura::test::AuraTestBase { - public: - RemoteViewProviderTest() = default; - ~RemoteViewProviderTest() override = default; - - // aura::test::AuraTestBase - void SetUp() override { - env_ = aura::Env::CreateInstance(); - EnableMusWithTestWindowTree(); - AuraTestBase::SetUp(); - - test::RemoteViewProviderTestApi::SetWindowTreeClient( - window_tree_client_impl()); - - embedded_ = std::make_unique<aura::Window>(nullptr); - embedded_->set_owned_by_parent(false); - embedded_->Init(ui::LAYER_NOT_DRAWN); - embedded_->SetBounds(gfx::Rect(100, 50)); - - provider_ = std::make_unique<RemoteViewProvider>(embedded_.get()); - } - - void TearDown() override { - // EmbedRoot in |provider_| must be released before WindowTreeClient. - provider_.reset(); - - AuraTestBase::TearDown(); - } - - // Gets the embed token and waits for it. - base::UnguessableToken GetEmbedToken() { - base::RunLoop run_loop; - base::UnguessableToken token; - provider_->GetEmbedToken( - base::BindLambdaForTesting([&](const base::UnguessableToken& in_token) { - token = in_token; - run_loop.Quit(); - })); - run_loop.Run(); - return token; - } - - // Simulates EmbedUsingToken call on embedder side and waits for - // WindowTreeClient to create a local embedder window. - aura::Window* SimulateEmbedUsingTokenAndGetEmbedder( - const base::UnguessableToken& token) { - base::RunLoop run_loop; - aura::Window* embedder = nullptr; - provider_->SetCallbacks( - base::BindLambdaForTesting([&](aura::Window* in_embedder) { - embedder = in_embedder; - run_loop.Quit(); - }), - base::DoNothing() /* OnUnembedCallback */); - window_tree()->AddEmbedRootForToken(token); - run_loop.Run(); - return embedder; - } - - // Helper to simulate embed. - aura::Window* SimulateEmbed() { - base::UnguessableToken token = GetEmbedToken(); - if (token.is_empty()) { - ADD_FAILURE() << "Failed to get embed token."; - return nullptr; - } - - return SimulateEmbedUsingTokenAndGetEmbedder(token); - } - - // Simulates the embedder window close. - void SimulateEmbedderClose(aura::Window* embedder) { - base::RunLoop run_loop; - provider_->SetCallbacks( - base::DoNothing() /* OnEmbedCallback */, - base::BindLambdaForTesting([&]() { run_loop.Quit(); })); - - const ws::Id embedder_window_id = - aura::WindowMus::Get(embedder)->server_id(); - window_tree()->RemoveEmbedderWindow(embedder_window_id); - run_loop.Run(); - } - - protected: - std::unique_ptr<aura::Env> env_; - std::unique_ptr<aura::Window> embedded_; - std::unique_ptr<RemoteViewProvider> provider_; - - private: - DISALLOW_COPY_AND_ASSIGN(RemoteViewProviderTest); -}; - -// Tests the basics on the embedded client. -TEST_F(RemoteViewProviderTest, Embed) { - aura::Window* embedder = SimulateEmbed(); - ASSERT_TRUE(embedder); - - // |embedded_| has the same non-empty size with |embedder| after embed. - EXPECT_EQ(embedded_->bounds().size(), embedder->bounds().size()); - EXPECT_FALSE(embedded_->bounds().IsEmpty()); - EXPECT_FALSE(embedder->bounds().IsEmpty()); - - // |embedded_| resizes with |embedder|. - const gfx::Rect new_bounds(embedder->bounds().width() + 100, - embedder->bounds().height() + 50); - embedder->SetBounds(new_bounds); - EXPECT_EQ(embedded_->bounds().size(), embedder->bounds().size()); - EXPECT_FALSE(embedded_->bounds().IsEmpty()); - EXPECT_FALSE(embedder->bounds().IsEmpty()); -} - -// Tests when |embedded_| is released first. -TEST_F(RemoteViewProviderTest, EmbeddedReleasedFirst) { - SimulateEmbed(); - embedded_.reset(); -} - -// Tests when |provider_| is released first. -TEST_F(RemoteViewProviderTest, ClientReleasedFirst) { - SimulateEmbed(); - provider_.reset(); -} - -// Tests when embedder goes away first. -TEST_F(RemoteViewProviderTest, EmbedderReleasedFirst) { - aura::Window* embedder = SimulateEmbed(); - ASSERT_TRUE(embedder); - - SimulateEmbedderClose(embedder); -} - -// Tests that the client can embed again. -TEST_F(RemoteViewProviderTest, EmbedAgain) { - aura::Window* embedder = SimulateEmbed(); - ASSERT_TRUE(embedder); - - aura::WindowTracker window_tracker; - window_tracker.Add(embedder); - SimulateEmbedderClose(embedder); - // SimulateEmbedderClose() should delete |embedder|. - EXPECT_TRUE(window_tracker.windows().empty()); - - aura::Window* new_embedder = SimulateEmbed(); - // SimulateEmbed() should create a new window. - ASSERT_TRUE(new_embedder); -} - -TEST_F(RemoteViewProviderTest, ScreenBounds) { - aura::Window* embedder = SimulateEmbed(); - ASSERT_TRUE(embedder); - - aura::Window* root_window = embedded_->GetRootWindow(); - ASSERT_TRUE(root_window); - const gfx::Rect root_bounds(101, 102, 100, 50); - viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator; - parent_local_surface_id_allocator.GenerateId(); - window_tree_client()->OnWindowBoundsChanged( - aura::WindowMus::Get(root_window)->server_id(), root_bounds, - ui::SHOW_STATE_DEFAULT, - parent_local_surface_id_allocator.GetCurrentLocalSurfaceIdAllocation()); - EXPECT_EQ(root_bounds, root_window->GetHost()->GetBoundsInPixels()); - EXPECT_EQ(root_bounds.origin(), root_window->GetBoundsInScreen().origin()); -} - -TEST_F(RemoteViewProviderTest, FocusChangeObserver) { - SimulateEmbed(); - - TestFocusChangeObserver observer(embedded_.get()); - ASSERT_FALSE(observer.on_window_focused_called()); - - embedded_->Focus(); - EXPECT_TRUE(observer.on_window_focused_called()); -} - -TEST_F(RemoteViewProviderTest, Cursor) { - aura::Window* embedder = SimulateEmbed(); - ASSERT_TRUE(embedder); - - auto* cursor_client = - aura::client::GetCursorClient(embedded_->GetRootWindow()); - ASSERT_TRUE(cursor_client); - - EXPECT_NE(window_tree()->last_cursor(), ui::CursorType::kHand); - cursor_client->SetCursor(ui::CursorType::kHand); - EXPECT_EQ(window_tree()->last_cursor(), ui::CursorType::kHand); -} - -} // namespace views
diff --git a/ui/views/mus/screen_mus.cc b/ui/views/mus/screen_mus.cc deleted file mode 100644 index b4c9a266..0000000 --- a/ui/views/mus/screen_mus.cc +++ /dev/null
@@ -1,127 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/screen_mus.h" - -#include "base/stl_util.h" -#include "ui/aura/env.h" -#include "ui/aura/mus/window_tree_host_mus.h" -#include "ui/aura/window.h" -#include "ui/aura/window_tree_host.h" -#include "ui/display/types/display_constants.h" -#include "ui/views/mus/screen_mus_delegate.h" -#include "ui/views/mus/window_manager_frame_values.h" - -namespace mojo { - -template <> -struct TypeConverter<views::WindowManagerFrameValues, - ws::mojom::FrameDecorationValuesPtr> { - static views::WindowManagerFrameValues Convert( - const ws::mojom::FrameDecorationValuesPtr& input) { - views::WindowManagerFrameValues result; - result.normal_insets = input->normal_client_area_insets; - result.maximized_insets = input->maximized_client_area_insets; - result.max_title_bar_button_width = input->max_title_bar_button_width; - return result; - } -}; - -} // namespace mojo - -namespace views { - -using Type = display::DisplayList::Type; - -ScreenMus::ScreenMus(ScreenMusDelegate* delegate) : delegate_(delegate) { - DCHECK(delegate); -} - -ScreenMus::~ScreenMus() = default; - -void ScreenMus::OnDisplaysChanged( - std::vector<ws::mojom::WsDisplayPtr> ws_displays, - int64_t primary_display_id, - int64_t internal_display_id, - int64_t display_id_for_new_windows) { - const bool primary_changed = primary_display_id != GetPrimaryDisplay().id(); - int64_t handled_display_id = display::kInvalidDisplayId; - const WindowManagerFrameValues initial_frame_values = - WindowManagerFrameValues::instance(); - - if (internal_display_id != display::kInvalidDisplayId) - display::Display::SetInternalDisplayId(internal_display_id); - - if (primary_changed) { - handled_display_id = primary_display_id; - for (auto& ws_display_ptr : ws_displays) { - if (ws_display_ptr->display.id() == primary_display_id) { - WindowManagerFrameValues frame_values = - ws_display_ptr->frame_decoration_values - .To<WindowManagerFrameValues>(); - WindowManagerFrameValues::SetInstance(frame_values); - - const bool is_primary = true; - ProcessDisplayChanged(ws_display_ptr->display, is_primary); - break; - } - } - } - - // Add new displays and update existing ones. - std::set<int64_t> display_ids; - for (auto& ws_display_ptr : ws_displays) { - display_ids.insert(ws_display_ptr->display.id()); - if (handled_display_id == ws_display_ptr->display.id()) - continue; - - const bool is_primary = false; - ProcessDisplayChanged(ws_display_ptr->display, is_primary); - } - - // Remove any displays no longer in |ws_displays|. - std::set<int64_t> existing_display_ids; - for (const auto& display : display_list().displays()) - existing_display_ids.insert(display.id()); - std::set<int64_t> removed_display_ids = - base::STLSetDifference<std::set<int64_t>>(existing_display_ids, - display_ids); - for (int64_t display_id : removed_display_ids) { - // TODO(kylechar): DisplayList would need to change to handle having no - // primary display. - if (display_id != GetPrimaryDisplay().id()) - display_list().RemoveDisplay(display_id); - } - - if (primary_changed && - initial_frame_values != WindowManagerFrameValues::instance()) { - delegate_->OnWindowManagerFrameValuesChanged(); - } - - SetDisplayForNewWindows(display_id_for_new_windows); -} - -display::Display ScreenMus::GetDisplayNearestWindow( - gfx::NativeWindow window) const { - aura::WindowTreeHostMus* window_tree_host_mus = - aura::WindowTreeHostMus::ForWindow(window); - if (!window_tree_host_mus) - return GetPrimaryDisplay(); - return window_tree_host_mus->GetDisplay(); -} - -gfx::Point ScreenMus::GetCursorScreenPoint() { - return aura::Env::GetInstance()->last_mouse_location(); -} - -bool ScreenMus::IsWindowUnderCursor(gfx::NativeWindow window) { - return window && window->IsVisible() && - window->GetBoundsInScreen().Contains(GetCursorScreenPoint()); -} - -aura::Window* ScreenMus::GetWindowAtScreenPoint(const gfx::Point& point) { - return delegate_->GetWindowAtScreenPoint(point); -} - -} // namespace views
diff --git a/ui/views/mus/screen_mus.h b/ui/views/mus/screen_mus.h deleted file mode 100644 index 36bb1909c..0000000 --- a/ui/views/mus/screen_mus.h +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_MUS_SCREEN_MUS_H_ -#define UI_VIEWS_MUS_SCREEN_MUS_H_ - -#include "services/ws/public/mojom/screen_provider_observer.mojom.h" -#include "ui/display/screen_base.h" -#include "ui/views/mus/mus_export.h" - -namespace views { - -class ScreenMusDelegate; - -// Screen implementation that gets information from -// ws::mojom::ScreenProviderObserver. -// -// NOTE: this is not necessarily installed as the Screen implementation. -class VIEWS_MUS_EXPORT ScreenMus : public display::ScreenBase, - public ws::mojom::ScreenProviderObserver { - public: - explicit ScreenMus(ScreenMusDelegate* delegate); - ~ScreenMus() override; - - // ws::mojom::ScreenProviderObserver: - void OnDisplaysChanged(std::vector<ws::mojom::WsDisplayPtr> ws_displays, - int64_t primary_display_id, - int64_t internal_display_id, - int64_t display_id_for_new_windows) override; - - // display::Screen: - display::Display GetDisplayNearestWindow( - gfx::NativeWindow window) const override; - gfx::Point GetCursorScreenPoint() override; - bool IsWindowUnderCursor(gfx::NativeWindow window) override; - aura::Window* GetWindowAtScreenPoint(const gfx::Point& point) override; - - private: - ScreenMusDelegate* delegate_; - - DISALLOW_COPY_AND_ASSIGN(ScreenMus); -}; - -} // namespace views - -#endif // UI_VIEWS_MUS_SCREEN_MUS_H_
diff --git a/ui/views/mus/screen_mus_delegate.h b/ui/views/mus/screen_mus_delegate.h deleted file mode 100644 index a102510..0000000 --- a/ui/views/mus/screen_mus_delegate.h +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_MUS_SCREEN_MUS_DELEGATE_H_ -#define UI_VIEWS_MUS_SCREEN_MUS_DELEGATE_H_ - -#include "ui/views/mus/mus_export.h" - -namespace aura { -class Window; -} - -namespace gfx { -class Point; -} - -namespace views { - -// Delegate for screen implementation backed by ui::mojom::ScreenProvider. -class VIEWS_MUS_EXPORT ScreenMusDelegate { - public: - virtual void OnWindowManagerFrameValuesChanged() = 0; - - virtual aura::Window* GetWindowAtScreenPoint(const gfx::Point& point) = 0; - - protected: - virtual ~ScreenMusDelegate() = default; -}; - -} // namespace views - -#endif // UI_VIEWS_MUS_SCREEN_MUS_DELEGATE_H_
diff --git a/ui/views/mus/screen_mus_unittest.cc b/ui/views/mus/screen_mus_unittest.cc deleted file mode 100644 index d8a0c0b..0000000 --- a/ui/views/mus/screen_mus_unittest.cc +++ /dev/null
@@ -1,135 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/screen_mus.h" - -#include "base/command_line.h" -#include "base/test/scoped_task_environment.h" -#include "services/ws/public/mojom/window_tree_constants.mojom.h" -#include "ui/display/display_switches.h" -#include "ui/display/screen.h" -#include "ui/views/test/views_test_base.h" - -namespace views { -namespace { - -std::vector<ws::mojom::WsDisplayPtr> ConvertDisplayToWsDisplays( - const std::vector<display::Display>& displays) { - std::vector<ws::mojom::WsDisplayPtr> results; - for (const auto& display : displays) { - ws::mojom::WsDisplayPtr display_ptr = ws::mojom::WsDisplay::New(); - display_ptr->display = display; - display_ptr->frame_decoration_values = - ws::mojom::FrameDecorationValues::New(); - results.push_back(std::move(display_ptr)); - } - return results; -} - -using ScreenMusTest = ViewsTestWithDesktopNativeWidget; - -TEST_F(ScreenMusTest, PrimaryChangedToExisting) { - // ScreenMus is only used in multi-process Mash. - if (::features::IsSingleProcessMash()) - return; - - ScreenMus* screen = static_cast<ScreenMus*>(display::Screen::GetScreen()); - std::vector<display::Display> displays = screen->GetAllDisplays(); - ASSERT_FALSE(displays.empty()); - - // Convert to a single display with a different primary id. - displays.resize(1); - displays[0].set_id(displays[0].id() + 1); - screen->OnDisplaysChanged(ConvertDisplayToWsDisplays(displays), - displays[0].id(), 0, 0); - ASSERT_EQ(1u, screen->GetAllDisplays().size()); - EXPECT_EQ(displays[0].id(), screen->GetAllDisplays()[0].id()); - EXPECT_EQ(displays[0].id(), screen->GetPrimaryDisplay().id()); -} - -TEST_F(ScreenMusTest, AddAndUpdate) { - if (::features::IsSingleProcessMash()) - return; - - ScreenMus* screen = static_cast<ScreenMus*>(display::Screen::GetScreen()); - std::vector<display::Display> displays = screen->GetAllDisplays(); - ASSERT_FALSE(displays.empty()); - - // Update the bounds of display 1, and add a new display. - displays.resize(1); - gfx::Rect new_bounds = displays[0].bounds(); - new_bounds.set_height(new_bounds.height() + 1); - displays[0].set_bounds(new_bounds); - displays.push_back(displays[0]); - displays[1].set_id(displays[0].id() + 1); - screen->OnDisplaysChanged(ConvertDisplayToWsDisplays(displays), - displays[1].id(), 0, 0); - ASSERT_EQ(2u, screen->GetAllDisplays().size()); - ASSERT_TRUE(screen->display_list().FindDisplayById(displays[0].id()) != - screen->display_list().displays().end()); - EXPECT_EQ(new_bounds.height(), screen->display_list() - .FindDisplayById(displays[0].id()) - ->bounds() - .height()); - ASSERT_TRUE(screen->display_list().FindDisplayById(displays[1].id()) != - screen->display_list().displays().end()); - EXPECT_EQ(displays[1].id(), screen->GetPrimaryDisplay().id()); -} - -TEST_F(ScreenMusTest, SetDisplayForNewWindows) { - if (::features::IsSingleProcessMash()) - return; - - ScreenMus* screen = static_cast<ScreenMus*>(display::Screen::GetScreen()); - - // Set up 2 displays with display 1 as the display for new windows. - constexpr int64_t kDisplayId1 = 111; - constexpr int64_t kDisplayId2 = 222; - std::vector<display::Display> displays = {display::Display(kDisplayId1), - display::Display(kDisplayId2)}; - screen->OnDisplaysChanged(ConvertDisplayToWsDisplays(displays), kDisplayId1, - kDisplayId1, - kDisplayId1 /* display_id_for_new_windows */); - EXPECT_EQ(kDisplayId1, screen->GetDisplayForNewWindows().id()); - - // Set display 2 as the display for new windows. - screen->OnDisplaysChanged(ConvertDisplayToWsDisplays(displays), kDisplayId1, - kDisplayId1, - kDisplayId2 /* display_id_for_new_windows */); - EXPECT_EQ(kDisplayId2, screen->GetDisplayForNewWindows().id()); - - // Set a bad display as the display for new windows. ScreenMus should fall - // back to the primary display. - screen->OnDisplaysChanged(ConvertDisplayToWsDisplays(displays), kDisplayId1, - kDisplayId1, 666 /* display_id_for_new_windows */); - EXPECT_EQ(kDisplayId1, screen->GetDisplayForNewWindows().id()); -} - -class ScreenMusScaleFactorTest : public ScreenMusTest { - public: - ScreenMusScaleFactorTest() = default; - ~ScreenMusScaleFactorTest() override = default; - - void SetUp() override { - base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( - switches::kForceDeviceScaleFactor, "2"); - ScreenMusTest::SetUp(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(ScreenMusScaleFactorTest); -}; - -TEST_F(ScreenMusScaleFactorTest, ConsistentDisplayInHighDPI) { - display::Screen* screen = display::Screen::GetScreen(); - std::vector<display::Display> displays = screen->GetAllDisplays(); - ASSERT_FALSE(displays.empty()); - for (const display::Display& display : displays) { - EXPECT_EQ(2.f, display.device_scale_factor()); - EXPECT_EQ(display.work_area(), display.bounds()); - } -} - -} // namespace -} // namespace views
diff --git a/ui/views/mus/screen_position_client_mus.cc b/ui/views/mus/screen_position_client_mus.cc deleted file mode 100644 index 9fbca24..0000000 --- a/ui/views/mus/screen_position_client_mus.cc +++ /dev/null
@@ -1,23 +0,0 @@ -// 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 "ui/views/mus/screen_position_client_mus.h" - -#include "ui/aura/mus/window_tree_host_mus.h" -#include "ui/aura/window.h" - -namespace views { - -ScreenPositionClientMus::ScreenPositionClientMus(aura::WindowTreeHostMus* host) - : DesktopScreenPositionClient(host->window()), host_(host) {} - -ScreenPositionClientMus::~ScreenPositionClientMus() = default; - -gfx::Point ScreenPositionClientMus::GetOriginInScreen( - const aura::Window* window) { - DCHECK_EQ(window, host_->window()); - return host_->bounds_in_dip().origin(); -} - -} // namespace views
diff --git a/ui/views/mus/screen_position_client_mus.h b/ui/views/mus/screen_position_client_mus.h deleted file mode 100644 index 0d43390..0000000 --- a/ui/views/mus/screen_position_client_mus.h +++ /dev/null
@@ -1,37 +0,0 @@ -// 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 UI_VIEWS_MUS_SCREEN_POSITION_CLIENT_MUS_H_ -#define UI_VIEWS_MUS_SCREEN_POSITION_CLIENT_MUS_H_ - -#include "base/macros.h" -#include "ui/views/mus/mus_export.h" -#include "ui/views/widget/desktop_aura/desktop_screen_position_client.h" - -namespace aura { -class WindowTreeHostMus; -} - -namespace views { - -// ScreenPositionClient for mus. Ensures unnecessary conversions to pixels -// doesn't happen. -class VIEWS_MUS_EXPORT ScreenPositionClientMus - : public DesktopScreenPositionClient { - public: - explicit ScreenPositionClientMus(aura::WindowTreeHostMus* host); - ~ScreenPositionClientMus() override; - - // DesktopScreenPositionClient: - gfx::Point GetOriginInScreen(const aura::Window* window) override; - - private: - aura::WindowTreeHostMus* host_; - - DISALLOW_COPY_AND_ASSIGN(ScreenPositionClientMus); -}; - -} // namespace views - -#endif // UI_VIEWS_MUS_SCREEN_POSITION_CLIENT_MUS_H_
diff --git a/ui/views/mus/window_manager_constants_converters.cc b/ui/views/mus/window_manager_constants_converters.cc deleted file mode 100644 index 6e15c03..0000000 --- a/ui/views/mus/window_manager_constants_converters.cc +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/window_manager_constants_converters.h" - -namespace mojo { - -// static -ws::mojom::WindowType -TypeConverter<ws::mojom::WindowType, views::Widget::InitParams::Type>::Convert( - views::Widget::InitParams::Type type) { - switch (type) { - case views::Widget::InitParams::TYPE_WINDOW: - return ws::mojom::WindowType::WINDOW; - case views::Widget::InitParams::TYPE_WINDOW_FRAMELESS: - return ws::mojom::WindowType::WINDOW_FRAMELESS; - case views::Widget::InitParams::TYPE_CONTROL: - return ws::mojom::WindowType::CONTROL; - case views::Widget::InitParams::TYPE_POPUP: - return ws::mojom::WindowType::POPUP; - case views::Widget::InitParams::TYPE_MENU: - return ws::mojom::WindowType::MENU; - case views::Widget::InitParams::TYPE_TOOLTIP: - return ws::mojom::WindowType::TOOLTIP; - case views::Widget::InitParams::TYPE_BUBBLE: - return ws::mojom::WindowType::BUBBLE; - case views::Widget::InitParams::TYPE_DRAG: - return ws::mojom::WindowType::DRAG; - } - return ws::mojom::WindowType::POPUP; -} - -} // namespace mojo
diff --git a/ui/views/mus/window_manager_constants_converters.h b/ui/views/mus/window_manager_constants_converters.h deleted file mode 100644 index c24deec..0000000 --- a/ui/views/mus/window_manager_constants_converters.h +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_MUS_WINDOW_MANAGER_CONSTANTS_CONVERTERS_H_ -#define UI_VIEWS_MUS_WINDOW_MANAGER_CONSTANTS_CONVERTERS_H_ - -#include "services/ws/public/mojom/window_tree_constants.mojom.h" -#include "ui/views/mus/mus_export.h" -#include "ui/views/widget/widget.h" - -namespace mojo { - -template <> -struct VIEWS_MUS_EXPORT - TypeConverter<ws::mojom::WindowType, views::Widget::InitParams::Type> { - static ws::mojom::WindowType Convert(views::Widget::InitParams::Type type); -}; - -} // namespace mojo - -#endif // UI_VIEWS_MUS_WINDOW_MANAGER_CONSTANTS_CONVERTERS_H_
diff --git a/ui/views/mus/window_manager_frame_values.cc b/ui/views/mus/window_manager_frame_values.cc deleted file mode 100644 index 2e24d9fd..0000000 --- a/ui/views/mus/window_manager_frame_values.cc +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/mus/window_manager_frame_values.h" - -#include "base/lazy_instance.h" - -namespace views { -namespace { - -base::LazyInstance<WindowManagerFrameValues>::Leaky lazy_instance = - LAZY_INSTANCE_INITIALIZER; - -} // namespace - -WindowManagerFrameValues::WindowManagerFrameValues() = default; - -WindowManagerFrameValues::~WindowManagerFrameValues() = default; - -// static -void WindowManagerFrameValues::SetInstance( - const WindowManagerFrameValues& values) { - lazy_instance.Get() = values; -} - -// static -const WindowManagerFrameValues& WindowManagerFrameValues::instance() { - return lazy_instance.Get(); -} - -} // namespace views
diff --git a/ui/views/mus/window_manager_frame_values.h b/ui/views/mus/window_manager_frame_values.h deleted file mode 100644 index b65dbd42..0000000 --- a/ui/views/mus/window_manager_frame_values.h +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_MUS_WINDOW_MANAGER_FRAME_VALUES_H_ -#define UI_VIEWS_MUS_WINDOW_MANAGER_FRAME_VALUES_H_ - -#include "ui/gfx/geometry/insets.h" -#include "ui/views/mus/mus_export.h" - -namespace views { - -// Provides constants used by the window manager in rendering frame -// decorations. -struct VIEWS_MUS_EXPORT WindowManagerFrameValues { - WindowManagerFrameValues(); - ~WindowManagerFrameValues(); - - static void SetInstance(const WindowManagerFrameValues& values); - static const WindowManagerFrameValues& instance(); - - bool operator==(const WindowManagerFrameValues& other) const { - return normal_insets == other.normal_insets && - maximized_insets == other.maximized_insets && - max_title_bar_button_width == other.max_title_bar_button_width; - } - - bool operator!=(const WindowManagerFrameValues& other) const { - return !(*this == other); - } - - // Ideal insets the window manager renders non-client frame decorations into. - gfx::Insets normal_insets; - gfx::Insets maximized_insets; - - // Max width of buttons in the title bar. This width assumes all buttons are - // present. - int max_title_bar_button_width = 0; -}; - -} // namespace views - -#endif // UI_VIEWS_MUS_WINDOW_MANAGER_FRAME_VALUES_H_
diff --git a/ui/views/test/DEPS b/ui/views/test/DEPS index c5efd4c7..ebb84a2 100644 --- a/ui/views/test/DEPS +++ b/ui/views/test/DEPS
@@ -3,11 +3,8 @@ ] specific_include_rules = { - "platform_test_helper_mus.cc": [ - "+services/service_manager/background_service_manager.h", - "+services/service_manager/public", - "+services/viz/public/cpp", - "+services/ws/ime/test_ime_driver/public/cpp/manifest.h", - "+services/ws/test_ws/test_manifest.h", - ] + "views_test_base\.cc": [ + "+mojo/core/embedder", + "+ui/gl", + ], }
diff --git a/ui/views/test/platform_test_helper.h b/ui/views/test/platform_test_helper.h index 58f61b5..05d28a33 100644 --- a/ui/views/test/platform_test_helper.h +++ b/ui/views/test/platform_test_helper.h
@@ -18,7 +18,6 @@ namespace views { -class ViewsTestHelper; class Widget; class PlatformTestHelper { @@ -32,10 +31,6 @@ static void set_factory(Factory factory); static std::unique_ptr<PlatformTestHelper> Create(); - // Called once the ViewsTestHelper has been created, but before SetUp() is - // called. - virtual void OnTestHelperCreated(ViewsTestHelper* helper) {} - // Simulate an OS-level destruction of the native window held by |widget|. virtual void SimulateNativeDestroy(Widget* widget);
diff --git a/ui/views/test/platform_test_helper_mus.cc b/ui/views/test/platform_test_helper_mus.cc deleted file mode 100644 index ceb400ee..0000000 --- a/ui/views/test/platform_test_helper_mus.cc +++ /dev/null
@@ -1,209 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/views/test/platform_test_helper_mus.h" - -#include "base/bind.h" -#include "base/command_line.h" -#include "base/files/file_path.h" -#include "base/threading/simple_thread.h" -#include "services/service_manager/background_service_manager.h" -#include "services/service_manager/public/cpp/connector.h" -#include "services/service_manager/public/cpp/constants.h" -#include "services/service_manager/public/cpp/manifest_builder.h" -#include "services/service_manager/public/cpp/service.h" -#include "services/service_manager/public/cpp/service_binding.h" -#include "services/viz/public/cpp/manifest.h" -#include "services/ws/ime/test_ime_driver/public/cpp/manifest.h" -#include "services/ws/public/mojom/constants.mojom.h" -#include "services/ws/test_ws/test_manifest.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/aura/mus/window_tree_host_mus.h" -#include "ui/aura/test/env_test_helper.h" -#include "ui/aura/test/mus/input_method_mus_test_api.h" -#include "ui/aura/window.h" -#include "ui/base/ime/input_method_base.h" -#include "ui/base/ui_base_features.h" -#include "ui/views/mus/desktop_window_tree_host_mus.h" -#include "ui/views/mus/mus_client.h" -#include "ui/views/test/views_test_helper_aura.h" -#include "ui/views/views_delegate.h" -#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" -#include "ui/views/widget/native_widget_aura.h" - -namespace views { - -namespace { - -class TestInputMethod : public ui::InputMethodBase { - public: - TestInputMethod() : ui::InputMethodBase(nullptr) {} - ~TestInputMethod() override = default; - - // ui::InputMethod override: - ui::EventDispatchDetails DispatchKeyEvent(ui::KeyEvent* event) override { - return ui::EventDispatchDetails(); - } - ui::AsyncKeyDispatcher* GetAsyncKeyDispatcher() override { return nullptr; } - void OnCaretBoundsChanged(const ui::TextInputClient* client) override {} - void CancelComposition(const ui::TextInputClient* client) override {} - bool IsCandidatePopupOpen() const override { return false; } - - private: - DISALLOW_COPY_AND_ASSIGN(TestInputMethod); -}; - -NativeWidget* CreateNativeWidget(const Widget::InitParams& init_params, - internal::NativeWidgetDelegate* delegate) { - NativeWidget* native_widget = - MusClient::Get()->CreateNativeWidget(init_params, delegate); - if (!native_widget) - return nullptr; - - // Disable sending KeyEvents to IME as tests aren't set up to wait for an - // ack (and tests run concurrently). - aura::WindowTreeHostMus* window_tree_host_mus = - static_cast<aura::WindowTreeHostMus*>( - static_cast<DesktopNativeWidgetAura*>(native_widget)->host()); - - static TestInputMethod test_input_method; - window_tree_host_mus->SetSharedInputMethod(&test_input_method); - return native_widget; -} - -} // namespace - -class PlatformTestHelperMus::ServiceManagerConnection { - public: - ServiceManagerConnection() - : thread_("Persistent service_manager connections"), - default_service_binding_(&default_service_) { - base::WaitableEvent wait(base::WaitableEvent::ResetPolicy::AUTOMATIC, - base::WaitableEvent::InitialState::NOT_SIGNALED); - base::Thread::Options options; - thread_.StartWithOptions(options); - thread_.task_runner()->PostTask( - FROM_HERE, - base::BindOnce( - &ServiceManagerConnection::SetUpConnectionsOnBackgroundThread, - base::Unretained(this), &wait)); - wait.Wait(); - } - - ~ServiceManagerConnection() { - base::WaitableEvent wait(base::WaitableEvent::ResetPolicy::AUTOMATIC, - base::WaitableEvent::InitialState::NOT_SIGNALED); - thread_.task_runner()->PostTask( - FROM_HERE, - base::BindOnce( - &ServiceManagerConnection::TearDownConnectionsOnBackgroundThread, - base::Unretained(this), &wait)); - wait.Wait(); - } - - std::unique_ptr<MusClient> CreateMusClient() { - MusClient::InitParams params; - params.connector = GetConnector(); - params.identity = service_manager_identity_; - // The window tree client might have been created already by the test suite - // (e.g. AuraTestSuiteSetup). - params.window_tree_client = - aura::test::EnvTestHelper().GetWindowTreeClient(); - params.running_in_ws_process = ::features::IsSingleProcessMash(); - return std::make_unique<MusClient>(params); - } - - private: - service_manager::Connector* GetConnector() { - service_manager_connector_.reset(); - base::WaitableEvent wait(base::WaitableEvent::ResetPolicy::AUTOMATIC, - base::WaitableEvent::InitialState::NOT_SIGNALED); - thread_.task_runner()->PostTask( - FROM_HERE, base::BindOnce(&ServiceManagerConnection::CloneConnector, - base::Unretained(this), &wait)); - wait.Wait(); - DCHECK(service_manager_connector_); - return service_manager_connector_.get(); - } - - void CloneConnector(base::WaitableEvent* wait) { - service_manager_connector_ = - default_service_binding_.GetConnector()->Clone(); - wait->Signal(); - } - - void SetUpConnectionsOnBackgroundThread(base::WaitableEvent* wait) { - static const char* kServiceName = "views_unittests"; - - background_service_manager_ = - std::make_unique<service_manager::BackgroundServiceManager>( - std::vector<service_manager::Manifest>{ - test_ws::GetManifest(), test_ime_driver::GetManifest(), - viz::GetManifest(), - service_manager::ManifestBuilder() - .WithServiceName(kServiceName) - .RequireCapability("*", "app") - .RequireCapability("*", "test") - .Build()}); - - service_manager::mojom::ServicePtrInfo service; - default_service_binding_.Bind(mojo::MakeRequest(&service)); - // The service name matches the name field in unittests_manifest.json. - background_service_manager_->RegisterService( - service_manager::Identity(kServiceName, - service_manager::kSystemInstanceGroup, - base::Token{}, base::Token::CreateRandom()), - std::move(service), mojo::NullReceiver()); - service_manager_connector_ = - default_service_binding_.GetConnector()->Clone(); - service_manager_identity_ = default_service_binding_.identity(); - wait->Signal(); - } - - void TearDownConnectionsOnBackgroundThread(base::WaitableEvent* wait) { - default_service_binding_.Close(); - background_service_manager_.reset(); - wait->Signal(); - } - - base::Thread thread_; - std::unique_ptr<service_manager::BackgroundServiceManager> - background_service_manager_; - service_manager::Service default_service_; - service_manager::ServiceBinding default_service_binding_; - std::unique_ptr<service_manager::Connector> service_manager_connector_; - service_manager::Identity service_manager_identity_; - - DISALLOW_COPY_AND_ASSIGN(ServiceManagerConnection); -}; - -PlatformTestHelperMus::PlatformTestHelperMus() { - service_manager_connection_ = std::make_unique<ServiceManagerConnection>(); - mus_client_ = service_manager_connection_->CreateMusClient(); - ViewsDelegate::GetInstance()->set_native_widget_factory( - base::BindRepeating(&CreateNativeWidget)); -} - -PlatformTestHelperMus::~PlatformTestHelperMus() = default; - -void PlatformTestHelperMus::OnTestHelperCreated(ViewsTestHelper* helper) { - static_cast<ViewsTestHelperAura*>(helper)->EnableMusWithWindowTreeClient( - mus_client_->window_tree_client()); -} - -void PlatformTestHelperMus::SimulateNativeDestroy(Widget* widget) { - aura::WindowTreeHostMus* window_tree_host = - static_cast<aura::WindowTreeHostMus*>(widget->GetNativeView()->GetHost()); - static_cast<aura::WindowTreeClientDelegate*>(mus_client_.get()) - ->OnEmbedRootDestroyed(window_tree_host); -} - -void PlatformTestHelperMus::InitializeContextFactory( - ui::ContextFactory** context_factory, - ui::ContextFactoryPrivate** context_factory_private) { - *context_factory = &context_factory_; - *context_factory_private = nullptr; -} - -} // namespace views
diff --git a/ui/views/test/platform_test_helper_mus.h b/ui/views/test/platform_test_helper_mus.h deleted file mode 100644 index afc3245..0000000 --- a/ui/views/test/platform_test_helper_mus.h +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_VIEWS_TEST_PLATFORM_TEST_HELPER_MUS_H_ -#define UI_VIEWS_TEST_PLATFORM_TEST_HELPER_MUS_H_ - -#include "base/macros.h" -#include "ui/compositor/test/fake_context_factory.h" -#include "ui/views/test/platform_test_helper.h" - -namespace views { - -class MusClient; - -class PlatformTestHelperMus : public PlatformTestHelper { - public: - PlatformTestHelperMus(); - ~PlatformTestHelperMus() override; - - // PlatformTestHelper: - void OnTestHelperCreated(ViewsTestHelper* helper) override; - void SimulateNativeDestroy(Widget* widget) override; - void InitializeContextFactory( - ui::ContextFactory** context_factory, - ui::ContextFactoryPrivate** context_factory_private) override; - - private: - class ServiceManagerConnection; - - std::unique_ptr<ServiceManagerConnection> service_manager_connection_; - std::unique_ptr<MusClient> mus_client_; - ui::FakeContextFactory context_factory_; - - DISALLOW_COPY_AND_ASSIGN(PlatformTestHelperMus); -}; - -} // namespace views - -#endif // UI_VIEWS_TEST_PLATFORM_TEST_HELPER_MUS_H_
diff --git a/ui/views/test/scoped_views_test_helper.cc b/ui/views/test/scoped_views_test_helper.cc index aa615ff..2f28510 100644 --- a/ui/views/test/scoped_views_test_helper.cc +++ b/ui/views/test/scoped_views_test_helper.cc
@@ -34,7 +34,6 @@ test_helper_.reset( ViewsTestHelper::Create(context_factory, context_factory_private)); - platform_test_helper_->OnTestHelperCreated(test_helper_.get()); test_helper_->SetUp(); ui::InitializeInputMethodForTesting();
diff --git a/ui/views/test/views_test_base.cc b/ui/views/test/views_test_base.cc index 464992a..c2ea8a7 100644 --- a/ui/views/test/views_test_base.cc +++ b/ui/views/test/views_test_base.cc
@@ -21,26 +21,11 @@ #include "ui/views/test/platform_test_helper.h" #include "ui/views/test/test_platform_native_widget.h" -#if BUILDFLAG(ENABLE_MUS) -#include "base/at_exit.h" -#include "base/base_switches.h" -#include "base/command_line.h" -#include "base/message_loop/message_loop.h" -#include "base/threading/simple_thread.h" -#include "base/threading/thread.h" -#include "mojo/core/embedder/scoped_ipc_support.h" -#include "services/ws/common/switches.h" // nogncheck -#include "ui/aura/env.h" -#include "ui/base/ui_base_features.h" -#include "ui/base/ui_base_switches.h" -#include "ui/gl/gl_switches.h" -#include "ui/views/test/platform_test_helper_mus.h" -#include "ui/views/views_delegate.h" -#endif - #if defined(USE_AURA) -#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" #include "ui/views/widget/native_widget_aura.h" +#if !defined(OS_CHROMEOS) +#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" +#endif #elif defined(OS_MACOSX) #include "ui/views/widget/native_widget_mac.h" #endif @@ -77,12 +62,6 @@ #endif } -#if BUILDFLAG(ENABLE_MUS) -std::unique_ptr<PlatformTestHelper> CreatePlatformTestHelper() { - return std::make_unique<PlatformTestHelperMus>(); -} -#endif // BUILDFLAG(ENABLE_MUS) - } // namespace ViewsTestBase::ViewsTestBase() = default; @@ -102,46 +81,16 @@ has_compositing_manager_ = InitializeVisuals(); -#if BUILDFLAG(ENABLE_MUS) - at_exit_manager_ = std::make_unique<base::ShadowingAtExitManager>(); - if (!aura::Env::HasInstance()) { - env_ = aura::Env::CreateInstance(is_mus() ? aura::Env::Mode::MUS - : aura::Env::Mode::LOCAL); - } -#endif - testing::Test::SetUp(); ui::MaterialDesignController::Initialize(); setup_called_ = true; if (!views_delegate_for_setup_) views_delegate_for_setup_ = std::make_unique<TestViewsDelegate>(); -#if BUILDFLAG(ENABLE_MUS) - if (is_mus()) { - // Set the mash feature flag, but don't override single process mash. - if (!::features::IsSingleProcessMash()) { - feature_list_.InitAndEnableFeature(::features::kMash); - base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( - switches::kEnableFeatures, ::features::kMash.name); - } - - PlatformTestHelper::set_factory( - base::BindRepeating(&CreatePlatformTestHelper)); - - mojo::core::Init(); - ipc_thread_ = std::make_unique<base::Thread>("IPC thread"); - ipc_thread_->StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); - ipc_support_ = std::make_unique<mojo::core::ScopedIPCSupport>( - ipc_thread_->task_runner(), - mojo::core::ScopedIPCSupport::ShutdownPolicy::CLEAN); - } -#else if (native_widget_type_ == NativeWidgetType::kDesktop) { ViewsDelegate::GetInstance()->set_native_widget_factory(base::BindRepeating( &ViewsTestBase::CreateNativeWidgetForTest, base::Unretained(this))); } -#endif test_helper_ = std::make_unique<ScopedViewsTestHelper>( std::move(views_delegate_for_setup_)); @@ -158,32 +107,16 @@ teardown_called_ = true; testing::Test::TearDown(); test_helper_.reset(); - -#if BUILDFLAG(ENABLE_MUS) - ipc_support_.reset(); - ipc_thread_.reset(); - if (is_mus()) - PlatformTestHelper::set_factory({}); - env_.reset(); - at_exit_manager_.reset(); -#endif } void ViewsTestBase::SetUpForInteractiveTests() { DCHECK(!setup_called_); interactive_setup_called_ = true; -#if BUILDFLAG(ENABLE_MUS) - bool init_mojo = !is_mus(); -#else - bool init_mojo = true; -#endif - if (init_mojo) { - // Mojo is initialized here similar to how each browser test case - // initializes Mojo when starting. This only works because each - // interactive_ui_test runs in a new process. - mojo::core::Init(); - } + // Mojo is initialized here similar to how each browser test case initializes + // Mojo when starting. This only works because each interactive_ui_test runs + // in a new process. + mojo::core::Init(); gl::GLSurfaceTestSupport::InitializeOneOff(); ui::RegisterPathProvider(); @@ -234,8 +167,13 @@ } if (native_widget_type_ == NativeWidgetType::kDesktop) { +#if !defined(OS_CHROMEOS) return new test::TestPlatformNativeWidget<DesktopNativeWidgetAura>( delegate, false, nullptr); +#else + return new test::TestPlatformNativeWidget<NativeWidgetAura>(delegate, false, + nullptr); +#endif } return new test::TestPlatformNativeWidget<NativeWidgetAura>(delegate, true,
diff --git a/ui/views/test/views_test_base.h b/ui/views/test/views_test_base.h index e2e3d8e..9bad016 100644 --- a/ui/views/test/views_test_base.h +++ b/ui/views/test/views_test_base.h
@@ -8,7 +8,6 @@ #include <memory> #include "base/macros.h" -#include "base/test/scoped_feature_list.h" #include "base/test/scoped_task_environment.h" #include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h" @@ -22,14 +21,6 @@ #include "ui/base/win/scoped_ole_initializer.h" #endif -namespace aura { -class Env; -} - -namespace base { -class ShadowingAtExitManager; -} - namespace views { // A base class for views unit test. It creates a message loop necessary @@ -39,10 +30,11 @@ using ScopedTaskEnvironment = base::test::ScopedTaskEnvironment; enum class NativeWidgetType { - kDefault, // On Aura, corresponds to NativeWidgetAura. - kDesktop, // On Aura, corresponds to DesktopNativeWidgetAura. - // For Mus/ChromeOS, passing this to the ViewsTestBase - // constructor will also do necessary Mus setup. + // On Aura, corresponds to NativeWidgetAura. + kDefault, + // On chromeos, corresponds to NativeWidgetAura (DesktopNativeWidgetAura + // is not used on ChromeOS). + kDesktop, }; ViewsTestBase(); @@ -93,12 +85,6 @@ // RootWindow. Everywhere else, NULL. gfx::NativeWindow GetContext(); -#if BUILDFLAG(ENABLE_MUS) - bool is_mus() const { - return native_widget_type_ == NativeWidgetType::kDesktop; - } -#endif - // Factory for creating the native widget when |native_widget_type_| is set to // kDesktop. NativeWidget* CreateNativeWidgetForTest( @@ -113,17 +99,6 @@ // There are exceptions, such as for modal dialog widgets, for which this // value is ignored. NativeWidgetType native_widget_type_ = NativeWidgetType::kDefault; -#if BUILDFLAG(ENABLE_MUS) - // Needed to make sure the InputDeviceManager is cleaned up between test runs. - std::unique_ptr<base::ShadowingAtExitManager> at_exit_manager_; - // Unlike on other platforms, |aura::Env| has to be created for each test and - // not as part of the test suite, because the type (LOCAL or MUS) depends on - // the individual test. - std::unique_ptr<aura::Env> env_; - std::unique_ptr<base::Thread> ipc_thread_; - std::unique_ptr<mojo::core::ScopedIPCSupport> ipc_support_; - base::test::ScopedFeatureList feature_list_; -#endif std::unique_ptr<ScopedTaskEnvironment> scoped_task_environment_; std::unique_ptr<TestViewsDelegate> views_delegate_for_setup_;
diff --git a/ui/views/test/widget_test_aura.cc b/ui/views/test/widget_test_aura.cc index b43efc2..ea2ad38 100644 --- a/ui/views/test/widget_test_aura.cc +++ b/ui/views/test/widget_test_aura.cc
@@ -11,7 +11,6 @@ #include "ui/aura/window.h" #include "ui/aura/window_delegate.h" #include "ui/aura/window_tree_host.h" -#include "ui/views/mus/mus_client.h" #include "ui/views/widget/widget.h" #include "ui/wm/core/shadow_controller.h" @@ -80,20 +79,14 @@ reinterpret_cast<LPARAM>(&data)); } #endif - if (MusClient::Get()) { - auto mus_roots = MusClient::Get()->window_tree_client()->GetRoots(); - roots.insert(roots.end(), mus_roots.begin(), mus_roots.end()); - } else { - aura::test::AuraTestHelper* aura_test_helper = - aura::test::AuraTestHelper::GetInstance(); + aura::test::AuraTestHelper* aura_test_helper = + aura::test::AuraTestHelper::GetInstance(); #if defined(OS_CHROMEOS) - // Chrome OS non-mash unit tests use AuraTestHelper to get the root window. - // Chrome OS non-mash browser tests must use ash::Shell::GetAllRootWindows. - DCHECK(aura_test_helper) << "Can't find all widgets without a test helper"; + // Chrome OS browser tests must use ash::Shell::GetAllRootWindows. + DCHECK(aura_test_helper) << "Can't find all widgets without a test helper"; #endif - if (aura_test_helper) - roots.push_back(aura_test_helper->root_window()); - } + if (aura_test_helper) + roots.push_back(aura_test_helper->root_window()); return roots; }
diff --git a/ui/views/views_delegate.h b/ui/views/views_delegate.h index 2ec0fd6..52f1717 100644 --- a/ui/views/views_delegate.h +++ b/ui/views/views_delegate.h
@@ -40,8 +40,6 @@ class Widget; #if defined(USE_AURA) -class DesktopNativeWidgetAura; -class DesktopWindowTreeHost; class TouchSelectionMenuRunnerViews; #endif @@ -60,14 +58,6 @@ using NativeWidgetFactory = base::RepeatingCallback<NativeWidget*(const Widget::InitParams&, internal::NativeWidgetDelegate*)>; -#if defined(USE_AURA) - using DesktopWindowTreeHostFactory = - base::RepeatingCallback<std::unique_ptr<DesktopWindowTreeHost>( - const Widget::InitParams&, - internal::NativeWidgetDelegate*, - DesktopNativeWidgetAura*)>; -#endif - #if defined(OS_WIN) enum AppbarAutohideEdge { EDGE_TOP = 1 << 0, @@ -101,15 +91,6 @@ return native_widget_factory_; } -#if defined(USE_AURA) - void set_desktop_window_tree_host_factory( - DesktopWindowTreeHostFactory factory) { - desktop_window_tree_host_factory_ = std::move(factory); - } - const DesktopWindowTreeHostFactory& desktop_window_tree_host_factory() const { - return desktop_window_tree_host_factory_; - } -#endif // Saves the position, size and "show" state for the window with the // specified name. virtual void SaveWindowPlacement(const Widget* widget, @@ -205,8 +186,6 @@ #if defined(USE_AURA) std::unique_ptr<TouchSelectionMenuRunnerViews> touch_selection_menu_runner_; - - DesktopWindowTreeHostFactory desktop_window_tree_host_factory_; #endif NativeWidgetFactory native_widget_factory_;
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc index 2a38f66..c936fea4 100644 --- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc +++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -447,14 +447,6 @@ if (!desktop_window_tree_host_) { if (params.desktop_window_tree_host) { desktop_window_tree_host_ = params.desktop_window_tree_host; - } else if (!ViewsDelegate::GetInstance() - ->desktop_window_tree_host_factory() - .is_null()) { - desktop_window_tree_host_ = - ViewsDelegate::GetInstance() - ->desktop_window_tree_host_factory() - .Run(params, native_widget_delegate_, this) - .release(); } else { desktop_window_tree_host_ = DesktopWindowTreeHost::Create(native_widget_delegate_, this);
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win_unittest.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win_unittest.cc index 993eb6f7..bcddad8e 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win_unittest.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win_unittest.cc
@@ -2,15 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h" + #include <oleacc.h> #include <windows.h> +#include "base/command_line.h" #include "ui/accessibility/accessibility_switches.h" #include "ui/accessibility/platform/ax_platform_node_win.h" #include "ui/accessibility/platform/ax_system_caret_win.h" #include "ui/views/test/desktop_window_tree_host_win_test_api.h" #include "ui/views/test/widget_test.h" -#include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h" #include "ui/views/win/hwnd_message_handler.h" namespace views {
diff --git a/ui/views/widget/native_widget_aura.cc b/ui/views/widget/native_widget_aura.cc index 1659e91..6874a4d 100644 --- a/ui/views/widget/native_widget_aura.cc +++ b/ui/views/widget/native_widget_aura.cc
@@ -102,13 +102,9 @@ //////////////////////////////////////////////////////////////////////////////// // NativeWidgetAura, public: -NativeWidgetAura::NativeWidgetAura(internal::NativeWidgetDelegate* delegate, - bool is_parallel_widget_in_window_manager, - aura::Env* env) +NativeWidgetAura::NativeWidgetAura(internal::NativeWidgetDelegate* delegate) : delegate_(delegate), - is_parallel_widget_in_window_manager_( - is_parallel_widget_in_window_manager), - window_(new aura::Window(this, aura::client::WINDOW_TYPE_UNKNOWN, env)), + window_(new aura::Window(this, aura::client::WINDOW_TYPE_UNKNOWN)), ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET), destroying_(false), cursor_(gfx::kNullCursor), @@ -357,7 +353,7 @@ } void NativeWidgetAura::CenterWindow(const gfx::Size& size) { - if (!window_ || is_parallel_widget_in_window_manager_) + if (!window_) return; window_->SetProperty(aura::client::kPreferredSize, new gfx::Size(size)); @@ -419,7 +415,7 @@ } bool NativeWidgetAura::SetWindowTitle(const base::string16& title) { - if (!window_ || is_parallel_widget_in_window_manager_) + if (!window_) return false; if (window_->GetTitle() == title) return false; @@ -429,8 +425,7 @@ void NativeWidgetAura::SetWindowIcons(const gfx::ImageSkia& window_icon, const gfx::ImageSkia& app_icon) { - if (!is_parallel_widget_in_window_manager_) - AssignIconToAuraWindow(window_, window_icon, app_icon); + AssignIconToAuraWindow(window_, window_icon, app_icon); } void NativeWidgetAura::InitModalType(ui::ModalType modal_type) { @@ -610,7 +605,7 @@ } void NativeWidgetAura::SetAlwaysOnTop(bool on_top) { - if (window_ && !is_parallel_widget_in_window_manager_) + if (window_) window_->SetProperty(aura::client::kAlwaysOnTopKey, on_top); } @@ -813,9 +808,6 @@ } void NativeWidgetAura::OnSizeConstraintsChanged() { - if (is_parallel_widget_in_window_manager_) - return; - int32_t behavior = ws::mojom::kResizeBehaviorNone; if (GetWidget()->widget_delegate()) behavior = GetWidget()->widget_delegate()->GetResizeBehavior(); @@ -1123,15 +1115,8 @@ // static NativeWidgetPrivate* NativeWidgetPrivate::CreateNativeWidget( - const Widget::InitParams& init_params, internal::NativeWidgetDelegate* delegate) { - aura::Env* env = nullptr; - if (init_params.parent) - env = init_params.parent->env(); - else if (init_params.context) - env = init_params.context->env(); - return new NativeWidgetAura( - delegate, /*is_parallel_widget_in_window_manager*/ false, env); + return new NativeWidgetAura(delegate); } // static
diff --git a/ui/views/widget/native_widget_aura.h b/ui/views/widget/native_widget_aura.h index 9f50fed..ecda1d7 100644 --- a/ui/views/widget/native_widget_aura.h +++ b/ui/views/widget/native_widget_aura.h
@@ -21,7 +21,6 @@ #include "ui/wm/public/activation_delegate.h" namespace aura { -class Env; class Window; } @@ -40,12 +39,7 @@ public aura::client::FocusChangeObserver, public aura::client::DragDropDelegate { public: - // |is_parallel_widget_in_window_manager| is true only when this - // NativeWidgetAura is created in the window manager to represent a client - // window, in all other cases it's false. - explicit NativeWidgetAura(internal::NativeWidgetDelegate* delegate, - bool is_parallel_widget_in_window_manager = false, - aura::Env* env = nullptr); + explicit NativeWidgetAura(internal::NativeWidgetDelegate* delegate); // Called internally by NativeWidgetAura and DesktopNativeWidgetAura to // associate |native_widget| with |window|. @@ -217,10 +211,6 @@ internal::NativeWidgetDelegate* delegate_; - // True if the Widget is created in the window-manager and another client is - // embedded in it. When true certain operations are not performed. - const bool is_parallel_widget_in_window_manager_; - // WARNING: set to NULL when destroyed. As the Widget is not necessarily // destroyed along with |window_| all usage of |window_| should first verify // non-NULL.
diff --git a/ui/views/widget/native_widget_mac.mm b/ui/views/widget/native_widget_mac.mm index 8cf15d28..4b1b2c4 100644 --- a/ui/views/widget/native_widget_mac.mm +++ b/ui/views/widget/native_widget_mac.mm
@@ -764,7 +764,6 @@ // static NativeWidgetPrivate* NativeWidgetPrivate::CreateNativeWidget( - const Widget::InitParams& init_params, internal::NativeWidgetDelegate* delegate) { return new NativeWidgetMac(delegate); }
diff --git a/ui/views/widget/native_widget_private.h b/ui/views/widget/native_widget_private.h index c02942b..27f114f 100644 --- a/ui/views/widget/native_widget_private.h +++ b/ui/views/widget/native_widget_private.h
@@ -51,7 +51,6 @@ // Creates an appropriate default NativeWidgetPrivate implementation for the // current OS/circumstance. static NativeWidgetPrivate* CreateNativeWidget( - const Widget::InitParams& init_params, internal::NativeWidgetDelegate* delegate); static NativeWidgetPrivate* GetNativeWidgetForNativeView(
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc index d795406..ce097b1a 100644 --- a/ui/views/widget/widget.cc +++ b/ui/views/widget/widget.cc
@@ -77,7 +77,7 @@ if (native_widget) return native_widget; } - return internal::NativeWidgetPrivate::CreateNativeWidget(params, delegate); + return internal::NativeWidgetPrivate::CreateNativeWidget(delegate); } void NotifyCaretBoundsChanged(ui::InputMethod* input_method) {
diff --git a/ui/views/widget/widget.h b/ui/views/widget/widget.h index 7fefa87..8a073d7 100644 --- a/ui/views/widget/widget.h +++ b/ui/views/widget/widget.h
@@ -5,7 +5,6 @@ #ifndef UI_VIEWS_WIDGET_WIDGET_H_ #define UI_VIEWS_WIDGET_WIDGET_H_ -#include <map> #include <memory> #include <set> #include <string> @@ -301,10 +300,6 @@ // Used if widget is not activatable to do determine if mouse events should // be sent to the widget. bool wants_mouse_events_when_inactive = false; - - // A map of properties applied to windows when running in mus. - // TODO(crbug.com/958241): this is deprecated and will be removed shortly. - std::map<std::string, std::vector<uint8_t>> mus_properties; }; // Represents a lock held on the widget's ShouldPaintAsActive() state. As
diff --git a/ui/views/widget/widget_interactive_uitest.cc b/ui/views/widget/widget_interactive_uitest.cc index 683c60ae..e8c5f2c 100644 --- a/ui/views/widget/widget_interactive_uitest.cc +++ b/ui/views/widget/widget_interactive_uitest.cc
@@ -1025,6 +1025,7 @@ DISALLOW_COPY_AND_ASSIGN(ModalDialogDelegate); }; +#if !defined(OS_CHROMEOS) // Tests whether the focused window is set correctly when a modal window is // created and destroyed. When it is destroyed it should focus the owner window. TEST_F(DesktopWidgetTestInteractive, WindowModalWindowDestroyedActivationTest) { @@ -1051,12 +1052,6 @@ // Create a modal dialog. ui::ModalType modal_type = ui::MODAL_TYPE_WINDOW; -#if defined(OS_CHROMEOS) - // On Chrome OS this only works for MODAL_TYPE_CHILD, which makes a widget - // backed by NativeWidgetAura. Restoring focus to the parent window from a - // closed MODAL_TYPE_WINDOW requires help from the window service. - modal_type = ui::MODAL_TYPE_CHILD; -#endif // This instance will be destroyed when the dialog is destroyed. ModalDialogDelegate* dialog_delegate = new ModalDialogDelegate(modal_type); @@ -1090,6 +1085,7 @@ top_level_widget.CloseNow(); WidgetFocusManager::GetInstance()->RemoveFocusChangeListener(&focus_listener); } +#endif // Disabled on Mac. Desktop Mac doesn't have system modal windows since Carbon // was deprecated. It does have application modal windows, but only Ash requests @@ -1463,6 +1459,7 @@ } #endif // defined(OS_WIN) +#if !defined(OS_CHROMEOS) // Tests that minimizing a widget causes the gesture_handler // to be cleared when the widget is minimized. TEST_F(DesktopWidgetTestInteractive, EventHandlersClearedOnWidgetMinimize) { @@ -1482,6 +1479,7 @@ widget->CloseNow(); } +#endif #if defined(OS_LINUX) && !defined(OS_CHROMEOS) // Tests that when a desktop native widget has modal transient child, it should @@ -1533,7 +1531,7 @@ top_level->CloseNow(); deactivate_widget->CloseNow(); } -#endif // defined(USE_AURA) && !defined(OS_CHROMEOS) +#endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) namespace {
diff --git a/ui/views/widget/widget_unittest.cc b/ui/views/widget/widget_unittest.cc index cc4a524..9571a4f 100644 --- a/ui/views/widget/widget_unittest.cc +++ b/ui/views/widget/widget_unittest.cc
@@ -4001,8 +4001,13 @@ // activation. Test that shadows are added to non-root windows even if not // activated. TEST_F(WidgetShadowTest, MAYBE_ShadowsInRootWindow) { - // A desktop window clips to its bounds, so it shouldn't have a shadow. +#if defined(OS_CHROMEOS) + // On ChromeOS, top-levels have shadows. + bool top_level_window_should_have_shadow = true; +#else + // On non-chromeos platforms, the hosting OS is responsible for the shadow. bool top_level_window_should_have_shadow = false; +#endif // To start, just create a Widget. This constructs the first ShadowController // which will start observing the environment for additional aura::Window