diff --git a/DEPS b/DEPS index 6437326..157cc1c 100644 --- a/DEPS +++ b/DEPS
@@ -105,11 +105,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '5045e501d2aec23e5f1e4b46346033ac3202c6b0', + 'skia_revision': 'f2030783094e502fb74221077a5ee7cb41287fe4', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': 'a80d9730c72b47eb2f8350a50e88b104fea626c8', + 'v8_revision': '7edcaa70ff71125593e90bce1be8efe462c09a39', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -165,7 +165,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'f13bae2df0b82e06b4c7cf9b1ccaf5cee89c0c88', + 'catapult_revision': 'c5ef6d834a158822a50c67dc117835b28b32be73', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -588,7 +588,7 @@ # Used for embedded builds. CrOS & Linux use the system version. 'src/third_party/fontconfig/src': { - 'url': Var('chromium_git') + '/external/fontconfig.git' + '@' + '6cc99d6a82ad67d2f5eac887b28bca13c0dfddde', + 'url': Var('chromium_git') + '/external/fontconfig.git' + '@' + 'b546940435ebfb0df575bc7a2350d1e913919c34', 'condition': 'checkout_linux', }, @@ -1010,7 +1010,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '5e83981c2c44f24109b96b555d6865d481e0c609', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '00c71836144bebc1ffc61565f3bbb2048b7f4402', + Var('webrtc_git') + '/src.git' + '@' + '790da37b72f96feb8d5309b4485ef3df54ffa2d1', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/WATCHLISTS b/WATCHLISTS index 0e92a9c..7ba22c8 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -100,9 +100,6 @@ '|chrome/browser/ui/web_applications/'\ '|chrome/common/mac/' }, - 'appcache': { - 'filepath': 'appcache/', - }, 'apps': { 'filepath': '^apps/', }, @@ -1706,7 +1703,6 @@ 'app_list': ['tfarina@chromium.org'], 'app_shortcuts': ['mgiuca+watch@chromium.org', 'tapted+watch@chromium.org'], - 'appcache': ['michaeln@chromium.org'], 'apps': ['chromium-apps-reviews@chromium.org', 'tfarina@chromium.org'], 'arc': ['elijahtaylor+arcwatch@chromium.org', @@ -1827,8 +1823,7 @@ 'tzik@chromium.org'], 'blink_frames': ['blink-reviews-frames@chromium.org'], 'blink_geolocation': ['timvolodine@chromium.org'], - 'blink_heap': ['ager@chromium.org', - 'haraken@chromium.org', + 'blink_heap': ['haraken@chromium.org', 'kouhei+heap@chromium.org', 'oilpan-reviews@chromium.org'], 'blink_html': ['blink-reviews-html@chromium.org'], @@ -1895,7 +1890,6 @@ 'horo+watch@chromium.org', 'jsbell+serviceworker@chromium.org', 'kinuko+serviceworker@chromium.org', - 'michaeln@chromium.org', 'nhiroki@chromium.org', 'serviceworker-reviews@chromium.org', 'shimazu+serviceworker@chromium.org', @@ -2279,7 +2273,6 @@ 'service_worker': ['horo+watch@chromium.org', 'jsbell+serviceworker@chromium.org', 'kinuko+serviceworker@chromium.org', - 'michaeln@chromium.org', 'nhiroki@chromium.org', 'serviceworker-reviews@chromium.org', 'shimazu+serviceworker@chromium.org',
diff --git a/ash/frame/custom_frame_view_ash.cc b/ash/frame/custom_frame_view_ash.cc index 3fe6ed7..0a49a50 100644 --- a/ash/frame/custom_frame_view_ash.cc +++ b/ash/frame/custom_frame_view_ash.cc
@@ -458,6 +458,7 @@ } void CustomFrameViewAsh::SetVisible(bool visible) { + overlay_view_->SetVisible(visible); views::View::SetVisible(visible); // We need to re-layout so that client view will occupy entire window. InvalidateLayout();
diff --git a/base/BUILD.gn b/base/BUILD.gn index 93fc7d49..f0f92302 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -941,8 +941,6 @@ "timer/elapsed_timer.h", "timer/hi_res_timer_manager.h", "timer/hi_res_timer_manager_win.cc", - "timer/mock_timer.cc", - "timer/mock_timer.h", "timer/timer.cc", "timer/timer.h", "trace_event/auto_open_close_event.cc",
diff --git a/base/mac/mac_util.mm b/base/mac/mac_util.mm index a8308be5..82b90470 100644 --- a/base/mac/mac_util.mm +++ b/base/mac/mac_util.mm
@@ -422,7 +422,7 @@ // immediate death. CHECK(darwin_major_version >= 6); int mac_os_x_minor_version = darwin_major_version - 4; - DLOG_IF(WARNING, darwin_major_version > 17) + DLOG_IF(WARNING, darwin_major_version > 18) << "Assuming Darwin " << base::IntToString(darwin_major_version) << " is macOS 10." << base::IntToString(mac_os_x_minor_version);
diff --git a/base/test/BUILD.gn b/base/test/BUILD.gn index d56ffc0..ab2d2c0d 100644 --- a/base/test/BUILD.gn +++ b/base/test/BUILD.gn
@@ -26,6 +26,8 @@ static_library("test_support") { testonly = true sources = [ + "../timer/mock_timer.cc", + "../timer/mock_timer.h", "../trace_event/trace_config_memory_test_util.h", "android/java_handler_thread_helpers.cc", "android/java_handler_thread_helpers.h",
diff --git a/base/test/fontconfig_util_linux.cc b/base/test/fontconfig_util_linux.cc index 7111119..5c9bf5c 100644 --- a/base/test/fontconfig_util_linux.cc +++ b/base/test/fontconfig_util_linux.cc
@@ -7,7 +7,6 @@ #include <fontconfig/fontconfig.h> #include "base/base_paths.h" -#include "base/environment.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/logging.h" @@ -382,35 +381,31 @@ } // namespace void SetUpFontconfig() { - // TODO(thomasanderson): Use FONTCONFIG_SYSROOT to avoid having to write - // a new fonts.conf with updated paths. - std::unique_ptr<Environment> env = Environment::Create(); - if (!env->HasVar("FONTCONFIG_FILE")) { - // fonts.conf must be generated on-the-fly since it contains absolute paths - // which may be different if - // 1. The user moves/renames their build directory (or any parent dirs). - // 2. The build directory is mapped on a swarming bot at a location - // different from the one the buildbot used. - FilePath dir_module; - PathService::Get(DIR_MODULE, &dir_module); - FilePath font_cache = dir_module.Append("fontconfig_caches"); - FilePath test_fonts = dir_module.Append("test_fonts"); - std::string fonts_conf = ReplaceStringPlaceholders( - kFontsConfTemplate, {font_cache.value(), test_fonts.value()}, nullptr); + FilePath dir_module; + PathService::Get(DIR_MODULE, &dir_module); + FilePath font_cache = dir_module.Append("fontconfig_caches"); + FilePath test_fonts = dir_module.Append("test_fonts"); + std::string fonts_conf = ReplaceStringPlaceholders( + kFontsConfTemplate, {font_cache.value(), test_fonts.value()}, nullptr); - // Write the data to a different file and then atomically rename it to - // fonts.conf. This avoids the file being in a bad state when different - // parallel tests call this function at the same time. - FilePath fonts_conf_file_temp; - CHECK(CreateTemporaryFileInDir(dir_module, &fonts_conf_file_temp)); - CHECK( - WriteFile(fonts_conf_file_temp, fonts_conf.c_str(), fonts_conf.size())); - FilePath fonts_conf_file = dir_module.Append("fonts.conf"); - CHECK(ReplaceFile(fonts_conf_file_temp, fonts_conf_file, nullptr)); - env->SetVar("FONTCONFIG_FILE", fonts_conf_file.value()); - } + FcConfig* config = FcConfigCreate(); + CHECK(config); +#if FC_VERSION >= 21205 + CHECK(FcConfigParseAndLoadFromMemory( + config, reinterpret_cast<const FcChar8*>(fonts_conf.c_str()), FcTrue)); +#else + FilePath temp; + CHECK(CreateTemporaryFile(&temp)); + CHECK(WriteFile(temp, fonts_conf.c_str(), fonts_conf.size())); + CHECK(FcConfigParseAndLoad( + config, reinterpret_cast<const FcChar8*>(temp.value().c_str()), FcTrue)); + CHECK(DeleteFile(temp, false)); +#endif + CHECK(FcConfigBuildFonts(config)); + CHECK(FcConfigSetCurrent(config)); - CHECK(FcInit()); + // Decrement the reference count for |config|. It's now owned by fontconfig. + FcConfigDestroy(config); } void TearDownFontconfig() {
diff --git a/base/timer/mock_timer.cc b/base/timer/mock_timer.cc index ca0893b..b9cda80 100644 --- a/base/timer/mock_timer.cc +++ b/base/timer/mock_timer.cc
@@ -4,56 +4,79 @@ #include "base/timer/mock_timer.h" +#include "base/test/test_simple_task_runner.h" + namespace base { -MockTimer::MockTimer(bool retain_user_task, bool is_repeating) - : Timer(retain_user_task, is_repeating), - is_running_(false) { +namespace { + +void FlushPendingTasks(TestSimpleTaskRunner* task_runner) { + // Do not use TestSimpleTaskRunner::RunPendingTasks() here. As RunPendingTasks + // overrides ThreadTaskRunnerHandle when it runs tasks, tasks posted by timer + // tasks to TTRH go to |test_task_runner_|, though they should be posted to + // the original task runner. + // Do not use TestSimpleTaskRunner::RunPendingTasks(), as its overridden + // ThreadTaskRunnerHandle causes unexpected side effects. + for (TestPendingTask& task : task_runner->TakePendingTasks()) + std::move(task.task).Run(); } -MockTimer::MockTimer(const Location& posted_from, - TimeDelta delay, - const base::Closure& user_task, - bool is_repeating) - : Timer(true, is_repeating), delay_(delay), is_running_(false) {} +} // namespace + +MockTimer::MockTimer(bool retain_user_task, bool is_repeating) + : Timer(retain_user_task, is_repeating, &clock_), + test_task_runner_(MakeRefCounted<TestSimpleTaskRunner>()) { + Timer::SetTaskRunner(test_task_runner_); +} MockTimer::~MockTimer() = default; -bool MockTimer::IsRunning() const { - return is_running_; -} - -base::TimeDelta MockTimer::GetCurrentDelay() const { - return delay_; -} - -void MockTimer::Start(const Location& posted_from, - TimeDelta delay, - const base::Closure& user_task) { - delay_ = delay; - user_task_ = user_task; - Reset(); -} - -void MockTimer::Stop() { - is_running_ = false; - if (!retain_user_task()) - user_task_.Reset(); -} - -void MockTimer::Reset() { - DCHECK(!user_task_.is_null()); - is_running_ = true; +void MockTimer::SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner) { + NOTREACHED() << "MockTimer doesn't support SetTaskRunner()."; } void MockTimer::Fire() { - DCHECK(is_running_); - base::Closure old_task = user_task_; - if (is_repeating()) - Reset(); - else - Stop(); - old_task.Run(); + DCHECK(IsRunning()); + clock_.Advance(std::max(TimeDelta(), desired_run_time() - clock_.NowTicks())); + FlushPendingTasks(test_task_runner_.get()); +} + +MockOneShotTimer::MockOneShotTimer() + : OneShotTimer(&clock_), + test_task_runner_(MakeRefCounted<TestSimpleTaskRunner>()) { + OneShotTimer::SetTaskRunner(test_task_runner_); +} + +MockOneShotTimer::~MockOneShotTimer() = default; + +void MockOneShotTimer::SetTaskRunner( + scoped_refptr<SequencedTaskRunner> task_runner) { + NOTREACHED() << "MockOneShotTimer doesn't support SetTaskRunner()."; +} + +void MockOneShotTimer::Fire() { + DCHECK(IsRunning()); + clock_.Advance(std::max(TimeDelta(), desired_run_time() - clock_.NowTicks())); + FlushPendingTasks(test_task_runner_.get()); +} + +MockRepeatingTimer::MockRepeatingTimer() + : RepeatingTimer(&clock_), + test_task_runner_(MakeRefCounted<TestSimpleTaskRunner>()) { + RepeatingTimer::SetTaskRunner(test_task_runner_); +} + +MockRepeatingTimer::~MockRepeatingTimer() = default; + +void MockRepeatingTimer::SetTaskRunner( + scoped_refptr<SequencedTaskRunner> task_runner) { + NOTREACHED() << "MockRepeatingTimer doesn't support SetTaskRunner()."; +} + +void MockRepeatingTimer::Fire() { + DCHECK(IsRunning()); + clock_.Advance(std::max(TimeDelta(), desired_run_time() - clock_.NowTicks())); + FlushPendingTasks(test_task_runner_.get()); } } // namespace base
diff --git a/base/timer/mock_timer.h b/base/timer/mock_timer.h index 49394b2..597e155 100644 --- a/base/timer/mock_timer.h +++ b/base/timer/mock_timer.h
@@ -5,35 +5,68 @@ #ifndef BASE_TIMER_MOCK_TIMER_H_ #define BASE_TIMER_MOCK_TIMER_H_ +#include "base/test/simple_test_tick_clock.h" #include "base/timer/timer.h" namespace base { -class BASE_EXPORT MockTimer : public Timer { +class TestSimpleTaskRunner; + +// A mock implementation of base::Timer which requires being explicitly +// Fire()'d. +// Prefer using ScopedTaskEnvironment::MOCK_TIME + FastForward*() to this when +// possible +class MockTimer : public Timer { public: MockTimer(bool retain_user_task, bool is_repeating); - MockTimer(const Location& posted_from, - TimeDelta delay, - const base::Closure& user_task, - bool is_repeating); ~MockTimer() override; - // base::Timer implementation. - bool IsRunning() const override; - base::TimeDelta GetCurrentDelay() const override; - void Start(const Location& posted_from, - base::TimeDelta delay, - const base::Closure& user_task) override; - void Stop() override; - void Reset() override; - - // Testing methods. + // Testing method. void Fire(); private: - base::Closure user_task_; - TimeDelta delay_; - bool is_running_; + // Timer implementation. + // MockTimer doesn't support SetTaskRunner. Do not use this. + void SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner) override; + + SimpleTestTickClock clock_; + scoped_refptr<TestSimpleTaskRunner> test_task_runner_; +}; + +// See MockTimer's comment. Prefer using ScopedTaskEnvironment::MOCK_TIME. +class MockOneShotTimer : public OneShotTimer { + public: + MockOneShotTimer(); + ~MockOneShotTimer() override; + + // Testing method. + void Fire(); + + private: + // Timer implementation. + // MockOneShotTimer doesn't support SetTaskRunner. Do not use this. + void SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner) override; + + SimpleTestTickClock clock_; + scoped_refptr<TestSimpleTaskRunner> test_task_runner_; +}; + +// See MockTimer's comment. Prefer using ScopedTaskEnvironment::MOCK_TIME. +class MockRepeatingTimer : public RepeatingTimer { + public: + MockRepeatingTimer(); + ~MockRepeatingTimer() override; + + // Testing method. + void Fire(); + + private: + // Timer implementation. + // MockRepeatingTimer doesn't support SetTaskRunner. Do not use this. + void SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner) override; + + SimpleTestTickClock clock_; + scoped_refptr<TestSimpleTaskRunner> test_task_runner_; }; } // namespace base
diff --git a/base/timer/timer.h b/base/timer/timer.h index 2777632..2a5c29b 100644 --- a/base/timer/timer.h +++ b/base/timer/timer.h
@@ -106,17 +106,17 @@ virtual ~Timer(); // Returns true if the timer is running (i.e., not stopped). - virtual bool IsRunning() const; + bool IsRunning() const; // Returns the current delay for this timer. - virtual TimeDelta GetCurrentDelay() const; + TimeDelta GetCurrentDelay() const; // Set the task runner on which the task should be scheduled. This method can // only be called before any tasks have been scheduled. If |task_runner| runs // tasks on a different sequence than the sequence owning this Timer, // |user_task_| will be posted to it when the Timer fires (note that this // means |user_task_| can run after ~Timer() and should support that). - void SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner); + virtual void SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner); // Start the timer to run at the given |delay| from now. If the timer is // already running, it will be replaced to call the given |user_task|. @@ -164,9 +164,6 @@ void set_is_running(bool running) { is_running_ = running; } const Location& posted_from() const { return posted_from_; } - bool retain_user_task() const { return retain_user_task_; } - bool is_repeating() const { return is_repeating_; } - bool is_running() const { return is_running_; } private: friend class BaseTimerTaskInternal;
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index 8eb5a0e7..b297d0c 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -643,6 +643,68 @@ } } + # Declare a target for a set of Android resources generated at build + # time and stored in a single zip archive. The content of the archive + # should match the layout of a regular Android res/ folder (but the + # archive should not include a top-level res/ directory). + # + # Note that there is no associated .srcjar, R.txt or package name + # associated with this target. + # + # Variables: + # generated_resources_zip: Generated zip archive path. + # generating_target_name: Name of the target generating + # generated_resources_zip. This rule will check that it is part + # of its outputs. + # deps: Specifies the dependencies of this target. Any Android resources + # listed here will be also be included *after* this one when compiling + # all resources for a final apk or junit binary. This is useful to + # ensure that the resources of the current target override those of the + # dependency as well (and would not work if you have these deps to the + # generating target's dependencies). + # + # Example + # _zip_archive = "$target_gen_dir/${target_name}.resources_zip" + # + # action("my_resources__create_zip") { + # _depfile = "$target_gen_dir/${target_name}.d" + # script = "//build/path/to/create_my_resources_zip.py" + # args = [ + # "--depfile", rebase_path(_depfile, root_build_dir), + # "--output-zip", rebase_path(_zip_archive, root_build_dir), + # ] + # inputs = [] + # outputs = _zip_archive + # depfile = _depfile + # } + # + # android_generated_resources("my_resources") { + # generated_resources_zip = _zip_archive + # generating_target_name = ":my_resources__create_zip" + # } + # + template("android_generated_resources") { + forward_variables_from(invoker, [ "testonly" ]) + + _build_config = "$target_gen_dir/${target_name}.build_config" + + write_build_config("${target_name}__build_config") { + build_config = _build_config + resources_zip = invoker.generated_resources_zip + type = "android_resources" + if (defined(invoker.deps)) { + possible_config_deps = invoker.deps + } + } + + group(target_name) { + public_deps = [ + ":${target_name}__build_config", + invoker.generating_target_name, + ] + } + } + # Declare a target for processing Android resources as Jinja templates. # # This takes an Android resource directory where each resource is a Jinja @@ -671,18 +733,10 @@ # directory or they will not be available to tester bots. _resources_zip_rebased_path = rebase_path(target_gen_dir, root_gen_dir) _resources_zip = "${root_out_dir}/resource_zips/${_resources_zip_rebased_path}/${target_name}.resources.zip" - _build_config = "$target_gen_dir/$target_name.build_config" - write_build_config("${target_name}__build_config") { - build_config = _build_config - resources_zip = _resources_zip - type = "android_resources" - if (defined(invoker.deps)) { - possible_config_deps = invoker.deps - } - } + _generating_target_name = "${target_name}__template" - action("${target_name}__template") { + action(_generating_target_name) { forward_variables_from(invoker, [ "deps" ]) inputs = invoker.resources script = "//build/android/gyp/jinja_template.py" @@ -708,11 +762,10 @@ } } - group(target_name) { - public_deps = [ - ":${target_name}__build_config", - ":${target_name}__template", - ] + android_generated_resources(target_name) { + forward_variables_from(invoker, [ "deps" ]) + generating_target_name = ":$_generating_target_name" + generated_resources_zip = _resources_zip } } @@ -988,13 +1041,6 @@ # directory or they will not be available to tester bots. _resources_zip_rebased_path = rebase_path(target_gen_dir, root_gen_dir) _resources_zip = "${root_out_dir}/resource_zips/${_resources_zip_rebased_path}/${target_name}.resources.zip" - _build_config = "$target_gen_dir/$target_name.build_config" - - write_build_config("${target_name}__build_config") { - type = "android_resources" - build_config = _build_config - resources_zip = _resources_zip - } _grit_target_name = "${target_name}__grit" _grit_output_dir = "$target_gen_dir/${target_name}_grit_output" @@ -1015,7 +1061,9 @@ outputs = invoker.outputs } - zip(target_name) { + _zip_target_name = "${target_name}__zip" + + zip(_zip_target_name) { base_dir = _grit_output_dir # This needs to get outputs from grit's internal target, not the final @@ -1026,6 +1074,11 @@ ":$_grit_target_name", ] } + + android_generated_resources(target_name) { + generating_target_name = ":$_zip_target_name" + generated_resources_zip = _resources_zip + } } # Declare a target that packages strings.xml generated from a grd file. @@ -1051,28 +1104,24 @@ # directory or they will not be available to tester bots. _resources_zip_rebased_path = rebase_path(target_gen_dir, root_gen_dir) _resources_zip = "${root_out_dir}/resource_zips/${_resources_zip_rebased_path}/${target_name}.resources.zip" - _build_config = "$target_gen_dir/$target_name.build_config" - _build_config_target_name = "${target_name}__build_config" - write_build_config(_build_config_target_name) { - type = "android_resources" - build_config = _build_config - resources_zip = _resources_zip - } + _zip_target_name = "${target_name}__zip" - zip(target_name) { + zip(_zip_target_name) { forward_variables_from(invoker, [ "visibility" ]) base_dir = invoker.grit_output_dir inputs = rebase_path(invoker.generated_files, ".", base_dir) output = _resources_zip - deps = [ - ":$_build_config_target_name", - ] if (defined(invoker.deps)) { - deps += invoker.deps + deps = invoker.deps } } + + android_generated_resources(target_name) { + generating_target_name = ":$_zip_target_name" + generated_resources_zip = _resources_zip + } } # Declare a Java executable target
diff --git a/build/fuchsia/sdk.sha1 b/build/fuchsia/sdk.sha1 index a35bcfb7..1a40548 100644 --- a/build/fuchsia/sdk.sha1 +++ b/build/fuchsia/sdk.sha1
@@ -1 +1 @@ -f39463541d7a9e067646a77d44d72631848c7ecf \ No newline at end of file +195b24ffb560cbbbba41dadbe3a6710dd58d02af \ No newline at end of file
diff --git a/cc/layers/surface_layer_impl.cc b/cc/layers/surface_layer_impl.cc index def52815..366bc02 100644 --- a/cc/layers/surface_layer_impl.cc +++ b/cc/layers/surface_layer_impl.cc
@@ -127,12 +127,8 @@ if (visible_quad_rect.IsEmpty()) return nullptr; - // If a |common_shared_quad_state| is provided then use that. Otherwise, - // allocate a new SharedQuadState. Assign the new SharedQuadState to - // *|common_shared_quad_state| so that it may be reused by another emitted - // viz::SurfaceDrawQuad. viz::SharedQuadState* shared_quad_state = - shared_quad_state = render_pass->CreateAndAppendSharedQuadState(); + render_pass->CreateAndAppendSharedQuadState(); PopulateScaledSharedQuadState(shared_quad_state, device_scale_factor, device_scale_factor, contents_opaque());
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 5e5da00e..5d327b9 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -189,6 +189,17 @@ ] } +android_aidl("cct_dynamic_module_aidl") { + import_include = [ "java/src" ] + sources = [ + "java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/IActivityDelegate.aidl", + "java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/IActivityHost.aidl", + "java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/IModuleEntryPoint.aidl", + "java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/IModuleHost.aidl", + "java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/IObjectWrapper.aidl", + ] +} + android_library("chrome_java") { deps = [ ":chrome_java_resources", @@ -292,6 +303,7 @@ ":chrome_android_java_enums_srcjar", ":chrome_android_java_google_api_keys_srcjar", ":chrome_version_srcjar", + ":cct_dynamic_module_aidl", ":photo_picker_aidl", ":resource_id_javagen", "//chrome:assist_ranker_prediction_enum_javagen",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java index 67821c1e..f5d4c87 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
@@ -157,6 +157,7 @@ public static final String CAF_MEDIA_ROUTER_IMPL = "CafMediaRouterImpl"; public static final String CAPTIVE_PORTAL_CERTIFICATE_LIST = "CaptivePortalCertificateList"; public static final String CCT_BACKGROUND_TAB = "CCTBackgroundTab"; + public static final String CCT_MODULE = "CCTModule"; public static final String CCT_EXTERNAL_LINK_HANDLING = "CCTExternalLinkHandling"; public static final String CCT_PARALLEL_REQUEST = "CCTParallelRequest"; public static final String CCT_POST_MESSAGE_API = "CCTPostMessageAPI";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java index ec08a2af1..87d494e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
@@ -59,7 +59,11 @@ import org.chromium.chrome.browser.browserservices.BrowserSessionContentHandler; import org.chromium.chrome.browser.browserservices.BrowserSessionContentUtils; import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.customtabs.dynamicmodule.ActivityDelegate; +import org.chromium.chrome.browser.customtabs.dynamicmodule.ActivityHostImpl; +import org.chromium.chrome.browser.customtabs.dynamicmodule.ModuleEntryPoint; import org.chromium.chrome.browser.datausage.DataUseTabUIManager; +import org.chromium.chrome.browser.externalauth.ExternalAuthUtils; import org.chromium.chrome.browser.externalnav.ExternalNavigationDelegateImpl; import org.chromium.chrome.browser.firstrun.FirstRunSignInProcessor; import org.chromium.chrome.browser.fullscreen.BrowserStateBrowserControlsVisibilityDelegate; @@ -153,6 +157,8 @@ private WebappCustomTabTimeSpentLogger mWebappTimeSpentLogger; + @Nullable private ActivityDelegate mActivityDelegate; + private static class PageLoadMetricsObserver implements PageLoadMetrics.Observer { private final CustomTabsConnection mConnection; private final CustomTabsSessionToken mSession; @@ -338,6 +344,39 @@ } } + /** + * Dynamically loads a module using the package and class names specified in the intent, if it + * is not loaded yet. + */ + private void maybeLoadModule() { + // TODO(https://crbug.com/853728): Load the module in the background. + if (!ChromeFeatureList.isEnabled(ChromeFeatureList.CCT_MODULE)) { + Log.w(TAG, "The %s feature is disabled.", ChromeFeatureList.CCT_MODULE); + return; + } + + String packageName = mIntentDataProvider.getModulePackageName(); + if (!ExternalAuthUtils.getInstance().isGoogleSigned(packageName)) { + Log.w(TAG, "The %s package is not Google-signed.", packageName); + return; + } + + ModuleEntryPoint entryPoint = + mConnection.loadModule(packageName, mIntentDataProvider.getModuleClassName()); + if (entryPoint == null) return; + + mActivityDelegate = entryPoint.createActivityDelegate(new ActivityHostImpl(this)); + mActivityDelegate.onCreate(getSavedInstanceState()); + if (mBottomBarDelegate != null) { + mBottomBarDelegate.setBottomBarContentView(mActivityDelegate.getBottomBarView()); + mBottomBarDelegate.showBottomBarIfNecessary(); + } + + ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); + addContentView(mActivityDelegate.getOverlayView(), layoutParams); + } + @Override public boolean shouldAllocateChildConnection() { return !mHasCreatedTabEarly && !mHasSpeculated @@ -539,6 +578,9 @@ return entry != null ? entry.getUrl() : null; } }; + + maybeLoadModule(); + recordClientPackageName(); mConnection.showSignInToastIfNecessary(mSession, getIntent()); String url = getUrlToLoad(); @@ -704,6 +746,11 @@ super.onStartWithNative(); BrowserSessionContentUtils.setActiveContentHandler(mBrowserSessionContentHandler); if (mHasCreatedTabEarly && !mMainTab.isLoading()) postDeferredStartupIfNeeded(); + if (mActivityDelegate != null) { + mActivityDelegate.onStart(); + mActivityDelegate.onRestoreInstanceState(getSavedInstanceState()); + mActivityDelegate.onPostCreate(getSavedInstanceState()); + } } @Override @@ -739,6 +786,7 @@ mWebappTimeSpentLogger = WebappCustomTabTimeSpentLogger.createInstanceAndStartTimer( getIntent().getIntExtra(CustomTabIntentDataProvider.EXTRA_BROWSER_LAUNCH_SOURCE, ACTIVITY_TYPE_OTHER)); + if (mActivityDelegate != null) mActivityDelegate.onResume(); } @Override @@ -747,12 +795,14 @@ if (mWebappTimeSpentLogger != null) { mWebappTimeSpentLogger.onPause(); } + if (mActivityDelegate != null) mActivityDelegate.onPause(isChangingConfigurations()); } @Override public void onStopWithNative() { super.onStopWithNative(); BrowserSessionContentUtils.setActiveContentHandler(null); + if (mActivityDelegate != null) mActivityDelegate.onStop(isChangingConfigurations()); if (mIsClosing) { getTabModelSelector().closeAllTabs(true); mTabPersistencePolicy.deleteMetadataStateFileAsync(); @@ -761,6 +811,24 @@ } } + @Override + protected void onDestroyInternal() { + super.onDestroyInternal(); + if (mActivityDelegate != null) mActivityDelegate.onDestroy(isChangingConfigurations()); + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + if (mActivityDelegate != null) mActivityDelegate.onSaveInstanceState(outState); + } + + @Override + public void onWindowFocusChanged(boolean hasFocus) { + super.onWindowFocusChanged(hasFocus); + if (mActivityDelegate != null) mActivityDelegate.onWindowFocusChanged(hasFocus); + } + /** * Loads the current tab with the given load params while taking client * referrer and extra headers into account. @@ -928,6 +996,8 @@ if (exitFullscreenIfShowing()) return true; + if (mActivityDelegate != null && mActivityDelegate.onBackPressed()) return true; + if (!getToolbarManager().back()) { if (getCurrentTabModel().getCount() > 1) { getCurrentTabModel().closeTab(getActivityTab(), false, false, false);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java index 02176f4..fa8b78c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java
@@ -48,6 +48,7 @@ private ChromeActivity mActivity; private ChromeFullscreenManager mFullscreenManager; private ViewGroup mBottomBarView; + @Nullable private View mBottomBarContentView; private CustomTabIntentDataProvider mDataProvider; private PendingIntent mClickPendingIntent; private int[] mClickableIDs; @@ -74,7 +75,12 @@ * Makes the bottom bar area to show, if any. */ public void showBottomBarIfNecessary() { - if (!mDataProvider.shouldShowBottomBar()) return; + if (!shouldShowBottomBar()) return; + + if (mBottomBarContentView != null) { + getBottomBarView().addView(mBottomBarContentView); + return; + } RemoteViews remoteViews = mDataProvider.getBottomBarRemoteViews(); if (remoteViews != null) { @@ -140,10 +146,17 @@ } /** + * Sets the content of the bottom bar. + */ + public void setBottomBarContentView(View view) { + mBottomBarContentView = view; + } + + /** * @return The height of the bottom bar, excluding its top shadow. */ public int getBottomBarHeight() { - if (!mDataProvider.shouldShowBottomBar() || mBottomBarView == null + if (!shouldShowBottomBar() || mBottomBarView == null || mBottomBarView.getChildCount() < 2) { return 0; } @@ -244,6 +257,10 @@ } } + private boolean shouldShowBottomBar() { + return mBottomBarContentView != null || mDataProvider.shouldShowBottomBar(); + } + // FullscreenListener methods @Override public void onControlsOffsetChanged(float topOffset, float bottomOffset,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java index e5816746..1c264dc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
@@ -15,6 +15,7 @@ import android.net.Uri; import android.os.Bundle; import android.support.annotation.IntDef; +import android.support.annotation.Nullable; import android.support.customtabs.CustomTabsIntent; import android.text.TextUtils; import android.util.Pair; @@ -106,6 +107,14 @@ public static final String EXTRA_SEND_TO_EXTERNAL_DEFAULT_HANDLER = "android.support.customtabs.extra.SEND_TO_EXTERNAL_HANDLER"; + /** The APK package to load the module from. */ + private static final String EXTRA_MODULE_PACKAGE_NAME = + "org.chromium.chrome.browser.customtabs.EXTRA_MODULE_PACKAGE_NAME"; + + /** The class name of the module entry point. */ + private static final String EXTRA_MODULE_CLASS_NAME = + "org.chromium.chrome.browser.customtabs.EXTRA_MODULE_CLASS_NAME"; + private static final int MAX_CUSTOM_MENU_ITEMS = 5; private static final int MAX_CUSTOM_TOOLBAR_ITEMS = 2; @@ -122,6 +131,8 @@ private final int mInitialBackgroundColor; private final boolean mDisableStar; private final boolean mDisableDownload; + @Nullable private final String mModulePackageName; + @Nullable private final String mModuleClassName; private int mToolbarColor; private int mBottomBarColor; @@ -232,6 +243,8 @@ mDisableStar = IntentUtils.safeGetBooleanExtra(intent, EXTRA_DISABLE_STAR_BUTTON, false); mDisableDownload = IntentUtils.safeGetBooleanExtra(intent, EXTRA_DISABLE_DOWNLOAD_BUTTON, false); + mModulePackageName = IntentUtils.safeGetStringExtra(intent, EXTRA_MODULE_PACKAGE_NAME); + mModuleClassName = IntentUtils.safeGetStringExtra(intent, EXTRA_MODULE_CLASS_NAME); } /** @@ -594,4 +607,20 @@ // Only open custom tab in incognito mode for payment request. return isTrustedIntent() && mIsOpenedByChrome && isForPaymentRequest() && mIsIncognito; } + + /** + * @return The APK package to load the module from, or null if not specified. + */ + @Nullable + String getModulePackageName() { + return mModulePackageName; + } + + /** + * @return The class name of the module entry point, or null if not specified. + */ + @Nullable + String getModuleClassName() { + return mModuleClassName; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java index ba42faf..0c40540 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java
@@ -23,6 +23,7 @@ import android.support.customtabs.CustomTabsService; import android.support.customtabs.CustomTabsSessionToken; import android.text.TextUtils; +import android.util.Pair; import android.widget.RemoteViews; import org.json.JSONException; @@ -52,6 +53,8 @@ import org.chromium.chrome.browser.browserservices.BrowserSessionContentUtils; import org.chromium.chrome.browser.browserservices.Origin; import org.chromium.chrome.browser.browserservices.PostMessageHandler; +import org.chromium.chrome.browser.customtabs.dynamicmodule.ModuleEntryPoint; +import org.chromium.chrome.browser.customtabs.dynamicmodule.ModuleLoader; import org.chromium.chrome.browser.device.DeviceClassManager; import org.chromium.chrome.browser.init.ChainedTasks; import org.chromium.chrome.browser.init.ChromeBrowserInitializer; @@ -230,6 +233,12 @@ private volatile ChainedTasks mWarmupTasks; + /** The module package name and class name. */ + private Pair<String, String> mModuleNames; + + /** The module entry point. */ + private ModuleEntryPoint mModuleEntryPoint; + /** * <strong>DO NOT CALL</strong> * Public to be instanciable from {@link ChromeApplication}. This is however @@ -1408,4 +1417,27 @@ private static native void nativeCreateAndStartDetachedResourceRequest( Profile profile, String url, String origin, @WebReferrerPolicy int referrerPolicy); + + /** + * Dynamically loads the class {@code className} from the application identified by + * {@code packageName} and wraps it in a {@link ModuleEntryPoint}. + * @param packageName The package name of the application to load form. + * @param className The fully-qualified name of the class to load. + * @return The loaded class, cast to an AIDL interface and wrapped in a more user friendly form. + */ + @Nullable + public ModuleEntryPoint loadModule(String packageName, String className) { + if (mModuleEntryPoint != null && mModuleNames != null) { + if ((!mModuleNames.first.equals(packageName) + || !mModuleNames.second.equals(className))) { + throw new IllegalStateException("Only one module can be loaded at a time."); + } + return mModuleEntryPoint; + } + + // TODO(https://crbug.com/853732): Add cleanup mechanism to unload the module. + mModuleNames = new Pair<>(packageName, className); + mModuleEntryPoint = ModuleLoader.loadModule(packageName, className); + return mModuleEntryPoint; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ActivityDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ActivityDelegate.java new file mode 100644 index 0000000..5f3433f --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ActivityDelegate.java
@@ -0,0 +1,129 @@ +// Copyright 2018 The Chromium 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.customtabs.dynamicmodule; + +import android.os.Bundle; +import android.os.RemoteException; +import android.view.View; + +/** + * A wrapper around a {@link IActivityDelegate}. + * + * No {@link RemoteException} should ever be thrown as all of this code runs in the same process. + */ +public class ActivityDelegate { + private final IActivityDelegate mActivityDelegate; + + public ActivityDelegate(IActivityDelegate activityDelegate) { + mActivityDelegate = activityDelegate; + } + + public void onCreate(Bundle savedInstanceState) { + try { + mActivityDelegate.onCreate(savedInstanceState); + } catch (RemoteException e) { + assert false; + } + } + + public void onPostCreate(Bundle savedInstanceState) { + try { + mActivityDelegate.onPostCreate(savedInstanceState); + } catch (RemoteException e) { + assert false; + } + } + + public void onStart() { + try { + mActivityDelegate.onStart(); + } catch (RemoteException e) { + assert false; + } + } + + public void onStop(boolean isChangingConfigurations) { + try { + mActivityDelegate.onStop(isChangingConfigurations); + } catch (RemoteException e) { + assert false; + } + } + + public void onWindowFocusChanged(boolean hasFocus) { + try { + mActivityDelegate.onWindowFocusChanged(hasFocus); + } catch (RemoteException e) { + assert false; + } + } + + public void onSaveInstanceState(Bundle outState) { + try { + mActivityDelegate.onSaveInstanceState(outState); + } catch (RemoteException e) { + assert false; + } + } + + public void onRestoreInstanceState(Bundle savedInstanceState) { + try { + mActivityDelegate.onRestoreInstanceState(savedInstanceState); + } catch (RemoteException e) { + assert false; + } + } + + public void onResume() { + try { + mActivityDelegate.onResume(); + } catch (RemoteException e) { + assert false; + } + } + + public void onPause(boolean isChangingConfigurations) { + try { + mActivityDelegate.onPause(isChangingConfigurations); + } catch (RemoteException e) { + assert false; + } + } + + public void onDestroy(boolean isChangingConfigurations) { + try { + mActivityDelegate.onDestroy(isChangingConfigurations); + } catch (RemoteException e) { + assert false; + } + } + + public boolean onBackPressed() { + try { + return mActivityDelegate.onBackPressed(); + } catch (RemoteException e) { + assert false; + } + return false; + } + + public View getBottomBarView() { + try { + return ObjectWrapper.unwrap(mActivityDelegate.getBottomBarView(), View.class); + } catch (RemoteException e) { + assert false; + } + return null; + } + + public View getOverlayView() { + try { + return ObjectWrapper.unwrap(mActivityDelegate.getOverlayView(), View.class); + } catch (RemoteException e) { + assert false; + } + return null; + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ActivityHostImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ActivityHostImpl.java new file mode 100644 index 0000000..4e58178 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ActivityHostImpl.java
@@ -0,0 +1,23 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.customtabs.dynamicmodule; + +import android.content.Context; + +/** + * The implementation of {@link IActivityHost}. + */ +public class ActivityHostImpl extends IActivityHost.Stub { + private final Context mActivityContext; + + public ActivityHostImpl(Context activityContext) { + mActivityContext = activityContext; + } + + @Override + public IObjectWrapper getActivityContext() { + return ObjectWrapper.wrap(mActivityContext); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/IActivityDelegate.aidl b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/IActivityDelegate.aidl new file mode 100644 index 0000000..0921ad7 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/IActivityDelegate.aidl
@@ -0,0 +1,35 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.customtabs.dynamicmodule; + +import org.chromium.chrome.browser.customtabs.dynamicmodule.IObjectWrapper; + +interface IActivityDelegate { + void onCreate(in Bundle savedInstanceState) = 0; + + void onPostCreate(in Bundle savedInstanceState) = 1; + + void onStart() = 2; + + void onStop(boolean isChangingConfigurations) = 3; + + void onWindowFocusChanged(boolean hasFocus) = 4; + + void onSaveInstanceState(in Bundle outState) = 5; + + void onRestoreInstanceState(in Bundle savedInstanceState) = 6; + + void onResume() = 7; + + void onPause(boolean isChangingConfigurations) = 8; + + void onDestroy(boolean isChangingConfigurations) = 9; + + boolean onBackPressed() = 10; + + IObjectWrapper /* View */ getBottomBarView() = 11; + + IObjectWrapper /* View */ getOverlayView() = 12; +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/IActivityHost.aidl b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/IActivityHost.aidl new file mode 100644 index 0000000..ca84c93 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/IActivityHost.aidl
@@ -0,0 +1,11 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.customtabs.dynamicmodule; + +import org.chromium.chrome.browser.customtabs.dynamicmodule.IObjectWrapper; + +interface IActivityHost { + IObjectWrapper /* Context */ getActivityContext() = 0; +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/IModuleEntryPoint.aidl b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/IModuleEntryPoint.aidl new file mode 100644 index 0000000..79516d37a --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/IModuleEntryPoint.aidl
@@ -0,0 +1,16 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.customtabs.dynamicmodule; + +import org.chromium.chrome.browser.customtabs.dynamicmodule.IActivityDelegate; +import org.chromium.chrome.browser.customtabs.dynamicmodule.IActivityHost; +import org.chromium.chrome.browser.customtabs.dynamicmodule.IModuleHost; + +interface IModuleEntryPoint { + void init(in IModuleHost moduleHost) = 0; + IActivityDelegate createActivityDelegate(in IActivityHost activityHost) = 1; + int getVersion() = 2; + int getMinimumHostVersion() = 3; +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/IModuleHost.aidl b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/IModuleHost.aidl new file mode 100644 index 0000000..5c7afd09 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/IModuleHost.aidl
@@ -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. + +package org.chromium.chrome.browser.customtabs.dynamicmodule; + +import org.chromium.chrome.browser.customtabs.dynamicmodule.IObjectWrapper; + +interface IModuleHost { + IObjectWrapper /* Context */ getHostApplicationContext() = 0; + IObjectWrapper /* Context */ getModuleContext() = 1; + int getVersion() = 2; + int getMinimumModuleVersion() = 3; +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/IObjectWrapper.aidl b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/IObjectWrapper.aidl new file mode 100644 index 0000000..fc904ff --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/IObjectWrapper.aidl
@@ -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. + +package org.chromium.chrome.browser.customtabs.dynamicmodule; + +/** + * This interface intentionally has no methods, and instances of this should + * be created from class ObjectWrapper only. This is used as a way of passing + * objects that descend from the system classes via AIDL across classloaders + * without serializing them. + */ +interface IObjectWrapper { +} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleEntryPoint.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleEntryPoint.java new file mode 100644 index 0000000..d3041af0 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleEntryPoint.java
@@ -0,0 +1,55 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.customtabs.dynamicmodule; + +import android.os.RemoteException; + +/** + * A wrapper around a {@link IModuleEntryPoint}. + * + * No {@link RemoteException} should ever be thrown as all of this code runs in the same process. + */ +public class ModuleEntryPoint { + private final IModuleEntryPoint mEntryPoint; + + public ModuleEntryPoint(IModuleEntryPoint entryPoint) { + mEntryPoint = entryPoint; + } + + public void init(ModuleHostImpl moduleHost) { + try { + mEntryPoint.init(moduleHost); + } catch (RemoteException e) { + assert false; + } + } + + public ActivityDelegate createActivityDelegate(ActivityHostImpl activityHost) { + try { + return new ActivityDelegate(mEntryPoint.createActivityDelegate(activityHost)); + } catch (RemoteException e) { + assert false; + } + return null; + } + + public int getVersion() { + try { + return mEntryPoint.getVersion(); + } catch (RemoteException e) { + assert false; + } + return -1; + } + + public int getMinimumHostVersion() { + try { + return mEntryPoint.getMinimumHostVersion(); + } catch (RemoteException e) { + assert false; + } + return -1; + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleHostImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleHostImpl.java new file mode 100644 index 0000000..5bfdb5b4d --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleHostImpl.java
@@ -0,0 +1,43 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.customtabs.dynamicmodule; + +import android.content.Context; + +/** + * The implementation of {@link IModuleHost}. + */ +public class ModuleHostImpl extends IModuleHost.Stub { + private static final int VERSION = 1; + private static final int MINIMUM_MODULE_VERSION = 1; + + private final Context mApplicationContext; + private final Context mModuleContext; + + public ModuleHostImpl(Context applicationContext, Context moduleContext) { + mApplicationContext = applicationContext; + mModuleContext = moduleContext; + } + + @Override + public IObjectWrapper getHostApplicationContext() { + return ObjectWrapper.wrap(mApplicationContext); + } + + @Override + public IObjectWrapper getModuleContext() { + return ObjectWrapper.wrap(mModuleContext); + } + + @Override + public int getVersion() { + return VERSION; + } + + @Override + public int getMinimumModuleVersion() { + return MINIMUM_MODULE_VERSION; + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleLoader.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleLoader.java new file mode 100644 index 0000000..07db661 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleLoader.java
@@ -0,0 +1,83 @@ +// Copyright 2018 The Chromium 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.customtabs.dynamicmodule; + +import android.content.Context; +import android.content.pm.PackageManager; +import android.os.IBinder; +import android.support.annotation.Nullable; + +import org.chromium.base.ContextUtils; +import org.chromium.base.Log; + +/** + * Dynamically loads a module from another apk. + */ +public final class ModuleLoader { + private static final String TAG = "ModuleLoader"; + + private ModuleLoader() {} + + /** + * Dynamically loads the class {@code className} from the application identified by + * {@code packageName} and wraps it in a {@link ModuleEntryPoint}. + * @param packageName The package name of the application to load form. + * @param className The name of the class to load, in the form of a binary name (including the + * class package name). + * @return The loaded class, cast to an AIDL interface and wrapped in a more user friendly form. + */ + @Nullable + public static ModuleEntryPoint loadModule(String packageName, String className) { + Context applicationContext = ContextUtils.getApplicationContext(); + Context moduleContext = getModuleContext(applicationContext, packageName); + + if (moduleContext == null) return null; + + try { + Class<?> clazz = moduleContext.getClassLoader().loadClass(className); + + IBinder binder = (IBinder) clazz.newInstance(); + + ModuleHostImpl moduleHost = new ModuleHostImpl(applicationContext, moduleContext); + ModuleEntryPoint entryPoint = + new ModuleEntryPoint(IModuleEntryPoint.Stub.asInterface(binder)); + + if (!isCompatible(moduleHost, entryPoint)) { + Log.w(TAG, "Incompatible module due to version mismatch: host version %s, " + + "minimum required host version %s, entry point version %s, minimum " + + "required entry point version %s.", + moduleHost.getVersion(), entryPoint.getMinimumHostVersion(), + entryPoint.getVersion(), moduleHost.getMinimumModuleVersion()); + return null; + } + + entryPoint.init(moduleHost); + return entryPoint; + } catch (Exception e) { // No multi-catch below API level 19 for reflection exceptions. + Log.e(TAG, "Could not create entry point using package name %s and class name %s", + packageName, className, e); + } + return null; + } + + @Nullable + private static Context getModuleContext(Context applicationContext, String packageName) { + try { + // The flags Context.CONTEXT_INCLUDE_CODE and Context.CONTEXT_IGNORE_SECURITY are + // needed to be able to load classes via the classloader of the returned context. + Context moduleContext = applicationContext.createPackageContext( + packageName, Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY); + return moduleContext; + } catch (PackageManager.NameNotFoundException e) { + Log.e(TAG, "Could not create package context for %s", packageName, e); + } + return null; + } + + private static boolean isCompatible(ModuleHostImpl moduleHost, ModuleEntryPoint entryPoint) { + return entryPoint.getVersion() >= moduleHost.getMinimumModuleVersion() + && moduleHost.getVersion() >= entryPoint.getMinimumHostVersion(); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/OWNERS new file mode 100644 index 0000000..8f094e0 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/OWNERS
@@ -0,0 +1,2 @@ +per-file *.aidl=set noparent +per-file *.aidl=file://ipc/SECURITY_OWNERS
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ObjectWrapper.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ObjectWrapper.java new file mode 100644 index 0000000..7f7b4b2f6 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ObjectWrapper.java
@@ -0,0 +1,104 @@ +// Copyright 2018 The Chromium 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.customtabs.dynamicmodule; + +import android.os.IBinder; +import android.support.annotation.Nullable; + +import java.lang.reflect.Field; + +/** + * This wraps an object to be transferred across sibling classloaders in the same process via the + * IObjectWrapper AIDL interface. By using reflection to retrieve the object, no serialization needs + * to occur. + * + * @param <T> The type of the wrapped object. + */ +public final class ObjectWrapper<T> extends IObjectWrapper.Stub { + /** + * The wrapped object. You must not add another member in this class because the check for + * retrieving this member variable is that this is the ONLY member variable declared in this + * class and it is private. This is because ObjectWrapper can be obfuscated, so that this member + * variable can have an obfuscated name. + */ + private final T mWrappedObject; + + /* DO NOT ADD NEW CLASS MEMBERS (see above) */ + + /** Disable creating an object wrapper. Instead, use {@link #wrap(Object)}. */ + private ObjectWrapper(T object) { + mWrappedObject = object; + } + + /** + * Create the wrapped object. + * + * @param object The object instance to wrap. + * @return The wrapped object. + */ + public static <T> IObjectWrapper wrap(T object) { + return new ObjectWrapper<T>(object); + } + + /** + * Unwrap the object within the {@link IObjectWrapper} using reflection. + * + * @param remote The {@link IObjectWrapper} instance to unwrap. + * @param clazz The {@link Class} of the unwrapped object type. + * @return The unwrapped object. + */ + @Nullable + public static <T> T unwrap(@Nullable IObjectWrapper remote, Class<T> clazz) { + if (remote == null) return null; + + // Handle the case when not getting an IObjectWrapper from a sibling classloader + if (remote instanceof ObjectWrapper) { + @SuppressWarnings("unchecked") + ObjectWrapper<T> typedRemote = ((ObjectWrapper<T>) remote); + return typedRemote.mWrappedObject; + } + + IBinder remoteBinder = remote.asBinder(); + + // It is possible that ObjectWrapper was obfuscated in which case wrappedObject + // would have a different name. The following checks that there is a single + // declared field that is private. + Class<?> remoteClazz = remoteBinder.getClass(); + + Field validField = null; + for (Field field : remoteClazz.getDeclaredFields()) { + if (field.isSynthetic()) continue; + + // Only one valid, non-synthetic field is allowed on the class. + if (validField != null) { + validField = null; + break; + } + validField = field; + } + + if (validField == null || validField.isAccessible()) { + throw new IllegalArgumentException("The concrete class implementing IObjectWrapper" + + " must have exactly *one* declared *private* field for the wrapped object. " + + " Preferably, this is an instance of the ObjectWrapper<T> class."); + } + + validField.setAccessible(true); + try { + Object wrappedObject = validField.get(remoteBinder); + if (wrappedObject == null) return null; + if (!clazz.isInstance(wrappedObject)) { + throw new IllegalArgumentException("remoteBinder is the wrong class."); + } + return clazz.cast(wrappedObject); + } catch (NullPointerException e) { + throw new IllegalArgumentException("Binder object is null.", e); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("remoteBinder is the wrong class.", e); + } catch (IllegalAccessException e) { + throw new IllegalArgumentException("Could not access the field in remoteBinder.", e); + } + } +}
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 4695bb4..a9458da 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -364,8 +364,8 @@ "java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java", "java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnectionService.java", "java/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistencePolicy.java", - "java/src/org/chromium/chrome/browser/customtabs/RequestThrottler.java", "java/src/org/chromium/chrome/browser/customtabs/NavigationInfoCaptureTrigger.java", + "java/src/org/chromium/chrome/browser/customtabs/RequestThrottler.java", "java/src/org/chromium/chrome/browser/customtabs/SeparateTaskCustomTabActivity.java", "java/src/org/chromium/chrome/browser/customtabs/SeparateTaskCustomTabActivity0.java", "java/src/org/chromium/chrome/browser/customtabs/SeparateTaskCustomTabActivity1.java", @@ -378,6 +378,12 @@ "java/src/org/chromium/chrome/browser/customtabs/SeparateTaskCustomTabActivity8.java", "java/src/org/chromium/chrome/browser/customtabs/SeparateTaskCustomTabActivity9.java", "java/src/org/chromium/chrome/browser/customtabs/SeparateTaskManagedCustomTabActivity.java", + "java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ActivityDelegate.java", + "java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ActivityHostImpl.java", + "java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleEntryPoint.java", + "java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleHostImpl.java", + "java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleLoader.java", + "java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ObjectWrapper.java", "java/src/org/chromium/chrome/browser/database/SQLiteCursor.java", "java/src/org/chromium/chrome/browser/datausage/DataUseTabUIManager.java", "java/src/org/chromium/chrome/browser/datausage/ExternalDataUseObserver.java",
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 16eae040..daba763 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -5161,6 +5161,10 @@ Stop plugin </message> + <message name="IDS_BROWSER_BLOATED_RENDERER_INFOBAR" desc="The text of the infobar notifying the user that the page ran out of memory"> + The web page was reloaded because it ran out of memory. + </message> + <!-- Passwords and Exceptions Dialog --> <message name="IDS_PASSWORDS_EXCEPTIONS_WINDOW_TITLE" desc="Title for 'Passwords and exceptions dialog'"> Passwords @@ -10540,6 +10544,21 @@ <message name="IDS_WEBAUTHN_DIALOG_DESCRIPTION" desc="Contents of the dialog shown when a web site wants to register/verify a user's security key through the Web Authentication API."> The site wants to verify your Security Key for added security for your account. </message> + <message name="IDS_WEBAUTHN_TRANSPORT_BLE" desc="Use a Security Key with the Web Authentication API over Bluetooth Low Energy."> + Use your Security Key with Bluetooth + </message> + <message name="IDS_WEBAUTHN_TRANSPORT_USB" desc="Use a Security Key with the Web Authentication API over Universal Serial Bus (USB)."> + Use your Security Key with USB + </message> + <message name="IDS_WEBAUTHN_TRANSPORT_NFC" desc="Use a Security Key with the Web Authentication API over Near-Field Communication (NFC)."> + Use your Security Key with NFC + </message> + <message name="IDS_WEBAUTHN_TRANSPORT_INTERNAL" desc="Use a Security Key with the Web Authentication API that is built in to the platform, such as Touch ID or Face ID."> + Use a built-in Security Key + </message> + <message name="IDS_WEBAUTHN_TRANSPORT_CABLE" desc="Use a phone as a Security Key over cloud-assisted BLE with the Web Authentication API."> + Use your phone as a Security Key + </message> </messages> </release> </grit>
diff --git a/chrome/app/vector_icons/BUILD.gn b/chrome/app/vector_icons/BUILD.gn index 8506565..3f1eb7c4 100644 --- a/chrome/app/vector_icons/BUILD.gn +++ b/chrome/app/vector_icons/BUILD.gn
@@ -18,6 +18,7 @@ "apps.icon", "blocked_badge.icon", "blocked_redirect.icon", + "bluetooth.icon", "browser_tools.icon", "browser_tools_animated.icon", "browser_tools_error.icon", @@ -47,6 +48,7 @@ "extension_crashed.icon", "file_download.icon", "file_download_shelf.icon", + "fingerprint.icon", "folder.icon", "folder_supervised.icon", "forward_arrow_touch.icon", @@ -66,6 +68,7 @@ "navigate_stop_touch.icon", "new_tab_button_incognito.icon", "new_tab_button_plus.icon", + "nfc.icon", "overflow_chevron.icon", "page_info_content_paste.icon", "paintbrush.icon",
diff --git a/chrome/app/vector_icons/bluetooth.icon b/chrome/app/vector_icons/bluetooth.icon new file mode 100644 index 0000000..2155aa1 --- /dev/null +++ b/chrome/app/vector_icons/bluetooth.icon
@@ -0,0 +1,31 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +CANVAS_DIMENSIONS, 24, +MOVE_TO, 17.71f, 7.71f, +LINE_TO, 12, 2, +R_H_LINE_TO, -1, +R_V_LINE_TO, 7.59f, +LINE_TO, 6.41f, 5, +LINE_TO, 5, 6.41f, +LINE_TO, 10.59f, 12, +LINE_TO, 5, 17.59f, +LINE_TO, 6.41f, 19, +LINE_TO, 11, 14.41f, +V_LINE_TO, 22, +R_H_LINE_TO, 1, +R_LINE_TO, 5.71f, -5.71f, +R_LINE_TO, -4.3f, -4.29f, +R_LINE_TO, 4.3f, -4.29f, +CLOSE, +MOVE_TO, 13, 5.83f, +R_LINE_TO, 1.88f, 1.88f, +LINE_TO, 13, 9.59f, +V_LINE_TO, 5.83f, +CLOSE, +R_MOVE_TO, 1.88f, 10.46f, +LINE_TO, 13, 18.17f, +R_V_LINE_TO, -3.76f, +R_LINE_TO, 1.88f, 1.88f, +CLOSE
diff --git a/chrome/app/vector_icons/fingerprint.icon b/chrome/app/vector_icons/fingerprint.icon new file mode 100644 index 0000000..8fee946 --- /dev/null +++ b/chrome/app/vector_icons/fingerprint.icon
@@ -0,0 +1,83 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +CANVAS_DIMENSIONS, 24, +MOVE_TO, 17.81f, 4.47f, +R_CUBIC_TO, -0.08f, 0, -0.16f, -0.02f, -0.23f, -0.06f, +CUBIC_TO, 15.66f, 3.42f, 14, 3, 12.01f, 3, +R_CUBIC_TO, -1.98f, 0, -3.86f, 0.47f, -5.57f, 1.41f, +R_CUBIC_TO, -0.24f, 0.13f, -0.54f, 0.04f, -0.68f, -0.2f, +R_CUBIC_TO, -0.13f, -0.24f, -0.04f, -0.55f, 0.2f, -0.68f, +CUBIC_TO, 7.82f, 2.52f, 9.86f, 2, 12.01f, 2, +R_CUBIC_TO, 2.13f, 0, 3.99f, 0.47f, 6.03f, 1.52f, +R_CUBIC_TO, 0.25f, 0.13f, 0.34f, 0.43f, 0.21f, 0.67f, +R_CUBIC_TO, -0.09f, 0.18f, -0.26f, 0.28f, -0.44f, 0.28f, +CLOSE, +MOVE_TO, 3.5f, 9.72f, +R_CUBIC_TO, -0.1f, 0, -0.2f, -0.03f, -0.29f, -0.09f, +R_CUBIC_TO, -0.23f, -0.16f, -0.28f, -0.47f, -0.12f, -0.7f, +R_CUBIC_TO, 0.99f, -1.4f, 2.25f, -2.5f, 3.75f, -3.27f, +CUBIC_TO, 9.98f, 4.04f, 14, 4.03f, 17.15f, 5.65f, +R_CUBIC_TO, 1.5f, 0.77f, 2.76f, 1.86f, 3.75f, 3.25f, +R_CUBIC_TO, 0.16f, 0.22f, 0.11f, 0.54f, -0.12f, 0.7f, +R_CUBIC_TO, -0.23f, 0.16f, -0.54f, 0.11f, -0.7f, -0.12f, +R_CUBIC_TO, -0.9f, -1.26f, -2.04f, -2.25f, -3.39f, -2.94f, +R_CUBIC_TO, -2.87f, -1.47f, -6.54f, -1.47f, -9.4f, 0.01f, +R_CUBIC_TO, -1.36f, 0.7f, -2.5f, 1.7f, -3.4f, 2.96f, +R_CUBIC_TO, -0.08f, 0.14f, -0.23f, 0.21f, -0.39f, 0.21f, +CLOSE, +R_MOVE_TO, 6.25f, 12.07f, +R_CUBIC_TO, -0.13f, 0, -0.26f, -0.05f, -0.35f, -0.15f, +R_CUBIC_TO, -0.87f, -0.87f, -1.34f, -1.43f, -2.01f, -2.64f, +R_CUBIC_TO, -0.69f, -1.23f, -1.05f, -2.73f, -1.05f, -4.34f, +R_CUBIC_TO, 0, -2.97f, 2.54f, -5.39f, 5.66f, -5.39f, +R_CUBIC_TO, 3.12f, 0, 5.66f, 2.42f, 5.66f, 5.39f, +R_CUBIC_TO, 0, 0.28f, -0.22f, 0.5f, -0.5f, 0.5f, +R_CUBIC_TO, -0.28f, 0, -0.5f, -0.22f, -0.5f, -0.5f, +R_CUBIC_TO, 0, -2.42f, -2.09f, -4.39f, -4.66f, -4.39f, +R_CUBIC_TO, -2.57f, 0, -4.66f, 1.97f, -4.66f, 4.39f, +R_CUBIC_TO, 0, 1.44f, 0.32f, 2.77f, 0.93f, 3.85f, +R_CUBIC_TO, 0.64f, 1.15f, 1.08f, 1.64f, 1.85f, 2.42f, +R_CUBIC_TO, 0.19f, 0.2f, 0.19f, 0.51f, 0, 0.71f, +R_CUBIC_TO, -0.11f, 0.1f, -0.24f, 0.15f, -0.37f, 0.15f, +CLOSE, +R_MOVE_TO, 7.17f, -1.85f, +R_CUBIC_TO, -1.19f, 0, -2.24f, -0.3f, -3.1f, -0.89f, +R_CUBIC_TO, -1.49f, -1.01f, -2.38f, -2.65f, -2.38f, -4.39f, +R_CUBIC_TO, 0, -0.28f, 0.22f, -0.5f, 0.5f, -0.5f, +R_CUBIC_TO, 0.28f, 0, 0.5f, 0.22f, 0.5f, 0.5f, +R_CUBIC_TO, 0, 1.41f, 0.72f, 2.74f, 1.94f, 3.56f, +R_CUBIC_TO, 0.71f, 0.48f, 1.54f, 0.71f, 2.54f, 0.71f, +R_CUBIC_TO, 0.24f, 0, 0.64f, -0.03f, 1.04f, -0.1f, +R_CUBIC_TO, 0.27f, -0.05f, 0.53f, 0.13f, 0.58f, 0.41f, +R_CUBIC_TO, 0.05f, 0.27f, -0.13f, 0.53f, -0.41f, 0.58f, +R_CUBIC_TO, -0.57f, 0.11f, -1.07f, 0.12f, -1.21f, 0.12f, +CLOSE, +MOVE_TO, 14.91f, 22, +R_CUBIC_TO, -0.04f, 0, -0.09f, -0.01f, -0.13f, -0.02f, +R_CUBIC_TO, -1.59f, -0.44f, -2.63f, -1.03f, -3.72f, -2.1f, +R_CUBIC_TO, -1.4f, -1.39f, -2.17f, -3.24f, -2.17f, -5.22f, +R_CUBIC_TO, 0, -1.62f, 1.38f, -2.94f, 3.08f, -2.94f, +R_CUBIC_TO, 1.7f, 0, 3.08f, 1.32f, 3.08f, 2.94f, +R_CUBIC_TO, 0, 1.07f, 0.93f, 1.94f, 2.08f, 1.94f, +R_CUBIC_TO, 1.15f, 0, 2.08f, -0.87f, 2.08f, -1.94f, +R_CUBIC_TO, 0, -3.77f, -3.25f, -6.83f, -7.25f, -6.83f, +R_CUBIC_TO, -2.84f, 0, -5.44f, 1.58f, -6.61f, 4.03f, +R_CUBIC_TO, -0.39f, 0.81f, -0.59f, 1.76f, -0.59f, 2.8f, +R_CUBIC_TO, 0, 0.78f, 0.07f, 2.01f, 0.67f, 3.61f, +R_CUBIC_TO, 0.1f, 0.26f, -0.03f, 0.55f, -0.29f, 0.64f, +R_CUBIC_TO, -0.26f, 0.1f, -0.55f, -0.04f, -0.64f, -0.29f, +R_CUBIC_TO, -0.49f, -1.31f, -0.73f, -2.61f, -0.73f, -3.96f, +R_CUBIC_TO, 0, -1.2f, 0.23f, -2.29f, 0.68f, -3.24f, +R_CUBIC_TO, 1.33f, -2.79f, 4.28f, -4.6f, 7.51f, -4.6f, +R_CUBIC_TO, 4.55f, 0, 8.25f, 3.51f, 8.25f, 7.83f, +R_CUBIC_TO, 0, 1.62f, -1.38f, 2.94f, -3.08f, 2.94f, +R_CUBIC_TO, -1.7f, 0, -3.08f, -1.32f, -3.08f, -2.94f, +R_CUBIC_TO, 0, -1.07f, -0.93f, -1.94f, -2.08f, -1.94f, +R_CUBIC_TO, -1.15f, 0, -2.08f, 0.87f, -2.08f, 1.94f, +R_CUBIC_TO, 0, 1.71f, 0.66f, 3.31f, 1.87f, 4.51f, +R_CUBIC_TO, 0.95f, 0.94f, 1.86f, 1.46f, 3.27f, 1.85f, +R_CUBIC_TO, 0.27f, 0.07f, 0.42f, 0.35f, 0.35f, 0.61f, +R_CUBIC_TO, -0.05f, 0.23f, -0.26f, 0.38f, -0.47f, 0.38f, +CLOSE
diff --git a/chrome/app/vector_icons/nfc.icon b/chrome/app/vector_icons/nfc.icon new file mode 100644 index 0000000..6d5a4c1 --- /dev/null +++ b/chrome/app/vector_icons/nfc.icon
@@ -0,0 +1,41 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +CANVAS_DIMENSIONS, 24, +MOVE_TO, 20, 2, +H_LINE_TO, 4, +R_CUBIC_TO, -1.1f, 0, -2, 0.9f, -2, 2, +R_V_LINE_TO, 16, +R_CUBIC_TO, 0, 1.1f, 0.9f, 2, 2, 2, +R_H_LINE_TO, 16, +R_CUBIC_TO, 1.1f, 0, 2, -0.9f, 2, -2, +V_LINE_TO, 4, +R_CUBIC_TO, 0, -1.1f, -0.9f, -2, -2, -2, +CLOSE, +R_MOVE_TO, 0, 18, +H_LINE_TO, 4, +V_LINE_TO, 4, +R_H_LINE_TO, 16, +R_V_LINE_TO, 16, +CLOSE, +MOVE_TO, 18, 6, +R_H_LINE_TO, -5, +R_CUBIC_TO, -1.1f, 0, -2, 0.9f, -2, 2, +R_V_LINE_TO, 2.28f, +R_CUBIC_TO, -0.6f, 0.35f, -1, 0.98f, -1, 1.72f, +R_CUBIC_TO, 0, 1.1f, 0.9f, 2, 2, 2, +R_CUBIC_TO, 1.1f, 0, 2, -0.9f, 2, -2, +R_CUBIC_TO, 0, -0.74f, -0.4f, -1.38f, -1, -1.72f, +V_LINE_TO, 8, +R_H_LINE_TO, 3, +R_V_LINE_TO, 8, +H_LINE_TO, 8, +V_LINE_TO, 8, +R_H_LINE_TO, 2, +V_LINE_TO, 6, +H_LINE_TO, 6, +R_V_LINE_TO, 12, +R_H_LINE_TO, 12, +V_LINE_TO, 6, +CLOSE
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 73108f26..1340875 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1465,6 +1465,8 @@ "subresource_filter/subresource_filter_profile_context.h", "subresource_filter/subresource_filter_profile_context_factory.cc", "subresource_filter/subresource_filter_profile_context_factory.h", + "sync/bookmark_sync_service_factory.cc", + "sync/bookmark_sync_service_factory.h", "sync/chrome_sync_client.cc", "sync/chrome_sync_client.h", "sync/glue/extensions_activity_monitor.cc", @@ -1557,6 +1559,8 @@ "webauthn/authenticator_request_scheduler.h", "webauthn/chrome_authenticator_request_delegate.cc", "webauthn/chrome_authenticator_request_delegate.h", + "webauthn/transport_list_model.cc", + "webauthn/transport_list_model.h", "webshare/share_target_pref_helper.cc", "webshare/share_target_pref_helper.h", "webshare/webshare_target.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 25de418..365c1ea13 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -3934,6 +3934,12 @@ kOsAndroid, FEATURE_VALUE_TYPE(media::kMediaControlsExpandGesture)}, #endif +#if defined(OS_ANDROID) + {"cct-module", flag_descriptions::kCCTModuleName, + flag_descriptions::kCCTModuleDescription, kOsAndroid, + FEATURE_VALUE_TYPE(chrome::android::kCCTModule)}, +#endif + // NOTE: Adding a new flag requires adding a corresponding entry to enum // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag // Histograms" in tools/metrics/histograms/README.md (run the
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc index 2864bbed..f14aebc6 100644 --- a/chrome/browser/android/chrome_feature_list.cc +++ b/chrome/browser/android/chrome_feature_list.cc
@@ -72,6 +72,7 @@ &kAndroidPaymentApps, &kCCTBackgroundTab, &kCCTExternalLinkHandling, + &kCCTModule, &kCCTParallelRequest, &kCCTPostMessageAPI, &kCCTRedirectPreconnect, @@ -189,6 +190,8 @@ const base::Feature kCCTExternalLinkHandling{"CCTExternalLinkHandling", base::FEATURE_ENABLED_BY_DEFAULT}; +const base::Feature kCCTModule{"CCTModule", base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kCCTParallelRequest{"CCTParallelRequest", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chrome/browser/android/chrome_feature_list.h b/chrome/browser/android/chrome_feature_list.h index 5c55385..756c0fd 100644 --- a/chrome/browser/android/chrome_feature_list.h +++ b/chrome/browser/android/chrome_feature_list.h
@@ -19,6 +19,7 @@ extern const base::Feature kAndroidPaymentApps; extern const base::Feature kCCTBackgroundTab; extern const base::Feature kCCTExternalLinkHandling; +extern const base::Feature kCCTModule; extern const base::Feature kCCTParallelRequest; extern const base::Feature kCCTPostMessageAPI; extern const base::Feature kCCTRedirectPreconnect;
diff --git a/chrome/browser/bookmarks/bookmark_html_writer.cc b/chrome/browser/bookmarks/bookmark_html_writer.cc index 6005844..d1ed1e3c 100644 --- a/chrome/browser/bookmarks/bookmark_html_writer.cc +++ b/chrome/browser/bookmarks/bookmark_html_writer.cc
@@ -453,9 +453,10 @@ FROM_HERE, base::BindOnce( &Writer::DoWrite, - new Writer(codec.Encode( - BookmarkModelFactory::GetForBrowserContext(profile_)), - path_, favicons_map_.release(), observer_))); + new Writer( + codec.Encode(BookmarkModelFactory::GetForBrowserContext(profile_), + /*sync_metadata_str=*/std::string()), + path_, favicons_map_.release(), observer_))); if (g_fetcher) { base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, g_fetcher); g_fetcher = nullptr;
diff --git a/chrome/browser/bookmarks/bookmark_model_factory.cc b/chrome/browser/bookmarks/bookmark_model_factory.cc index 7bc5ce0..0f9ad2b 100644 --- a/chrome/browser/bookmarks/bookmark_model_factory.cc +++ b/chrome/browser/bookmarks/bookmark_model_factory.cc
@@ -14,6 +14,7 @@ #include "chrome/browser/bookmarks/startup_task_runner_service_factory.h" #include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/sync/bookmark_sync_service_factory.h" #include "chrome/browser/ui/webui/md_bookmarks/md_bookmarks_ui.h" #include "chrome/browser/undo/bookmark_undo_service_factory.h" #include "chrome/common/chrome_switches.h" @@ -22,6 +23,7 @@ #include "components/bookmarks/browser/startup_task_runner_service.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/prefs/pref_service.h" +#include "components/sync_bookmarks/bookmark_sync_service.h" #include "components/undo/bookmark_undo_service.h" #include "content/public/browser/browser_thread.h" @@ -53,6 +55,7 @@ DependsOn(BookmarkUndoServiceFactory::GetInstance()); DependsOn(ManagedBookmarkServiceFactory::GetInstance()); DependsOn(StartupTaskRunnerServiceFactory::GetInstance()); + DependsOn(BookmarkSyncServiceFactory::GetInstance()); } BookmarkModelFactory::~BookmarkModelFactory() { @@ -63,7 +66,8 @@ Profile* profile = Profile::FromBrowserContext(context); BookmarkModel* bookmark_model = new BookmarkModel(std::make_unique<ChromeBookmarkClient>( - profile, ManagedBookmarkServiceFactory::GetForProfile(profile))); + profile, ManagedBookmarkServiceFactory::GetForProfile(profile), + BookmarkSyncServiceFactory::GetForProfile(profile))); bookmark_model->Load(profile->GetPrefs(), profile->GetPath(), StartupTaskRunnerServiceFactory::GetForProfile(profile) ->GetBookmarkTaskRunner(),
diff --git a/chrome/browser/bookmarks/chrome_bookmark_client.cc b/chrome/browser/bookmarks/chrome_bookmark_client.cc index 4a8a040..f2bed02c 100644 --- a/chrome/browser/bookmarks/chrome_bookmark_client.cc +++ b/chrome/browser/bookmarks/chrome_bookmark_client.cc
@@ -18,6 +18,7 @@ #include "components/history/core/browser/history_service.h" #include "components/history/core/browser/url_database.h" #include "components/offline_pages/buildflags/buildflags.h" +#include "components/sync_bookmarks/bookmark_sync_service.h" #if BUILDFLAG(ENABLE_OFFLINE_PAGES) #include "chrome/browser/offline_pages/offline_page_bookmark_observer.h" @@ -25,8 +26,11 @@ ChromeBookmarkClient::ChromeBookmarkClient( Profile* profile, - bookmarks::ManagedBookmarkService* managed_bookmark_service) - : profile_(profile), managed_bookmark_service_(managed_bookmark_service) {} + bookmarks::ManagedBookmarkService* managed_bookmark_service, + sync_bookmarks::BookmarkSyncService* bookmark_sync_service) + : profile_(profile), + managed_bookmark_service_(managed_bookmark_service), + bookmark_sync_service_(bookmark_sync_service) {} ChromeBookmarkClient::~ChromeBookmarkClient() { } @@ -34,6 +38,7 @@ void ChromeBookmarkClient::Init(bookmarks::BookmarkModel* model) { if (managed_bookmark_service_) managed_bookmark_service_->BookmarkModelCreated(model); + model_ = model; #if BUILDFLAG(ENABLE_OFFLINE_PAGES) offline_page_observer_ = @@ -127,3 +132,14 @@ ? true : managed_bookmark_service_->CanBeEditedByUser(node); } + +std::string ChromeBookmarkClient::EncodeBookmarkSyncMetadata() { + return bookmark_sync_service_->EncodeBookmarkSyncMetadata(); +} + +void ChromeBookmarkClient::DecodeBookmarkSyncMetadata( + const std::string& metadata_str, + const base::RepeatingClosure& schedule_save_closure) { + bookmark_sync_service_->DecodeBookmarkSyncMetadata( + metadata_str, schedule_save_closure, model_); +}
diff --git a/chrome/browser/bookmarks/chrome_bookmark_client.h b/chrome/browser/bookmarks/chrome_bookmark_client.h index af44824..9b463eacb 100644 --- a/chrome/browser/bookmarks/chrome_bookmark_client.h +++ b/chrome/browser/bookmarks/chrome_bookmark_client.h
@@ -23,6 +23,10 @@ class ManagedBookmarkService; } +namespace sync_bookmarks { +class BookmarkSyncService; +} + #if BUILDFLAG(ENABLE_OFFLINE_PAGES) namespace offline_pages { class OfflinePageBookmarkObserver; @@ -33,7 +37,8 @@ public: ChromeBookmarkClient( Profile* profile, - bookmarks::ManagedBookmarkService* managed_bookmark_service); + bookmarks::ManagedBookmarkService* managed_bookmark_service, + sync_bookmarks::BookmarkSyncService* bookmark_sync_service); ~ChromeBookmarkClient() override; // bookmarks::BookmarkClient: @@ -54,6 +59,10 @@ const bookmarks::BookmarkNode* permanent_node) override; bool CanSyncNode(const bookmarks::BookmarkNode* node) override; bool CanBeEditedByUser(const bookmarks::BookmarkNode* node) override; + std::string EncodeBookmarkSyncMetadata() override; + void DecodeBookmarkSyncMetadata( + const std::string& metadata_str, + const base::RepeatingClosure& schedule_save_closure) override; private: // Pointer to the associated Profile. Must outlive ChromeBookmarkClient. @@ -63,6 +72,12 @@ // be null during testing. bookmarks::ManagedBookmarkService* managed_bookmark_service_; + bookmarks::BookmarkModel* model_; + + // Pointer to the BookmarkSyncService responsible for encoding and decoding + // sync metadata persisted together with the bookmarks model. + sync_bookmarks::BookmarkSyncService* bookmark_sync_service_; + #if BUILDFLAG(ENABLE_OFFLINE_PAGES) // Owns the observer used by Offline Page listening to Bookmark Model events. std::unique_ptr<offline_pages::OfflinePageBookmarkObserver>
diff --git a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc index f773a36..e63a92d 100644 --- a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc +++ b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc
@@ -17,10 +17,13 @@ #include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/browsing_data/browsing_data_flash_lso_helper.h" #include "chrome/browser/browsing_data/browsing_data_helper.h" #include "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h" +#include "chrome/browser/browsing_data/cookies_tree_model.h" #include "chrome/browser/browsing_data/counters/cache_counter.h" #include "chrome/browser/browsing_data/counters/site_data_counting_helper.h" +#include "chrome/browser/browsing_data/local_data_container.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/external_protocol/external_protocol_handler.h" @@ -132,6 +135,32 @@ return found; } +class CookiesTreeObserver : public CookiesTreeModel::Observer { + public: + explicit CookiesTreeObserver(base::OnceClosure quit_closure) + : quit_closure_(std::move(quit_closure)) {} + + void TreeModelBeginBatch(CookiesTreeModel* model) override {} + + void TreeModelEndBatch(CookiesTreeModel* model) override { + std::move(quit_closure_).Run(); + } + + void TreeNodesAdded(ui::TreeModel* model, + ui::TreeModelNode* parent, + int start, + int count) override {} + void TreeNodesRemoved(ui::TreeModel* model, + ui::TreeModelNode* parent, + int start, + int count) override {} + void TreeNodeChanged(ui::TreeModel* model, ui::TreeModelNode* node) override { + } + + private: + base::OnceClosure quit_closure_; +}; + } // namespace class BrowsingDataRemoverBrowserTest : public InProcessBrowserTest { @@ -226,15 +255,18 @@ ui_test_utils::NavigateToURL(browser(), url); EXPECT_EQ(0, GetSiteDataCount()); + EXPECT_EQ(0, GetCookieTreeModelCount()); EXPECT_FALSE(HasDataForType(type)); SetDataForType(type); EXPECT_EQ(1, GetSiteDataCount()); + EXPECT_EQ(1, GetCookieTreeModelCount()); EXPECT_TRUE(HasDataForType(type)); RemoveAndWait(ChromeBrowsingDataRemoverDelegate::DATA_TYPE_SITE_DATA, delete_begin); EXPECT_EQ(0, GetSiteDataCount()); + EXPECT_EQ(0, GetCookieTreeModelCount()); EXPECT_FALSE(HasDataForType(type)); } @@ -242,16 +274,20 @@ // creates an empty store, are counted and deleted correctly. void TestEmptySiteData(const std::string& type, base::Time delete_begin) { EXPECT_EQ(0, GetSiteDataCount()); + EXPECT_EQ(0, GetCookieTreeModelCount()); GURL url = embedded_test_server()->GetURL("/browsing_data/site_data.html"); ui_test_utils::NavigateToURL(browser(), url); EXPECT_EQ(0, GetSiteDataCount()); + EXPECT_EQ(0, GetCookieTreeModelCount()); // Opening a store of this type creates a site data entry. EXPECT_FALSE(HasDataForType(type)); EXPECT_EQ(1, GetSiteDataCount()); + EXPECT_EQ(1, GetCookieTreeModelCount()); RemoveAndWait(ChromeBrowsingDataRemoverDelegate::DATA_TYPE_SITE_DATA, delete_begin); EXPECT_EQ(0, GetSiteDataCount()); + EXPECT_EQ(0, GetCookieTreeModelCount()); } bool HasDataForType(const std::string& type) { @@ -276,6 +312,43 @@ return count; } + int GetCookieTreeModelCount() { + Profile* profile = browser()->profile(); + content::StoragePartition* storage_partition = + content::BrowserContext::GetDefaultStoragePartition(profile); + content::IndexedDBContext* indexed_db_context = + storage_partition->GetIndexedDBContext(); + content::ServiceWorkerContext* service_worker_context = + storage_partition->GetServiceWorkerContext(); + content::CacheStorageContext* cache_storage_context = + storage_partition->GetCacheStorageContext(); + storage::FileSystemContext* file_system_context = + storage_partition->GetFileSystemContext(); + auto container = std::make_unique<LocalDataContainer>( + new BrowsingDataCookieHelper(storage_partition), + new BrowsingDataDatabaseHelper(profile), + new BrowsingDataLocalStorageHelper(profile), + /*session_storage_helper=*/nullptr, + new BrowsingDataAppCacheHelper(profile), + new BrowsingDataIndexedDBHelper(indexed_db_context), + BrowsingDataFileSystemHelper::Create(file_system_context), + BrowsingDataQuotaHelper::Create(profile), + BrowsingDataChannelIDHelper::Create(profile->GetRequestContext()), + new BrowsingDataServiceWorkerHelper(service_worker_context), + new BrowsingDataSharedWorkerHelper(storage_partition, + profile->GetResourceContext()), + new BrowsingDataCacheStorageHelper(cache_storage_context), + BrowsingDataFlashLSOHelper::Create(profile), + BrowsingDataMediaLicenseHelper::Create(file_system_context)); + base::RunLoop run_loop; + CookiesTreeObserver observer(run_loop.QuitClosure()); + CookiesTreeModel model(std::move(container), + profile->GetExtensionSpecialStoragePolicy()); + model.AddCookiesTreeObserver(&observer); + run_loop.Run(); + return model.GetRoot()->child_count(); + } + void OnVideoDecodePerfInfo(base::RunLoop* run_loop, bool* out_is_smooth, bool* out_is_power_efficient, @@ -572,11 +645,14 @@ // Test that session storage is not counted until crbug.com/772337 is fixed. IN_PROC_BROWSER_TEST_F(BrowsingDataRemoverBrowserTest, SessionStorageCounting) { EXPECT_EQ(0, GetSiteDataCount()); + EXPECT_EQ(0, GetCookieTreeModelCount()); GURL url = embedded_test_server()->GetURL("/browsing_data/site_data.html"); ui_test_utils::NavigateToURL(browser(), url); EXPECT_EQ(0, GetSiteDataCount()); + EXPECT_EQ(0, GetCookieTreeModelCount()); SetDataForType("SessionStorage"); EXPECT_EQ(0, GetSiteDataCount()); + EXPECT_EQ(0, GetCookieTreeModelCount()); EXPECT_TRUE(HasDataForType("SessionStorage")); } @@ -624,6 +700,7 @@ IN_PROC_BROWSER_TEST_F(BrowsingDataRemoverBrowserTest, PRE_PRE_StorageRemovedFromDisk) { ASSERT_EQ(0, GetSiteDataCount()); + EXPECT_EQ(0, GetCookieTreeModelCount()); ASSERT_EQ(0, CheckUserDirectoryForString(kLocalHost, {})); // To use secure-only features on a host name, we need an https server. net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); @@ -654,11 +731,13 @@ IN_PROC_BROWSER_TEST_F(BrowsingDataRemoverBrowserTest, PRE_StorageRemovedFromDisk) { EXPECT_EQ(1, GetSiteDataCount()); + EXPECT_EQ(1, GetCookieTreeModelCount()); RemoveAndWait(ChromeBrowsingDataRemoverDelegate::DATA_TYPE_SITE_DATA | content::BrowsingDataRemover::DATA_TYPE_CACHE | ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY | ChromeBrowsingDataRemoverDelegate::DATA_TYPE_CONTENT_SETTINGS); EXPECT_EQ(0, GetSiteDataCount()); + EXPECT_EQ(0, GetCookieTreeModelCount()); } // Check if any data remains after a deletion and a Chrome restart to force
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index eace5a88..e7269c7 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -144,6 +144,7 @@ #include "chrome/common/pepper_permission_util.h" #include "chrome/common/pref_names.h" #include "chrome/common/prerender_url_loader_throttle.h" +#include "chrome/common/prerender_util.h" #include "chrome/common/render_messages.h" #include "chrome/common/renderer_configuration.mojom.h" #include "chrome/common/secure_origin_whitelist.h" @@ -2152,9 +2153,13 @@ web_contents->GetBrowserContext(), url); prerender::PrerenderContents* prerender_contents = prerender::PrerenderContents::FromWebContents(web_contents); - if (prerender_contents) { - if (prerender_contents->prerender_mode() == prerender::PREFETCH_ONLY) - *extra_load_flags = net::LOAD_PREFETCH; + if (prerender_contents && + prerender_contents->prerender_mode() == prerender::PREFETCH_ONLY) { + *extra_load_flags = net::LOAD_PREFETCH; + if (*extra_headers == nullptr) + *extra_headers = std::make_unique<net::HttpRequestHeaders>(); + extra_headers->get()->SetHeader(prerender::kPurposeHeaderName, + prerender::kPurposeHeaderValue); } }
diff --git a/chrome/browser/chromeos/extensions/active_tab_permission_granter_delegate_chromeos.cc b/chrome/browser/chromeos/extensions/active_tab_permission_granter_delegate_chromeos.cc index 488cbac..e70f05e 100644 --- a/chrome/browser/chromeos/extensions/active_tab_permission_granter_delegate_chromeos.cc +++ b/chrome/browser/chromeos/extensions/active_tab_permission_granter_delegate_chromeos.cc
@@ -29,7 +29,7 @@ g_resolved_callback = callback; } -bool ActiveTabPermissionGranterDelegateChromeOS::ShouldGrantActiveTab( +bool ActiveTabPermissionGranterDelegateChromeOS::ShouldGrantActiveTabOrPrompt( const Extension* extension, content::WebContents* web_contents) { permission_helper::RequestResolvedCallback callback;
diff --git a/chrome/browser/chromeos/extensions/active_tab_permission_granter_delegate_chromeos.h b/chrome/browser/chromeos/extensions/active_tab_permission_granter_delegate_chromeos.h index 9e50857e..3b51bb9 100644 --- a/chrome/browser/chromeos/extensions/active_tab_permission_granter_delegate_chromeos.h +++ b/chrome/browser/chromeos/extensions/active_tab_permission_granter_delegate_chromeos.h
@@ -31,8 +31,9 @@ permission_helper::RequestResolvedCallback* callback); // ActiveTabPermissionGranter::Delegate - bool ShouldGrantActiveTab(const Extension* extension, - content::WebContents* web_contents) override; + bool ShouldGrantActiveTabOrPrompt( + const Extension* extension, + content::WebContents* web_contents) override; private: DISALLOW_COPY_AND_ASSIGN(ActiveTabPermissionGranterDelegateChromeOS);
diff --git a/chrome/browser/chromeos/extensions/active_tab_permission_granter_delegate_chromeos_unittest.cc b/chrome/browser/chromeos/extensions/active_tab_permission_granter_delegate_chromeos_unittest.cc index abbebdf..5d7c332 100644 --- a/chrome/browser/chromeos/extensions/active_tab_permission_granter_delegate_chromeos_unittest.cc +++ b/chrome/browser/chromeos/extensions/active_tab_permission_granter_delegate_chromeos_unittest.cc
@@ -54,7 +54,7 @@ TEST_F(ActiveTabPermissionGranterDelegateChromeOSTest, GrantedForWhitelisted) { auto extension = CreateExtension(kWhitelistedId); - EXPECT_TRUE(delegate_.ShouldGrantActiveTab(extension.get(), nullptr)); + EXPECT_TRUE(delegate_.ShouldGrantActiveTabOrPrompt(extension.get(), nullptr)); } TEST_F(ActiveTabPermissionGranterDelegateChromeOSTest, @@ -63,11 +63,13 @@ // Deny the permission request. ScopedTestDialogAutoConfirm auto_confirm(ScopedTestDialogAutoConfirm::CANCEL); // First request is always rejected (by design). - EXPECT_FALSE(delegate_.ShouldGrantActiveTab(extension.get(), nullptr)); + EXPECT_FALSE( + delegate_.ShouldGrantActiveTabOrPrompt(extension.get(), nullptr)); // Spin the loop, allowing the dialog to be resolved. base::RunLoop().RunUntilIdle(); // Dialog result is propagated here, permission request is rejected. - EXPECT_FALSE(delegate_.ShouldGrantActiveTab(extension.get(), nullptr)); + EXPECT_FALSE( + delegate_.ShouldGrantActiveTabOrPrompt(extension.get(), nullptr)); } TEST_F(ActiveTabPermissionGranterDelegateChromeOSTest, @@ -75,10 +77,11 @@ auto extension = CreateExtension(kNonWhitelistedId); // Allow the permission request. ScopedTestDialogAutoConfirm auto_confirm(ScopedTestDialogAutoConfirm::ACCEPT); - EXPECT_FALSE(delegate_.ShouldGrantActiveTab(extension.get(), nullptr)); + EXPECT_FALSE( + delegate_.ShouldGrantActiveTabOrPrompt(extension.get(), nullptr)); base::RunLoop().RunUntilIdle(); // The permission request is granted now. - EXPECT_TRUE(delegate_.ShouldGrantActiveTab(extension.get(), nullptr)); + EXPECT_TRUE(delegate_.ShouldGrantActiveTabOrPrompt(extension.get(), nullptr)); } } // namespace extensions
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc index 477bd99..ed5d3b8d 100644 --- a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc +++ b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc
@@ -81,6 +81,22 @@ // thumbnail. Given that we support hdpi devices, maximum dimension is 360. const int kFileManagerMaximumThumbnailDimension = 360; +std::unique_ptr<std::string> GetShareUrlFromAlternateUrl( + const GURL& alternate_url) { + // Set |share_url| to a modified version of |alternate_url| that opens the + // sharing dialog for files and folders (add ?userstoinvite="" to the URL). + // TODO(sashab): Add an endpoint to the Drive API that generates this URL, + // instead of manually modifying it here. + GURL::Replacements replacements; + std::string new_query = + (alternate_url.has_query() ? alternate_url.query() + "&" : "") + + "userstoinvite=%22%22"; + replacements.SetQueryStr(new_query); + + return std::make_unique<std::string>( + alternate_url.ReplaceComponents(replacements).spec()); +} + // Copies properties from |entry_proto| to |properties|. |shared_with_me| is // given from the running profile. void FillEntryPropertiesValueForDrive(const drive::ResourceEntry& entry_proto, @@ -101,19 +117,8 @@ if (entry_proto.has_alternate_url()) { properties->alternate_url.reset( new std::string(entry_proto.alternate_url())); - - // Set |share_url| to a modified version of |alternate_url| that opens the - // sharing dialog for files and folders (add ?userstoinvite="" to the URL). - // TODO(sashab): Add an endpoint to the Drive API that generates this URL, - // instead of manually modifying it here. - GURL share_url = GURL(entry_proto.alternate_url()); - GURL::Replacements replacements; - std::string new_query = - (share_url.has_query() ? share_url.query() + "&" : "") + - "userstoinvite=%22%22"; - replacements.SetQueryStr(new_query); - properties->share_url.reset( - new std::string(share_url.ReplaceComponents(replacements).spec())); + properties->share_url = + GetShareUrlFromAlternateUrl(GURL(entry_proto.alternate_url())); } if (entry_proto.has_file_specific_info()) { @@ -695,6 +700,8 @@ if (!metadata->alternate_url.empty()) { properties_->alternate_url = std::make_unique<std::string>(std::move(metadata->alternate_url)); + properties_->share_url = + GetShareUrlFromAlternateUrl(GURL(*properties_->alternate_url)); } if (metadata->image_metadata) { if (metadata->image_metadata->height) {
diff --git a/chrome/browser/chromeos/oauth2_token_service_delegate_unittest.cc b/chrome/browser/chromeos/oauth2_token_service_delegate_unittest.cc index 6cf78ea2..d3254e14d 100644 --- a/chrome/browser/chromeos/oauth2_token_service_delegate_unittest.cc +++ b/chrome/browser/chromeos/oauth2_token_service_delegate_unittest.cc
@@ -11,6 +11,7 @@ #include "base/files/scoped_temp_dir.h" #include "base/macros.h" +#include "base/memory/scoped_refptr.h" #include "base/stl_util.h" #include "base/test/scoped_task_environment.h" #include "chromeos/account_manager/account_manager.h" @@ -88,7 +89,10 @@ void SetUp() override { ASSERT_TRUE(tmp_dir_.CreateUniqueTempDir()); - account_manager_.Initialize(tmp_dir_.GetPath()); + request_context_ = new net::TestURLRequestContextGetter( + scoped_task_environment_.GetMainThreadTaskRunner()); + account_manager_.Initialize(tmp_dir_.GetPath(), request_context_.get(), + immediate_callback_runner_); scoped_task_environment_.RunUntilIdle(); pref_service_.registry()->RegisterListPref( @@ -139,10 +143,14 @@ base::test::ScopedTaskEnvironment scoped_task_environment_; base::ScopedTempDir tmp_dir_; + scoped_refptr<net::URLRequestContextGetter> request_context_; AccountInfo account_info_; AccountTrackerService account_tracker_service_; AccountManager account_manager_; std::unique_ptr<ChromeOSOAuth2TokenServiceDelegate> delegate_; + AccountManager::DelayNetworkCallRunner immediate_callback_runner_ = + base::BindRepeating( + [](const base::RepeatingClosure& closure) -> void { closure.Run(); }); private: sync_preferences::TestingPrefServiceSyncable pref_service_; @@ -256,7 +264,8 @@ AccountManager account_manager; // AccountManager will not be fully initialized until // |scoped_task_environment_.RunUntilIdle()| is called. - account_manager.Initialize(tmp_dir_.GetPath()); + account_manager.Initialize(tmp_dir_.GetPath(), request_context_.get(), + immediate_callback_runner_); // Register callbacks before AccountManager has been fully initialized. auto delegate = std::make_unique<ChromeOSOAuth2TokenServiceDelegate>(
diff --git a/chrome/browser/extensions/active_tab_permission_granter.cc b/chrome/browser/extensions/active_tab_permission_granter.cc index 12648f56..dd2042b 100644 --- a/chrome/browser/extensions/active_tab_permission_granter.cc +++ b/chrome/browser/extensions/active_tab_permission_granter.cc
@@ -74,6 +74,15 @@ ActiveTabPermissionGranter::Delegate* g_active_tab_permission_granter_delegate = nullptr; +// Returns true if activeTab is allowed to be granted to the extension. This can +// return false for platform-specific implementations. +bool ShouldGrantActiveTabOrPrompt(const Extension* extension, + content::WebContents* web_contents) { + return !g_active_tab_permission_granter_delegate || + g_active_tab_permission_granter_delegate->ShouldGrantActiveTabOrPrompt( + extension, web_contents); +} + } // namespace ActiveTabPermissionGranter::ActiveTabPermissionGranter( @@ -108,16 +117,16 @@ const PermissionsData* permissions_data = extension->permissions_data(); - bool should_grant_active_tab = - !g_active_tab_permission_granter_delegate || - g_active_tab_permission_granter_delegate->ShouldGrantActiveTab( - extension, web_contents()); // If the extension requested all-hosts but has had it withheld, we grant it // active tab-style permissions, even if it doesn't have the activeTab // permission in the manifest. - if (should_grant_active_tab && - (permissions_data->HasWithheldImpliedAllHosts() || - permissions_data->HasAPIPermission(APIPermission::kActiveTab))) { + // Note: It's important that we check if the extension has activeTab before + // checking ShouldGrantActiveTabOrPrompt() in order to prevent + // ShouldGrantActiveTabOrPrompt() from prompting for extensions that don't + // request the activeTab permission. + if ((permissions_data->HasWithheldImpliedAllHosts() || + permissions_data->HasAPIPermission(APIPermission::kActiveTab)) && + ShouldGrantActiveTabOrPrompt(extension, web_contents())) { // Gate activeTab for file urls on extensions having explicit access to file // urls. int valid_schemes = UserScript::ValidUserScriptSchemes();
diff --git a/chrome/browser/extensions/active_tab_permission_granter.h b/chrome/browser/extensions/active_tab_permission_granter.h index 48fcf9a1..88aeef9 100644 --- a/chrome/browser/extensions/active_tab_permission_granter.h +++ b/chrome/browser/extensions/active_tab_permission_granter.h
@@ -37,8 +37,9 @@ public: virtual ~Delegate() {} // Platform specific check whether the activeTab permission is allowed. - virtual bool ShouldGrantActiveTab( - const Extension* extension, content::WebContents* web_contents) = 0; + virtual bool ShouldGrantActiveTabOrPrompt( + const Extension* extension, + content::WebContents* web_contents) = 0; }; ActiveTabPermissionGranter(content::WebContents* web_contents,
diff --git a/chrome/browser/extensions/active_tab_unittest.cc b/chrome/browser/extensions/active_tab_unittest.cc index 6d9c5fd..29b62a9 100644 --- a/chrome/browser/extensions/active_tab_unittest.cc +++ b/chrome/browser/extensions/active_tab_unittest.cc
@@ -100,8 +100,9 @@ ~ActiveTabPermissionGranterTestDelegate() override {} // ActiveTabPermissionGranterTestDelegate::Delegate - bool ShouldGrantActiveTab(const Extension* extension, - content::WebContents* contents) override { + bool ShouldGrantActiveTabOrPrompt(const Extension* extension, + content::WebContents* contents) override { + should_grant_call_count_++; return should_grant_; } @@ -109,8 +110,11 @@ should_grant_ = should_grant; } + int should_grant_call_count() { return should_grant_call_count_; } + private: bool should_grant_ = false; + int should_grant_call_count_ = 0; DISALLOW_COPY_AND_ASSIGN(ActiveTabPermissionGranterTestDelegate); }; @@ -426,12 +430,23 @@ tab_id() + 1, APIPermission::kTabCaptureForTab)); } -// Test that the custom platform delegate works as expected. -TEST_F(ActiveTabTest, Delegate) { - auto test_delegate = - std::make_unique<ActiveTabPermissionGranterTestDelegate>(); - ActiveTabPermissionGranter::SetPlatformDelegate(test_delegate.get()); +class ActiveTabDelegateTest : public ActiveTabTest { + protected: + ActiveTabDelegateTest() + : test_delegate_( + std::make_unique<ActiveTabPermissionGranterTestDelegate>()) { + ActiveTabPermissionGranter::SetPlatformDelegate(test_delegate_.get()); + } + ~ActiveTabDelegateTest() override { + ActiveTabPermissionGranter::SetPlatformDelegate(nullptr); + } + + std::unique_ptr<ActiveTabPermissionGranterTestDelegate> test_delegate_; +}; + +// Test that the custom platform delegate works as expected. +TEST_F(ActiveTabDelegateTest, Delegate) { GURL google("http://www.google.com"); NavigateAndCommit(google); @@ -440,12 +455,17 @@ EXPECT_TRUE(IsBlocked(extension, google)); // This time it's granted because the delegate allows it. - test_delegate->SetShouldGrant(true); + test_delegate_->SetShouldGrant(true); active_tab_permission_granter()->GrantIfRequested(extension.get()); EXPECT_TRUE(IsAllowed(extension, google)); +} - // Cleanup :). - ActiveTabPermissionGranter::SetPlatformDelegate(nullptr); +// Regression test for crbug.com/833188. +TEST_F(ActiveTabDelegateTest, DelegateUsedOnlyWhenNeeded) { + active_tab_permission_granter()->GrantIfRequested( + extension_without_active_tab.get()); + + EXPECT_EQ(0, test_delegate_->should_grant_call_count()); } #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 0a84d5fb..171a128 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -1392,10 +1392,10 @@ "set, Chrome will forget the launcher has been installed each time it " "starts. This is used for testing the App Launcher install flow."; -const char kResourceLoadSchedulerName[] = "Use the resource load scheduler"; +const char kResourceLoadSchedulerName[] = "Enable resource load throttling"; const char kResourceLoadSchedulerDescription[] = - "Uses the resource load scheduler in blink to schedule and throttle " - "resource load requests."; + "Uses the resource load scheduler in blink to throttle resource load " + "requests."; const char kSafeSearchUrlReportingName[] = "SafeSearch URLs reporting."; const char kSafeSearchUrlReportingDescription[] = @@ -2008,6 +2008,10 @@ "Enables downloading pages in the background in case page is not yet " "loaded in current tab."; +const char kCCTModuleName[] = "Chrome Custom Tabs Module"; +const char kCCTModuleDescription[] = + "Enables a dynamically loaded module in Chrome Custom Tabs, on Android."; + const char kChromeDuplexName[] = "Chrome Duplex"; const char kChromeDuplexDescription[] = "Enables Chrome Duplex, split toolbar Chrome Home, on Android.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index ee25e5b4..20174d6 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1222,6 +1222,9 @@ extern const char kBackgroundLoaderForDownloadsName[]; extern const char kBackgroundLoaderForDownloadsDescription[]; +extern const char kCCTModuleName[]; +extern const char kCCTModuleDescription[]; + extern const char kChromeDuplexName[]; extern const char kChromeDuplexDescription[];
diff --git a/chrome/browser/infobars/infobars_browsertest.cc b/chrome/browser/infobars/infobars_browsertest.cc index 95ac2b80..8230f02 100644 --- a/chrome/browser/infobars/infobars_browsertest.cc +++ b/chrome/browser/infobars/infobars_browsertest.cc
@@ -32,6 +32,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/themes/theme_service.h" #include "chrome/browser/themes/theme_service_factory.h" +#include "chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/chrome_select_file_policy.h" #include "chrome/browser/ui/collected_cookies_infobar_delegate.h" @@ -234,6 +235,7 @@ IBD::DATA_REDUCTION_PROXY_PREVIEW_INFOBAR_DELEGATE}, {"automation", IBD::AUTOMATION_INFOBAR_DELEGATE}, {"page_load_capping", IBD::PAGE_LOAD_CAPPING_INFOBAR_DELEGATE}, + {"bloated_renderer", IBD::BLOATED_RENDERER_INFOBAR_DELEGATE}, }; auto id = kIdentifiers.find(name); expected_identifiers_.push_back((id == kIdentifiers.end()) ? IBD::INVALID @@ -426,6 +428,10 @@ PageLoadCappingInfoBarDelegate::PauseCallback()); break; + case IBD::BLOATED_RENDERER_INFOBAR_DELEGATE: + BloatedRendererTabHelper::ShowInfoBar(GetInfoBarService()); + break; + default: break; } @@ -601,6 +607,10 @@ ShowAndVerifyUi(); } +IN_PROC_BROWSER_TEST_F(InfoBarUiTest, InvokeUi_bloated_renderer) { + ShowAndVerifyUi(); +} + IN_PROC_BROWSER_TEST_F(InfoBarUiTest, InvokeUi_multiple_infobars) { ShowAndVerifyUi(); }
diff --git a/chrome/browser/metrics/process_memory_metrics_emitter.cc b/chrome/browser/metrics/process_memory_metrics_emitter.cc index 693b7c3..9eadd75d 100644 --- a/chrome/browser/metrics/process_memory_metrics_emitter.cc +++ b/chrome/browser/metrics/process_memory_metrics_emitter.cc
@@ -38,8 +38,11 @@ namespace { const char kEffectiveSize[] = "effective_size"; +const char kAllocatedObjectsSize[] = "allocated_objects_size"; const bool kLargeMetric = true; +enum class EmitTo { kUkmOnly, kUkmAndUmaAsSize }; + struct Metric { // The root dump name that represents the required metric. const char* const dump_name; @@ -50,116 +53,136 @@ const bool is_large_metric; // The type of metric that is measured, usually size in bytes or object count. const char* const metric; + // Indicates where to emit the metric. + const EmitTo target; // The setter method for the metric in UKM recorder. Memory_Experimental& (Memory_Experimental::*setter)(int64_t); }; const Metric kAllocatorDumpNamesForMetrics[] = { {"blink_gc", "BlinkGC", kLargeMetric, kEffectiveSize, - &Memory_Experimental::SetBlinkGC}, + EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetBlinkGC}, {"blink_gc/allocated_objects", "BlinkGC.AllocatedObjects", kLargeMetric, - kEffectiveSize, &Memory_Experimental::SetBlinkGC_AllocatedObjects}, + kEffectiveSize, EmitTo::kUkmAndUmaAsSize, + &Memory_Experimental::SetBlinkGC_AllocatedObjects}, {"blink_objects/Document", "NumberOfDocuments", !kLargeMetric, - MemoryAllocatorDump::kNameObjectCount, + MemoryAllocatorDump::kNameObjectCount, EmitTo::kUkmOnly, &Memory_Experimental::SetNumberOfDocuments}, {"blink_objects/AdSubframe", "NumberOfAdSubframes", !kLargeMetric, - MemoryAllocatorDump::kNameObjectCount, + MemoryAllocatorDump::kNameObjectCount, EmitTo::kUkmOnly, &Memory_Experimental::SetNumberOfAdSubframes}, {"blink_objects/DetachedScriptState", "NumberOfDetachedScriptStates", - !kLargeMetric, MemoryAllocatorDump::kNameObjectCount, + !kLargeMetric, MemoryAllocatorDump::kNameObjectCount, EmitTo::kUkmOnly, &Memory_Experimental::SetNumberOfDetachedScriptStates}, {"blink_objects/Frame", "NumberOfFrames", !kLargeMetric, - MemoryAllocatorDump::kNameObjectCount, + MemoryAllocatorDump::kNameObjectCount, EmitTo::kUkmOnly, &Memory_Experimental::SetNumberOfFrames}, {"blink_objects/LayoutObject", "NumberOfLayoutObjects", !kLargeMetric, - MemoryAllocatorDump::kNameObjectCount, + MemoryAllocatorDump::kNameObjectCount, EmitTo::kUkmOnly, &Memory_Experimental::SetNumberOfLayoutObjects}, {"blink_objects/Node", "NumberOfNodes", !kLargeMetric, - MemoryAllocatorDump::kNameObjectCount, + MemoryAllocatorDump::kNameObjectCount, EmitTo::kUkmOnly, &Memory_Experimental::SetNumberOfNodes}, {"components/download", "DownloadService", !kLargeMetric, kEffectiveSize, - &Memory_Experimental::SetDownloadService}, + EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetDownloadService}, {"discardable", "Discardable", kLargeMetric, kEffectiveSize, - &Memory_Experimental::SetDiscardable}, + EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetDiscardable}, {"extensions/value_store", "Extensions.ValueStore", kLargeMetric, - kEffectiveSize, &Memory_Experimental::SetExtensions_ValueStore}, + kEffectiveSize, EmitTo::kUkmAndUmaAsSize, + &Memory_Experimental::SetExtensions_ValueStore}, {"font_caches", "FontCaches", !kLargeMetric, kEffectiveSize, - &Memory_Experimental::SetFontCaches}, + EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetFontCaches}, {"gpu/gl", "CommandBuffer", kLargeMetric, kEffectiveSize, - &Memory_Experimental::SetCommandBuffer}, + EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetCommandBuffer}, {"history", "History", !kLargeMetric, kEffectiveSize, - &Memory_Experimental::SetHistory}, + EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetHistory}, {"java_heap", "JavaHeap", kLargeMetric, kEffectiveSize, - &Memory_Experimental::SetJavaHeap}, + EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetJavaHeap}, {"leveldatabase", "LevelDatabase", !kLargeMetric, kEffectiveSize, - &Memory_Experimental::SetLevelDatabase}, - {"malloc", "Malloc", kLargeMetric, kEffectiveSize, + EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetLevelDatabase}, + {"malloc", "Malloc", kLargeMetric, kEffectiveSize, EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetMalloc}, {"mojo", "NumberOfMojoHandles", !kLargeMetric, - MemoryAllocatorDump::kNameObjectCount, + MemoryAllocatorDump::kNameObjectCount, EmitTo::kUkmOnly, &Memory_Experimental::SetNumberOfMojoHandles}, - {"net", "Net", !kLargeMetric, kEffectiveSize, &Memory_Experimental::SetNet}, + {"net", "Net", !kLargeMetric, kEffectiveSize, EmitTo::kUkmAndUmaAsSize, + &Memory_Experimental::SetNet}, {"net/url_request_context", "Net.UrlRequestContext", !kLargeMetric, - kEffectiveSize, &Memory_Experimental::SetNet_UrlRequestContext}, + kEffectiveSize, EmitTo::kUkmAndUmaAsSize, + &Memory_Experimental::SetNet_UrlRequestContext}, {"omnibox", "OmniboxSuggestions", !kLargeMetric, kEffectiveSize, - &Memory_Experimental::SetOmniboxSuggestions}, + EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetOmniboxSuggestions}, {"partition_alloc", "PartitionAlloc", kLargeMetric, kEffectiveSize, - &Memory_Experimental::SetPartitionAlloc}, + EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetPartitionAlloc}, {"partition_alloc/allocated_objects", "PartitionAlloc.AllocatedObjects", - kLargeMetric, kEffectiveSize, + kLargeMetric, kEffectiveSize, EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetPartitionAlloc_AllocatedObjects}, {"partition_alloc/partitions/array_buffer", "PartitionAlloc.Partitions.ArrayBuffer", kLargeMetric, kEffectiveSize, + EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetPartitionAlloc_Partitions_ArrayBuffer}, {"partition_alloc/partitions/buffer", "PartitionAlloc.Partitions.Buffer", - kLargeMetric, kEffectiveSize, + kLargeMetric, kEffectiveSize, EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetPartitionAlloc_Partitions_Buffer}, {"partition_alloc/partitions/fast_malloc", "PartitionAlloc.Partitions.FastMalloc", kLargeMetric, kEffectiveSize, + EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetPartitionAlloc_Partitions_FastMalloc}, {"partition_alloc/partitions/layout", "PartitionAlloc.Partitions.Layout", - kLargeMetric, kEffectiveSize, + kLargeMetric, kEffectiveSize, EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetPartitionAlloc_Partitions_Layout}, {"site_storage", "SiteStorage", kLargeMetric, kEffectiveSize, - &Memory_Experimental::SetSiteStorage}, + EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetSiteStorage}, {"site_storage/blob_storage", "SiteStorage.BlobStorage", kLargeMetric, - kEffectiveSize, &Memory_Experimental::SetSiteStorage_BlobStorage}, + kEffectiveSize, EmitTo::kUkmAndUmaAsSize, + &Memory_Experimental::SetSiteStorage_BlobStorage}, {"site_storage/index_db", "SiteStorage.IndexDB", !kLargeMetric, - kEffectiveSize, &Memory_Experimental::SetSiteStorage_IndexDB}, + kEffectiveSize, EmitTo::kUkmAndUmaAsSize, + &Memory_Experimental::SetSiteStorage_IndexDB}, {"site_storage/localstorage", "SiteStorage.LocalStorage", !kLargeMetric, - kEffectiveSize, &Memory_Experimental::SetSiteStorage_LocalStorage}, + kEffectiveSize, EmitTo::kUkmAndUmaAsSize, + &Memory_Experimental::SetSiteStorage_LocalStorage}, {"site_storage/session_storage", "SiteStorage.SessionStorage", - !kLargeMetric, kEffectiveSize, + !kLargeMetric, kEffectiveSize, EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetSiteStorage_SessionStorage}, - {"skia", "Skia", kLargeMetric, kEffectiveSize, + {"skia", "Skia", kLargeMetric, kEffectiveSize, EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetSkia}, {"skia/sk_glyph_cache", "Skia.SkGlyphCache", kLargeMetric, kEffectiveSize, - &Memory_Experimental::SetSkia_SkGlyphCache}, + EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetSkia_SkGlyphCache}, {"skia/sk_resource_cache", "Skia.SkResourceCache", kLargeMetric, - kEffectiveSize, &Memory_Experimental::SetSkia_SkResourceCache}, + kEffectiveSize, EmitTo::kUkmAndUmaAsSize, + &Memory_Experimental::SetSkia_SkResourceCache}, {"sqlite", "Sqlite", !kLargeMetric, kEffectiveSize, - &Memory_Experimental::SetSqlite}, - {"sync", "Sync", kLargeMetric, kEffectiveSize, + EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetSqlite}, + {"sync", "Sync", kLargeMetric, kEffectiveSize, EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetSync}, {"tab_restore", "TabRestore", !kLargeMetric, kEffectiveSize, - &Memory_Experimental::SetTabRestore}, - {"ui", "UI", !kLargeMetric, kEffectiveSize, &Memory_Experimental::SetUI}, - {"v8", "V8", kLargeMetric, kEffectiveSize, &Memory_Experimental::SetV8}, + EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetTabRestore}, + {"ui", "UI", !kLargeMetric, kEffectiveSize, EmitTo::kUkmAndUmaAsSize, + &Memory_Experimental::SetUI}, + {"v8", "V8", kLargeMetric, kEffectiveSize, EmitTo::kUkmAndUmaAsSize, + &Memory_Experimental::SetV8}, + {"v8", "V8.AllocatedObjects", kLargeMetric, kAllocatedObjectsSize, + EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetV8_AllocatedObjects}, {"web_cache", "WebCache", !kLargeMetric, kEffectiveSize, - &Memory_Experimental::SetWebCache}, + EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetWebCache}, {"web_cache/Image_resources", "WebCache.ImageResources", !kLargeMetric, - kEffectiveSize, &Memory_Experimental::SetWebCache_ImageResources}, + kEffectiveSize, EmitTo::kUkmAndUmaAsSize, + &Memory_Experimental::SetWebCache_ImageResources}, {"web_cache/CSS stylesheet_resources", "WebCache.CSSStylesheetResources", - !kLargeMetric, kEffectiveSize, + !kLargeMetric, kEffectiveSize, EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetWebCache_CSSStylesheetResources}, {"web_cache/Script_resources", "WebCache.ScriptResources", !kLargeMetric, - kEffectiveSize, &Memory_Experimental::SetWebCache_ScriptResources}, + kEffectiveSize, EmitTo::kUkmAndUmaAsSize, + &Memory_Experimental::SetWebCache_ScriptResources}, {"web_cache/XSL stylesheet_resources", "WebCache.XSLStylesheetResources", - !kLargeMetric, kEffectiveSize, + !kLargeMetric, kEffectiveSize, EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetWebCache_XSLStylesheetResources}, {"web_cache/Font_resources", "WebCache.FontResources", !kLargeMetric, - kEffectiveSize, &Memory_Experimental::SetWebCache_FontResources}, + kEffectiveSize, EmitTo::kUkmAndUmaAsSize, + &Memory_Experimental::SetWebCache_FontResources}, {"web_cache/Other_resources", "WebCache.OtherResources", !kLargeMetric, - kEffectiveSize, &Memory_Experimental::SetWebCache_OtherResources}, + kEffectiveSize, EmitTo::kUkmAndUmaAsSize, + &Memory_Experimental::SetWebCache_OtherResources}, }; #define UMA_PREFIX "Memory." @@ -184,11 +207,8 @@ for (const auto& item : kAllocatorDumpNamesForMetrics) { base::Optional<uint64_t> value = pmd.GetMetric(item.dump_name, item.metric); if (value) { - // Effective size is the size of the memory dump after discounting all - // suballocations from the dump. - if (base::StringPiece(item.metric) == kEffectiveSize) { - // For each effective size metric, emit both an UMA in MB or KB, and an - // UKM in MB. + if (item.target == EmitTo::kUkmAndUmaAsSize) { + // For each size metric, emit both an UMA in MB or KB, and an UKM in MB. ((*builder).*(item.setter))(value.value() / 1024 / 1024); if (!record_uma) continue;
diff --git a/chrome/browser/metrics/process_memory_metrics_emitter_unittest.cc b/chrome/browser/metrics/process_memory_metrics_emitter_unittest.cc index 8ba47a3..294fb47 100644 --- a/chrome/browser/metrics/process_memory_metrics_emitter_unittest.cc +++ b/chrome/browser/metrics/process_memory_metrics_emitter_unittest.cc
@@ -170,6 +170,9 @@ metrics_mb_or_count["BlinkGC"] * 1024 * 1024); SetAllocatorDumpMetric(pmd, "v8", "effective_size", metrics_mb_or_count["V8"] * 1024 * 1024); + SetAllocatorDumpMetric( + pmd, "v8", "allocated_objects_size", + metrics_mb_or_count["V8.AllocatedObjects"] * 1024 * 1024); SetAllocatorDumpMetric(pmd, "blink_objects/AdSubframe", "object_count", metrics_mb_or_count["NumberOfAdSubframes"]); @@ -213,8 +216,8 @@ {"ProcessType", static_cast<int64_t>(ProcessType::RENDERER)}, {"Resident", 110}, {"Malloc", 120}, {"PrivateMemoryFootprint", 130}, {"SharedMemoryFootprint", 135}, {"PartitionAlloc", 140}, - {"BlinkGC", 150}, {"V8", 160}, {"NumberOfExtensions", 0}, - {"Uptime", 42}, + {"BlinkGC", 150}, {"V8", 160}, {"V8.AllocatedObjects", 100}, + {"NumberOfExtensions", 0}, {"Uptime", 42}, #if defined(OS_LINUX) || defined(OS_ANDROID) {"PrivateSwapFootprint", 50}, #endif
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 f850a7a..ac96830 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
@@ -300,6 +300,67 @@ EXPECT_FALSE(is_paused); } +// Tests that when starting a new Picture-in-Picture session from the same +// video, the video stays in Picture-in-Picture mode. +IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest, + RequestPictureInPictureTwiceFromSameVideo) { + 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* active_web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_TRUE(active_web_contents); + + SetUpWindowController(active_web_contents); + ASSERT_TRUE(window_controller()); + + EXPECT_TRUE(content::ExecuteScript(active_web_contents, "video.play();")); + EXPECT_TRUE( + content::ExecuteScript(active_web_contents, "enterPictureInPicture();")); + + // Check that requesting Picture-in-Picture promise was resolved. + base::string16 expected_title = base::ASCIIToUTF16("1"); + EXPECT_EQ(expected_title, + content::TitleWatcher(active_web_contents, expected_title) + .WaitAndGetTitle()); + + bool in_picture_in_picture = false; + EXPECT_TRUE(ExecuteScriptAndExtractBool( + active_web_contents, "isInPictureInPicture();", &in_picture_in_picture)); + EXPECT_TRUE(in_picture_in_picture); + + EXPECT_TRUE( + content::ExecuteScript(active_web_contents, "exitPictureInPicture();")); + + // 'left' is sent when the video leaves Picture-in-Picture. + expected_title = base::ASCIIToUTF16("left"); + EXPECT_EQ(expected_title, + content::TitleWatcher(active_web_contents, expected_title) + .WaitAndGetTitle()); + + EXPECT_TRUE( + content::ExecuteScript(active_web_contents, "enterPictureInPicture();")); + + // Check that requesting Picture-in-Picture promise was resolved. + expected_title = base::ASCIIToUTF16("2"); + EXPECT_EQ(expected_title, + content::TitleWatcher(active_web_contents, expected_title) + .WaitAndGetTitle()); + + in_picture_in_picture = false; + EXPECT_TRUE(ExecuteScriptAndExtractBool( + active_web_contents, "isInPictureInPicture();", &in_picture_in_picture)); + EXPECT_TRUE(in_picture_in_picture); + + bool is_paused = false; + EXPECT_TRUE(ExecuteScriptAndExtractBool(active_web_contents, "isPaused();", + &is_paused)); + EXPECT_FALSE(is_paused); +} + // Tests that when starting a new Picture-in-Picture session from the same tab, // the previous video is no longer in Picture-in-Picture mode. IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest,
diff --git a/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc b/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc index 3dda333..1152c59 100644 --- a/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc +++ b/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc
@@ -54,6 +54,12 @@ using prerender::test_utils::RequestCounter; using prerender::test_utils::TestPrerender; +namespace { + +const char kExpectedPurposeHeaderOnPrefetch[] = "Purpose"; + +} // namespace + namespace prerender { const char k302RedirectPage[] = "/prerender/302_redirect.html"; @@ -257,7 +263,7 @@ GURL prefetch_page = src_server()->GetURL(kPrefetchPage); GURL prefetch_script = src_server()->GetURL(kPrefetchScript); - content::URLLoaderInterceptor interceptor(base::Bind( + content::URLLoaderInterceptor interceptor(base::BindRepeating( [](const GURL& prefetch_page, const GURL& prefetch_script, content::URLLoaderInterceptor::RequestParams* params) { if (params->url_request.url == prefetch_page || @@ -277,6 +283,63 @@ test_prerender->WaitForLoads(0); } +// Check that prefetched resources and subresources set the 'Purpose: prefetch' +// header. +IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PurposeHeaderIsSet) { + GURL prefetch_page = src_server()->GetURL(kPrefetchPage); + GURL prefetch_script = src_server()->GetURL(kPrefetchScript); + + content::URLLoaderInterceptor interceptor(base::BindRepeating( + [](const GURL& prefetch_page, const GURL& prefetch_script, + content::URLLoaderInterceptor::RequestParams* params) { + if (params->url_request.url == prefetch_page || + params->url_request.url == prefetch_script) { + EXPECT_TRUE(params->url_request.load_flags & net::LOAD_PREFETCH); + EXPECT_TRUE(params->url_request.headers.HasHeader( + kExpectedPurposeHeaderOnPrefetch)); + std::string purpose_header; + params->url_request.headers.GetHeader( + kExpectedPurposeHeaderOnPrefetch, &purpose_header); + EXPECT_EQ("prefetch", purpose_header); + } + return false; + }, + prefetch_page, prefetch_script)); + + std::unique_ptr<TestPrerender> test_prerender = + PrefetchFromFile(kPrefetchPage, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); + WaitForRequestCount(prefetch_page, 1); + WaitForRequestCount(prefetch_script, 1); +} + +// Check that on normal navigations the 'Purpose: prefetch' header is not set. +IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, + PurposeHeaderNotSetWhenNotPrefetching) { + GURL prefetch_page = src_server()->GetURL(kPrefetchPage); + GURL prefetch_script = src_server()->GetURL(kPrefetchScript); + GURL prefetch_script2 = src_server()->GetURL(kPrefetchScript2); + + content::URLLoaderInterceptor interceptor(base::BindRepeating( + [](const GURL& prefetch_page, const GURL& prefetch_script, + const GURL& prefetch_script2, + content::URLLoaderInterceptor::RequestParams* params) { + if (params->url_request.url == prefetch_page || + params->url_request.url == prefetch_script || + params->url_request.url == prefetch_script2) { + EXPECT_FALSE(params->url_request.load_flags & net::LOAD_PREFETCH); + EXPECT_FALSE(params->url_request.headers.HasHeader( + kExpectedPurposeHeaderOnPrefetch)); + } + return false; + }, + prefetch_page, prefetch_script, prefetch_script2)); + + ui_test_utils::NavigateToURL(current_browser(), prefetch_page); + WaitForRequestCount(prefetch_page, 1); + WaitForRequestCount(prefetch_script, 1); + WaitForRequestCount(prefetch_script2, 1); +} + // Check that a prefetch followed by a load produces the approriate // histograms. Note that other histogram testing is done in // browser/page_load_metrics, in particular, testing the combinations of @@ -411,11 +474,7 @@ "/server-redirect/?" + net::EscapeQueryParamValue(kPrefetchPage, false); GURL redirect_url = src_server()->GetURL(redirect_path); GURL page_url = src_server()->GetURL(kPrefetchPage); - auto verify_prefetch_only = base::Bind([](net::URLRequest* request) { - EXPECT_TRUE(request->load_flags() & net::LOAD_PREFETCH); - }); - - content::URLLoaderInterceptor interceptor(base::Bind( + content::URLLoaderInterceptor interceptor(base::BindRepeating( [](const GURL& page_url, content::URLLoaderInterceptor::RequestParams* params) { if (params->url_request.url == page_url)
diff --git a/chrome/browser/printing/cloud_print/gcd_api_flow.cc b/chrome/browser/printing/cloud_print/gcd_api_flow.cc index 90b1bd6..1a6e886 100644 --- a/chrome/browser/printing/cloud_print/gcd_api_flow.cc +++ b/chrome/browser/printing/cloud_print/gcd_api_flow.cc
@@ -18,10 +18,9 @@ std::unique_ptr<GCDApiFlow> GCDApiFlow::Create( net::URLRequestContextGetter* request_context, - OAuth2TokenService* token_service, - const std::string& account_id) { + identity::IdentityManager* identity_manager) { return std::unique_ptr<GCDApiFlow>( - new GCDApiFlowImpl(request_context, token_service, account_id)); + new GCDApiFlowImpl(request_context, identity_manager)); } GCDApiFlow::GCDApiFlow() {
diff --git a/chrome/browser/printing/cloud_print/gcd_api_flow.h b/chrome/browser/printing/cloud_print/gcd_api_flow.h index 4f7de56d..1d1fff0b 100644 --- a/chrome/browser/printing/cloud_print/gcd_api_flow.h +++ b/chrome/browser/printing/cloud_print/gcd_api_flow.h
@@ -18,6 +18,10 @@ class DictionaryValue; } +namespace identity { +class IdentityManager; +} + namespace cloud_print { // API flow for communicating with cloud print and cloud devices. @@ -68,8 +72,7 @@ static std::unique_ptr<GCDApiFlow> Create( net::URLRequestContextGetter* request_context, - OAuth2TokenService* token_service, - const std::string& account_id); + identity::IdentityManager* identity_manager); virtual void Start(std::unique_ptr<Request> request) = 0;
diff --git a/chrome/browser/printing/cloud_print/gcd_api_flow_impl.cc b/chrome/browser/printing/cloud_print/gcd_api_flow_impl.cc index 520402b6..1ebed0f 100644 --- a/chrome/browser/printing/cloud_print/gcd_api_flow_impl.cc +++ b/chrome/browser/printing/cloud_print/gcd_api_flow_impl.cc
@@ -22,6 +22,8 @@ #include "net/base/url_util.h" #include "net/http/http_status_code.h" #include "net/url_request/url_request_status.h" +#include "services/identity/public/cpp/identity_manager.h" +#include "services/identity/public/cpp/primary_account_access_token_fetcher.h" using net::DefineNetworkTrafficAnnotation; @@ -78,13 +80,8 @@ } // namespace GCDApiFlowImpl::GCDApiFlowImpl(net::URLRequestContextGetter* request_context, - OAuth2TokenService* token_service, - const std::string& account_id) - : OAuth2TokenService::Consumer("cloud_print"), - request_context_(request_context), - token_service_(token_service), - account_id_(account_id) { -} + identity::IdentityManager* identity_manager) + : request_context_(request_context), identity_manager_(identity_manager) {} GCDApiFlowImpl::~GCDApiFlowImpl() { } @@ -93,14 +90,23 @@ request_ = std::move(request); OAuth2TokenService::ScopeSet oauth_scopes; oauth_scopes.insert(request_->GetOAuthScope()); - oauth_request_ = - token_service_->StartRequest(account_id_, oauth_scopes, this); + DCHECK(identity_manager_); + token_fetcher_ = identity_manager_->CreateAccessTokenFetcherForPrimaryAccount( + "cloud_print", oauth_scopes, + base::BindOnce(&GCDApiFlowImpl::OnAccessTokenFetchComplete, + base::Unretained(this)), + identity::PrimaryAccountAccessTokenFetcher::Mode::kImmediate); } -void GCDApiFlowImpl::OnGetTokenSuccess( - const OAuth2TokenService::Request* request, - const std::string& access_token, - const base::Time& expiration_time) { +void GCDApiFlowImpl::OnAccessTokenFetchComplete(GoogleServiceAuthError error, + std::string access_token) { + token_fetcher_.reset(); + + if (error.state() != GoogleServiceAuthError::NONE) { + request_->OnGCDApiFlowError(ERROR_TOKEN); + return; + } + CreateRequest(); std::string authorization_header = @@ -112,12 +118,6 @@ url_fetcher_->Start(); } -void GCDApiFlowImpl::OnGetTokenFailure( - const OAuth2TokenService::Request* request, - const GoogleServiceAuthError& error) { - request_->OnGCDApiFlowError(ERROR_TOKEN); -} - void GCDApiFlowImpl::CreateRequest() { url_fetcher_ = net::URLFetcher::Create( request_->GetURL(), net::URLFetcher::GET, this,
diff --git a/chrome/browser/printing/cloud_print/gcd_api_flow_impl.h b/chrome/browser/printing/cloud_print/gcd_api_flow_impl.h index 8cfdbf2..c3ef066 100644 --- a/chrome/browser/printing/cloud_print/gcd_api_flow_impl.h +++ b/chrome/browser/printing/cloud_print/gcd_api_flow_impl.h
@@ -12,16 +12,18 @@ #include "net/url_request/url_fetcher.h" #include "net/url_request/url_fetcher_delegate.h" +namespace identity { +class PrimaryAccountAccessTokenFetcher; +} +class GoogleServiceAuthError; + namespace cloud_print { -class GCDApiFlowImpl : public GCDApiFlow, - public net::URLFetcherDelegate, - public OAuth2TokenService::Consumer { +class GCDApiFlowImpl : public GCDApiFlow, public net::URLFetcherDelegate { public: // Create an OAuth2-based confirmation. GCDApiFlowImpl(net::URLRequestContextGetter* request_context, - OAuth2TokenService* token_service, - const std::string& account_id); + identity::IdentityManager* identity_manager); ~GCDApiFlowImpl() override; // GCDApiFlow implementation: @@ -30,21 +32,16 @@ // net::URLFetcherDelegate implementation: void OnURLFetchComplete(const net::URLFetcher* source) override; - // OAuth2TokenService::Consumer implementation: - void OnGetTokenSuccess(const OAuth2TokenService::Request* request, - const std::string& access_token, - const base::Time& expiration_time) override; - void OnGetTokenFailure(const OAuth2TokenService::Request* request, - const GoogleServiceAuthError& error) override; + void OnAccessTokenFetchComplete(GoogleServiceAuthError error, + std::string access_token); private: void CreateRequest(); std::unique_ptr<net::URLFetcher> url_fetcher_; - std::unique_ptr<OAuth2TokenService::Request> oauth_request_; + std::unique_ptr<identity::PrimaryAccountAccessTokenFetcher> token_fetcher_; scoped_refptr<net::URLRequestContextGetter> request_context_; - OAuth2TokenService* token_service_; - std::string account_id_; + identity::IdentityManager* identity_manager_; std::unique_ptr<Request> request_; DISALLOW_COPY_AND_ASSIGN(GCDApiFlowImpl);
diff --git a/chrome/browser/printing/cloud_print/gcd_api_flow_unittest.cc b/chrome/browser/printing/cloud_print/gcd_api_flow_unittest.cc index 2f5c919f..c26cd1da 100644 --- a/chrome/browser/printing/cloud_print/gcd_api_flow_unittest.cc +++ b/chrome/browser/printing/cloud_print/gcd_api_flow_unittest.cc
@@ -12,13 +12,13 @@ #include "base/values.h" #include "chrome/browser/printing/cloud_print/gcd_api_flow_impl.h" #include "content/public/test/test_browser_thread_bundle.h" -#include "google_apis/gaia/fake_oauth2_token_service.h" #include "google_apis/gaia/google_service_auth_error.h" #include "net/base/host_port_pair.h" #include "net/base/net_errors.h" #include "net/http/http_request_headers.h" #include "net/url_request/test_url_fetcher_factory.h" #include "net/url_request/url_request_test_util.h" +#include "services/identity/public/cpp/identity_test_environment.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -33,7 +33,7 @@ const char kFailedConfirmResponseBadJson[] = "[]"; -const char kAccountId[] = "account_id"; +const char kAccountId[] = "account_id@gmail.com"; class MockDelegate : public CloudPrintApiFlowRequest { public: @@ -48,38 +48,35 @@ public: GCDApiFlowTest() : request_context_(new net::TestURLRequestContextGetter( - base::ThreadTaskRunnerHandle::Get())), - account_id_(kAccountId) {} + base::ThreadTaskRunnerHandle::Get())) {} ~GCDApiFlowTest() override {} protected: void SetUp() override { - token_service_.GetFakeOAuth2TokenServiceDelegate()->set_request_context( - request_context_.get()); - token_service_.AddAccount(account_id_); + identity_test_environment_.MakePrimaryAccountAvailable(kAccountId); std::unique_ptr<MockDelegate> delegate = std::make_unique<MockDelegate>(); mock_delegate_ = delegate.get(); EXPECT_CALL(*mock_delegate_, GetURL()) .WillRepeatedly(Return( GURL("https://www.google.com/cloudprint/confirm?token=SomeToken"))); - gcd_flow_ = std::make_unique<GCDApiFlowImpl>(request_context_.get(), - &token_service_, account_id_); + gcd_flow_ = std::make_unique<GCDApiFlowImpl>( + request_context_.get(), identity_test_environment_.identity_manager()); gcd_flow_->Start(std::move(delegate)); } + identity::IdentityTestEnvironment identity_test_environment_; content::TestBrowserThreadBundle test_browser_thread_bundle_; scoped_refptr<net::TestURLRequestContextGetter> request_context_; net::TestURLFetcherFactory fetcher_factory_; - FakeOAuth2TokenService token_service_; - std::string account_id_; std::unique_ptr<GCDApiFlowImpl> gcd_flow_; MockDelegate* mock_delegate_; }; TEST_F(GCDApiFlowTest, SuccessOAuth2) { - gcd_flow_->OnGetTokenSuccess(NULL, "SomeToken", base::Time()); + gcd_flow_->OnAccessTokenFetchComplete(GoogleServiceAuthError::AuthErrorNone(), + "SomeToken"); net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0); EXPECT_EQ(GURL("https://www.google.com/cloudprint/confirm?token=SomeToken"), @@ -106,12 +103,14 @@ TEST_F(GCDApiFlowTest, BadToken) { EXPECT_CALL(*mock_delegate_, OnGCDApiFlowError(GCDApiFlow::ERROR_TOKEN)); - gcd_flow_->OnGetTokenFailure( - NULL, GoogleServiceAuthError(GoogleServiceAuthError::USER_NOT_SIGNED_UP)); + gcd_flow_->OnAccessTokenFetchComplete( + GoogleServiceAuthError(GoogleServiceAuthError::USER_NOT_SIGNED_UP), + std::string()); } TEST_F(GCDApiFlowTest, BadJson) { - gcd_flow_->OnGetTokenSuccess(NULL, "SomeToken", base::Time()); + gcd_flow_->OnAccessTokenFetchComplete(GoogleServiceAuthError::AuthErrorNone(), + "SomeToken"); net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0); EXPECT_EQ(GURL("https://www.google.com/cloudprint/confirm?token=SomeToken"),
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index dbdfb03..d73090ad 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc
@@ -142,6 +142,7 @@ #include "chrome/browser/chromeos/cryptauth/gcm_device_info_provider_impl.h" #include "chrome/browser/chromeos/locale_change_guard.h" #include "chrome/browser/chromeos/login/session/user_session_manager.h" +#include "chrome/browser/chromeos/net/delay_network_call.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/preferences.h" @@ -433,7 +434,11 @@ g_browser_process->platform_part()->GetAccountManagerFactory(); chromeos::AccountManager* account_manager = factory->GetAccountManager(path.value()); - account_manager->Initialize(path); + account_manager->Initialize( + path, g_browser_process->system_request_context(), + base::BindRepeating(&chromeos::DelayNetworkCall, + base::TimeDelta::FromMilliseconds( + chromeos::kDefaultNetworkRetryDelayMS))); } #endif
diff --git a/chrome/browser/profiles/profile_statistics_unittest.cc b/chrome/browser/profiles/profile_statistics_unittest.cc index 4fe0965e..04b3618 100644 --- a/chrome/browser/profiles/profile_statistics_unittest.cc +++ b/chrome/browser/profiles/profile_statistics_unittest.cc
@@ -19,6 +19,7 @@ #include "chrome/browser/profiles/profile_statistics_aggregator.h" #include "chrome/browser/profiles/profile_statistics_common.h" #include "chrome/browser/profiles/profile_statistics_factory.h" +#include "chrome/browser/sync/bookmark_sync_service_factory.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" @@ -27,6 +28,7 @@ #include "components/password_manager/core/browser/password_manager_test_utils.h" #include "components/password_manager/core/browser/test_password_store.h" #include "components/prefs/pref_service.h" +#include "components/sync_bookmarks/bookmark_sync_service.h" #include "content/public/browser/browser_thread.h" #include "content/public/test/test_browser_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h" @@ -38,7 +40,8 @@ Profile* profile = Profile::FromBrowserContext(context); std::unique_ptr<bookmarks::BookmarkModel> bookmark_model( new bookmarks::BookmarkModel(std::make_unique<ChromeBookmarkClient>( - profile, ManagedBookmarkServiceFactory::GetForProfile(profile)))); + profile, ManagedBookmarkServiceFactory::GetForProfile(profile), + BookmarkSyncServiceFactory::GetForProfile(profile)))); return std::move(bookmark_model); }
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc index 2b9674b..7f2ce59f 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
@@ -146,7 +146,7 @@ params.link_url = url; params.src_url = url; params.link_text = link_text; - params.page_url = web_contents->GetController().GetActiveEntry()->GetURL(); + params.page_url = web_contents->GetVisibleURL(); params.source_type = source_type; #if defined(OS_MACOSX) params.writing_direction_default = 0;
diff --git a/chrome/browser/signin/identity_manager_factory.cc b/chrome/browser/signin/identity_manager_factory.cc index fde02ad..423d520 100644 --- a/chrome/browser/signin/identity_manager_factory.cc +++ b/chrome/browser/signin/identity_manager_factory.cc
@@ -49,6 +49,13 @@ } // static +identity::IdentityManager* IdentityManagerFactory::GetForProfileIfExists( + Profile* profile) { + return static_cast<IdentityManagerWrapper*>( + GetInstance()->GetServiceForBrowserContext(profile, false)); +} + +// static IdentityManagerFactory* IdentityManagerFactory::GetInstance() { return base::Singleton<IdentityManagerFactory>::get(); }
diff --git a/chrome/browser/signin/identity_manager_factory.h b/chrome/browser/signin/identity_manager_factory.h index 18e4830..4bf10a9 100644 --- a/chrome/browser/signin/identity_manager_factory.h +++ b/chrome/browser/signin/identity_manager_factory.h
@@ -19,6 +19,7 @@ class IdentityManagerFactory : public BrowserContextKeyedServiceFactory { public: static identity::IdentityManager* GetForProfile(Profile* profile); + static identity::IdentityManager* GetForProfileIfExists(Profile* profile); // Returns an instance of the IdentityManagerFactory singleton. static IdentityManagerFactory* GetInstance();
diff --git a/chrome/browser/ssl/security_state_tab_helper_browsertest.cc b/chrome/browser/ssl/security_state_tab_helper_browsertest.cc index face88e..0ec3016 100644 --- a/chrome/browser/ssl/security_state_tab_helper_browsertest.cc +++ b/chrome/browser/ssl/security_state_tab_helper_browsertest.cc
@@ -302,7 +302,7 @@ net::X509Certificate* cert = browser->tab_strip_model() ->GetActiveWebContents() ->GetController() - .GetActiveEntry() + .GetVisibleEntry() ->GetSSL() .certificate.get(); EXPECT_TRUE(cert->EqualsExcludingChain(expected_cert)); @@ -326,7 +326,7 @@ net::X509Certificate* cert = browser->tab_strip_model() ->GetActiveWebContents() ->GetController() - .GetActiveEntry() + .GetLastCommittedEntry() ->GetSSL() .certificate.get(); EXPECT_TRUE(cert->EqualsExcludingChain(expected_cert));
diff --git a/chrome/browser/ssl/ssl_browsertest.cc b/chrome/browser/ssl/ssl_browsertest.cc index e3fb61b6..e8abccb 100644 --- a/chrome/browser/ssl/ssl_browsertest.cc +++ b/chrome/browser/ssl/ssl_browsertest.cc
@@ -1649,10 +1649,7 @@ GURL initial_url = https_server_.GetURL("/ssl/google.html"); ASSERT_EQ("127.0.0.1", initial_url.host()); ui_test_utils::NavigateToURL(browser(), initial_url); - WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); - NavigationEntry* entry = tab->GetController().GetActiveEntry(); - ASSERT_TRUE(entry); // Navigate from 127.0.0.1 to localhost so it triggers a // cross-site navigation to make sure http://crbug.com/5800 is gone. @@ -1757,9 +1754,7 @@ ui_test_utils::NavigateToURL( browser(), embedded_test_server()->GetURL("/ssl/google.html")); WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); - NavigationEntry* entry = tab->GetController().GetActiveEntry(); content::RenderFrameHost* rfh = tab->GetMainFrame(); - ASSERT_TRUE(entry); // Now go to a bad HTTPS page that shows an interstitial. ui_test_utils::NavigateToURL( @@ -1794,8 +1789,6 @@ ui_test_utils::NavigateToURL( browser(), embedded_test_server()->GetURL("/ssl/google.html")); WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); - NavigationEntry* entry = tab->GetController().GetActiveEntry(); - ASSERT_TRUE(entry); // Now go to a bad HTTPS page that shows an interstitial. ui_test_utils::NavigateToURL( @@ -1825,8 +1818,6 @@ ui_test_utils::NavigateToURL( browser(), embedded_test_server()->GetURL("/ssl/google.html")); WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); - NavigationEntry* entry = tab->GetController().GetActiveEntry(); - ASSERT_TRUE(entry); // Now go to a bad HTTPS page that shows an interstitial. ui_test_utils::NavigateToURL( @@ -1861,11 +1852,11 @@ ui_test_utils::NavigateToURL( browser(), embedded_test_server()->GetURL("/ssl/google.html")); WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); - NavigationEntry* entry1 = tab->GetController().GetActiveEntry(); + NavigationEntry* entry1 = tab->GetController().GetLastCommittedEntry(); ASSERT_TRUE(entry1); ui_test_utils::NavigateToURL( browser(), embedded_test_server()->GetURL("/ssl/blank_page.html")); - NavigationEntry* entry2 = tab->GetController().GetActiveEntry(); + NavigationEntry* entry2 = tab->GetController().GetLastCommittedEntry(); ASSERT_TRUE(entry2); // Now go back so that a page is in the forward history. @@ -1877,7 +1868,7 @@ observer.Wait(); } ASSERT_TRUE(tab->GetController().CanGoForward()); - NavigationEntry* entry3 = tab->GetController().GetActiveEntry(); + NavigationEntry* entry3 = tab->GetController().GetLastCommittedEntry(); ASSERT_TRUE(entry1 == entry3); // Now go to a bad HTTPS page that shows an interstitial. @@ -1899,7 +1890,7 @@ EXPECT_FALSE(IsShowingInterstitial(tab)); CheckUnauthenticatedState(tab, AuthState::NONE); EXPECT_FALSE(tab->GetController().CanGoForward()); - NavigationEntry* entry4 = tab->GetController().GetActiveEntry(); + NavigationEntry* entry4 = tab->GetController().GetLastCommittedEntry(); EXPECT_TRUE(entry2 == entry4); } @@ -1935,7 +1926,7 @@ ->tab_strip_model() ->GetActiveWebContents() ->GetController() - .GetActiveEntry(); + .GetVisibleEntry(); ASSERT_TRUE(entry); EXPECT_TRUE(entry->GetSSL().cert_status & net::CERT_STATUS_REV_CHECKING_ENABLED); @@ -1991,7 +1982,7 @@ ->tab_strip_model() ->GetActiveWebContents() ->GetController() - .GetActiveEntry(); + .GetVisibleEntry(); ASSERT_TRUE(entry); EXPECT_FALSE(entry->GetSSL().cert_status & net::CERT_STATUS_REV_CHECKING_ENABLED); @@ -4660,13 +4651,13 @@ WaitForInterstitial(tab); EXPECT_TRUE(IsShowingInterstitial(tab)); - content::NavigationEntry* entry = tab->GetController().GetActiveEntry(); + content::NavigationEntry* entry = tab->GetController().GetVisibleEntry(); ASSERT_TRUE(entry); content::SSLStatus interstitial_ssl_status = entry->GetSSL(); ProceedThroughInterstitial(tab); EXPECT_FALSE(tab->ShowingInterstitialPage()); - entry = tab->GetController().GetActiveEntry(); + entry = tab->GetController().GetLastCommittedEntry(); ASSERT_TRUE(entry); content::SSLStatus after_interstitial_ssl_status = entry->GetSSL(); @@ -4696,7 +4687,7 @@ ASSERT_NO_FATAL_FAILURE(ExpectBadClockInterstitial(tab)); // Grab the SSLStatus on the clock interstitial. - content::NavigationEntry* entry = tab->GetController().GetActiveEntry(); + content::NavigationEntry* entry = tab->GetController().GetVisibleEntry(); ASSERT_TRUE(entry); content::SSLStatus clock_interstitial_ssl_status = entry->GetSSL(); @@ -4712,7 +4703,7 @@ // Grab the SSLStatus from the page and check that it is the same as // on the clock interstitial. - entry = tab->GetController().GetActiveEntry(); + entry = tab->GetController().GetLastCommittedEntry(); ASSERT_TRUE(entry); content::SSLStatus after_interstitial_ssl_status = entry->GetSSL(); EXPECT_TRUE(ComparePreAndPostInterstitialSSLStatuses(
diff --git a/chrome/browser/ssl/ssl_browsertest_util.cc b/chrome/browser/ssl/ssl_browsertest_util.cc index 58c70bf..c7cb3cea 100644 --- a/chrome/browser/ssl/ssl_browsertest_util.cc +++ b/chrome/browser/ssl/ssl_browsertest_util.cc
@@ -88,7 +88,10 @@ security_state::SecurityLevel expected_security_level, int expected_authentication_state) { ASSERT_FALSE(tab->IsCrashed()); - content::NavigationEntry* entry = tab->GetController().GetActiveEntry(); + content::NavigationEntry* entry = + tab->ShowingInterstitialPage() + ? tab->GetController().GetTransientEntry() + : tab->GetController().GetLastCommittedEntry(); ASSERT_TRUE(entry); CertError::Check(*entry, expected_error); SecurityStyle::Check(tab, expected_security_level);
diff --git a/chrome/browser/supervised_user/supervised_user_browsertest.cc b/chrome/browser/supervised_user/supervised_user_browsertest.cc index 16af4e5..42417fe 100644 --- a/chrome/browser/supervised_user/supervised_user_browsertest.cc +++ b/chrome/browser/supervised_user/supervised_user_browsertest.cc
@@ -108,7 +108,7 @@ if (AreCommittedInterstitialsEnabled()) { base::string16 title; ui_test_utils::GetCurrentTabTitle(browser, &title); - return tab->GetController().GetActiveEntry()->GetPageType() == + return tab->GetController().GetLastCommittedEntry()->GetPageType() == content::PAGE_TYPE_ERROR && title == base::ASCIIToUTF16("Site blocked"); }
diff --git a/chrome/browser/supervised_user/supervised_user_interstitial.cc b/chrome/browser/supervised_user/supervised_user_interstitial.cc index 2c479b04..4d88524 100644 --- a/chrome/browser/supervised_user/supervised_user_interstitial.cc +++ b/chrome/browser/supervised_user/supervised_user_interstitial.cc
@@ -186,7 +186,7 @@ DCHECK(details.is_navigation_to_different_page()); const content::NavigationController& controller = web_contents_->GetController(); - details.entry = controller.GetActiveEntry(); + details.entry = controller.GetVisibleEntry(); if (controller.GetLastCommittedEntry()) { details.previous_entry_index = controller.GetLastCommittedEntryIndex(); details.previous_url = controller.GetLastCommittedEntry()->GetURL();
diff --git a/chrome/browser/supervised_user/supervised_user_navigation_throttle_browsertest.cc b/chrome/browser/supervised_user/supervised_user_navigation_throttle_browsertest.cc index d9a6aeb..98dceac 100644 --- a/chrome/browser/supervised_user/supervised_user_navigation_throttle_browsertest.cc +++ b/chrome/browser/supervised_user/supervised_user_navigation_throttle_browsertest.cc
@@ -83,7 +83,7 @@ if (AreCommittedInterstitialsEnabled()) { base::string16 title; ui_test_utils::GetCurrentTabTitle(browser, &title); - return tab->GetController().GetActiveEntry()->GetPageType() == + return tab->GetController().GetLastCommittedEntry()->GetPageType() == content::PAGE_TYPE_ERROR && title == base::ASCIIToUTF16("Site blocked"); } @@ -133,7 +133,7 @@ controller.LoadURL(GURL("http://www.example.com"), content::Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); observer.Wait(); - content::NavigationEntry* entry = controller.GetActiveEntry(); + content::NavigationEntry* entry = controller.GetVisibleEntry(); ASSERT_TRUE(entry); EXPECT_EQ(content::PAGE_TYPE_NORMAL, entry->GetPageType()); EXPECT_FALSE(observer.last_navigation_succeeded());
diff --git a/chrome/browser/sync/bookmark_sync_service_factory.cc b/chrome/browser/sync/bookmark_sync_service_factory.cc new file mode 100644 index 0000000..897bdd5 --- /dev/null +++ b/chrome/browser/sync/bookmark_sync_service_factory.cc
@@ -0,0 +1,44 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/sync/bookmark_sync_service_factory.h" + +#include "chrome/browser/profiles/incognito_helpers.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/undo/bookmark_undo_service_factory.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "components/sync_bookmarks/bookmark_sync_service.h" + +// static +sync_bookmarks::BookmarkSyncService* BookmarkSyncServiceFactory::GetForProfile( + Profile* profile) { + return static_cast<sync_bookmarks::BookmarkSyncService*>( + GetInstance()->GetServiceForBrowserContext(profile, true)); +} + +// static +BookmarkSyncServiceFactory* BookmarkSyncServiceFactory::GetInstance() { + return base::Singleton<BookmarkSyncServiceFactory>::get(); +} + +BookmarkSyncServiceFactory::BookmarkSyncServiceFactory() + : BrowserContextKeyedServiceFactory( + "BookmarkSyncServiceFactory", + BrowserContextDependencyManager::GetInstance()) { + DependsOn(BookmarkUndoServiceFactory::GetInstance()); +} + +BookmarkSyncServiceFactory::~BookmarkSyncServiceFactory() {} + +KeyedService* BookmarkSyncServiceFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + Profile* profile = Profile::FromBrowserContext(context); + return new sync_bookmarks::BookmarkSyncService( + BookmarkUndoServiceFactory::GetForProfileIfExists(profile)); +} + +content::BrowserContext* BookmarkSyncServiceFactory::GetBrowserContextToUse( + content::BrowserContext* context) const { + return chrome::GetBrowserContextRedirectedInIncognito(context); +}
diff --git a/chrome/browser/sync/bookmark_sync_service_factory.h b/chrome/browser/sync/bookmark_sync_service_factory.h new file mode 100644 index 0000000..4a9e2ef --- /dev/null +++ b/chrome/browser/sync/bookmark_sync_service_factory.h
@@ -0,0 +1,42 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SYNC_BOOKMARK_SYNC_SERVICE_FACTORY_H_ +#define CHROME_BROWSER_SYNC_BOOKMARK_SYNC_SERVICE_FACTORY_H_ + +#include "base/memory/singleton.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +class Profile; + +namespace sync_bookmarks { +class BookmarkSyncService; +} + +// Singleton that owns the bookmark sync service. +class BookmarkSyncServiceFactory : public BrowserContextKeyedServiceFactory { + public: + // Returns the instance of BookmarkSyncService associated with this profile + // (creating one if none exists). + static sync_bookmarks::BookmarkSyncService* GetForProfile(Profile* profile); + + // Returns an instance of the BookmarkSyncServiceFactory singleton. + static BookmarkSyncServiceFactory* GetInstance(); + + private: + friend struct base::DefaultSingletonTraits<BookmarkSyncServiceFactory>; + + BookmarkSyncServiceFactory(); + ~BookmarkSyncServiceFactory() override; + + // BrowserContextKeyedServiceFactory implementation. + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* profile) const override; + content::BrowserContext* GetBrowserContextToUse( + content::BrowserContext* context) const override; + + DISALLOW_COPY_AND_ASSIGN(BookmarkSyncServiceFactory); +}; + +#endif // CHROME_BROWSER_SYNC_BOOKMARK_SYNC_SERVICE_FACTORY_H_
diff --git a/chrome/browser/sync/chrome_sync_client.cc b/chrome/browser/sync/chrome_sync_client.cc index 602bb08..47a8863 100644 --- a/chrome/browser/sync/chrome_sync_client.cc +++ b/chrome/browser/sync/chrome_sync_client.cc
@@ -25,6 +25,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/search_engines/template_url_service_factory.h" +#include "chrome/browser/sync/bookmark_sync_service_factory.h" #include "chrome/browser/sync/glue/sync_start_util.h" #include "chrome/browser/sync/glue/theme_data_type_controller.h" #include "chrome/browser/sync/profile_sync_service_factory.h" @@ -68,6 +69,7 @@ #include "components/sync/engine/sequenced_model_worker.h" #include "components/sync/engine/ui_model_worker.h" #include "components/sync/user_events/user_event_service.h" +#include "components/sync_bookmarks/bookmark_sync_service.h" #include "components/sync_preferences/pref_service_syncable.h" #include "components/sync_sessions/favicon_cache.h" #include "components/sync_sessions/session_sync_bridge.h" @@ -514,7 +516,7 @@ ->GetSessionSyncControllerDelegateOnUIThread(); } case syncer::BOOKMARKS: { - return ProfileSyncServiceFactory::GetForProfile(profile_) + return BookmarkSyncServiceFactory::GetForProfile(profile_) ->GetBookmarkSyncControllerDelegateOnUIThread(); } default:
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 6d663681..4eb35df0 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -593,6 +593,8 @@ "autofill/popup_controller_common.h", "autofill/popup_view_common.cc", "autofill/popup_view_common.h", + "bloated_renderer/bloated_renderer_tab_helper.cc", + "bloated_renderer/bloated_renderer_tab_helper.h", "blocked_content/blocked_window_params.cc", "blocked_content/blocked_window_params.h", "blocked_content/list_item_position.cc", @@ -2994,8 +2996,12 @@ "views/webauthn/authenticator_request_dialog_view.h", "views/webauthn/authenticator_request_sheet_view.cc", "views/webauthn/authenticator_request_sheet_view.h", + "views/webauthn/authenticator_transport_selector_sheet_view.cc", + "views/webauthn/authenticator_transport_selector_sheet_view.h", "views/webauthn/sheet_view_factory.cc", "views/webauthn/sheet_view_factory.h", + "views/webauthn/transport_list_view.cc", + "views/webauthn/transport_list_view.h", "webauthn/authenticator_request_sheet_model.h", "webauthn/sheet_models.cc", "webauthn/sheet_models.h",
diff --git a/chrome/browser/ui/bloated_renderer/OWNERS b/chrome/browser/ui/bloated_renderer/OWNERS new file mode 100644 index 0000000..31698482 --- /dev/null +++ b/chrome/browser/ui/bloated_renderer/OWNERS
@@ -0,0 +1,3 @@ +ulan@chromium.org + +# COMPONENT: Blink>JavaScript
diff --git a/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.cc b/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.cc new file mode 100644 index 0000000..0e81edf --- /dev/null +++ b/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.cc
@@ -0,0 +1,41 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.h" + +#include "chrome/browser/infobars/infobar_service.h" +#include "chrome/grit/generated_resources.h" +#include "components/infobars/core/simple_alert_infobar_delegate.h" +#include "ui/base/l10n/l10n_util.h" + +DEFINE_WEB_CONTENTS_USER_DATA_KEY(BloatedRendererTabHelper); + +BloatedRendererTabHelper::BloatedRendererTabHelper( + content::WebContents* contents) + : content::WebContentsObserver(contents) {} + +void BloatedRendererTabHelper::WillReloadPageWithBloatedRenderer() { + reloading_bloated_renderer_ = true; +} + +void BloatedRendererTabHelper::DidFinishNavigation( + content::NavigationHandle* navigation_handle) { + // TODO(ulan): Use nagivation_handle to ensure that the finished navigation + // is the same nagivation started by reloading the bloated tab. + if (reloading_bloated_renderer_) { + ShowInfoBar(InfoBarService::FromWebContents(web_contents())); + reloading_bloated_renderer_ = false; + } +} + +void BloatedRendererTabHelper::ShowInfoBar(InfoBarService* infobar_service) { + if (!infobar_service) { + // No infobar service in unit-tests. + return; + } + SimpleAlertInfoBarDelegate::Create( + infobar_service, + infobars::InfoBarDelegate::BLOATED_RENDERER_INFOBAR_DELEGATE, nullptr, + l10n_util::GetStringUTF16(IDS_BROWSER_BLOATED_RENDERER_INFOBAR), false); +}
diff --git a/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.h b/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.h new file mode 100644 index 0000000..676e37ba --- /dev/null +++ b/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.h
@@ -0,0 +1,51 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_BLOATED_RENDERER_BLOATED_RENDERER_TAB_HELPER_H_ +#define CHROME_BROWSER_UI_BLOATED_RENDERER_BLOATED_RENDERER_TAB_HELPER_H_ + +#include "base/gtest_prod_util.h" +#include "base/macros.h" +#include "content/public/browser/web_contents_observer.h" +#include "content/public/browser/web_contents_user_data.h" + +class InfoBarService; + +// This tab helper observes the WillReloadBloatedRenderer event. Upon +// receiving the event, it activates the logic to show an infobar on the +// subsequent DidFinishNavigation event. +// +// Assumptions around the WillReloadBloatedRenderer event: +// - The renderer process was shutdown before it. +// - Page reload will be performed immediately after it. +// This ensures that the first DidFinishNavigation after it originates from +// reloading the bloated page. +// +// Note that we need to show the infobar after NavigationEntryCommitted +// because the infobar service removes existing infobars there. +class BloatedRendererTabHelper + : public content::WebContentsObserver, + public content::WebContentsUserData<BloatedRendererTabHelper> { + public: + ~BloatedRendererTabHelper() override = default; + + // content::WebContentsObserver: + void DidFinishNavigation( + content::NavigationHandle* navigation_handle) override; + + void WillReloadPageWithBloatedRenderer(); + static void ShowInfoBar(InfoBarService* infobar_service); + + private: + friend class content::WebContentsUserData<BloatedRendererTabHelper>; + FRIEND_TEST_ALL_PREFIXES(BloatedRendererTabHelperTest, DetectReload); + + explicit BloatedRendererTabHelper(content::WebContents* contents); + + bool reloading_bloated_renderer_ = false; + + DISALLOW_COPY_AND_ASSIGN(BloatedRendererTabHelper); +}; + +#endif // CHROME_BROWSER_UI_BLOATED_RENDERER_BLOATED_RENDERER_TAB_HELPER_H_
diff --git a/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper_unittest.cc b/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper_unittest.cc new file mode 100644 index 0000000..6545306 --- /dev/null +++ b/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper_unittest.cc
@@ -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. + +#include "chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.h" +#include "chrome/test/base/chrome_render_view_host_test_harness.h" +#include "testing/gtest/include/gtest/gtest.h" + +class BloatedRendererTabHelperTest : public ChromeRenderViewHostTestHarness {}; + +TEST_F(BloatedRendererTabHelperTest, DetectReload) { + BloatedRendererTabHelper::CreateForWebContents(web_contents()); + BloatedRendererTabHelper* helper = + BloatedRendererTabHelper::FromWebContents(web_contents()); + EXPECT_FALSE(helper->reloading_bloated_renderer_); + helper->WillReloadPageWithBloatedRenderer(); + EXPECT_TRUE(helper->reloading_bloated_renderer_); + helper->DidFinishNavigation(nullptr); + EXPECT_FALSE(helper->reloading_bloated_renderer_); +}
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc index 1d8b9a7..1bb23bc 100644 --- a/chrome/browser/ui/tab_helpers.cc +++ b/chrome/browser/ui/tab_helpers.cc
@@ -55,6 +55,7 @@ #include "chrome/browser/tracing/navigation_tracing.h" #include "chrome/browser/translate/chrome_translate_client.h" #include "chrome/browser/ui/autofill/chrome_autofill_client.h" +#include "chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.h" #include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h" #include "chrome/browser/ui/blocked_content/popup_opener_tab_helper.h" #include "chrome/browser/ui/find_bar/find_tab_helper.h" @@ -187,6 +188,7 @@ autofill::ChromeAutofillClient::FromWebContents(web_contents), g_browser_process->GetApplicationLocale(), autofill::AutofillManager::ENABLE_AUTOFILL_DOWNLOAD_MANAGER); + BloatedRendererTabHelper::CreateForWebContents(web_contents); BookmarkLastVisitUpdater::MaybeCreateForWebContentsWithBookmarkModel( web_contents, BookmarkModelFactory::GetForBrowserContext( web_contents->GetBrowserContext()));
diff --git a/chrome/browser/ui/views/webauthn/authenticator_transport_selector_sheet_view.cc b/chrome/browser/ui/views/webauthn/authenticator_transport_selector_sheet_view.cc new file mode 100644 index 0000000..40a950d --- /dev/null +++ b/chrome/browser/ui/views/webauthn/authenticator_transport_selector_sheet_view.cc
@@ -0,0 +1,25 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/views/webauthn/authenticator_transport_selector_sheet_view.h" + +#include <utility> + +AuthenticatorTransportSelectorSheetView:: + AuthenticatorTransportSelectorSheetView( + std::unique_ptr<AuthenticatorTransportSelectorSheetModel> model) + : AuthenticatorRequestSheetView(std::move(model)) {} +AuthenticatorTransportSelectorSheetView:: + ~AuthenticatorTransportSelectorSheetView() = default; + +std::unique_ptr<views::View> +AuthenticatorTransportSelectorSheetView::BuildStepSpecificContent() { + return std::make_unique<TransportListView>( + model()->dialog_model()->transport_list_model(), this); +} + +void AuthenticatorTransportSelectorSheetView::OnListItemSelected( + AuthenticatorTransport transport) { + model()->OnTransportSelected(transport); +}
diff --git a/chrome/browser/ui/views/webauthn/authenticator_transport_selector_sheet_view.h b/chrome/browser/ui/views/webauthn/authenticator_transport_selector_sheet_view.h new file mode 100644 index 0000000..4780db0 --- /dev/null +++ b/chrome/browser/ui/views/webauthn/authenticator_transport_selector_sheet_view.h
@@ -0,0 +1,39 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_WEBAUTHN_AUTHENTICATOR_TRANSPORT_SELECTOR_SHEET_VIEW_H_ +#define CHROME_BROWSER_UI_VIEWS_WEBAUTHN_AUTHENTICATOR_TRANSPORT_SELECTOR_SHEET_VIEW_H_ + +#include "base/macros.h" +#include "chrome/browser/ui/views/webauthn/authenticator_request_sheet_view.h" +#include "chrome/browser/ui/views/webauthn/transport_list_view.h" +#include "chrome/browser/ui/webauthn/sheet_models.h" + +// Represents a sheet in the Web Authentication request dialog that allows the +// user to pick the transport protocol over which they wish to use their +// security key. +class AuthenticatorTransportSelectorSheetView + : public AuthenticatorRequestSheetView, + public TransportListView::Delegate { + public: + explicit AuthenticatorTransportSelectorSheetView( + std::unique_ptr<AuthenticatorTransportSelectorSheetModel> model); + ~AuthenticatorTransportSelectorSheetView() override; + + private: + AuthenticatorTransportSelectorSheetModel* model() { + return static_cast<AuthenticatorTransportSelectorSheetModel*>( + AuthenticatorRequestSheetView::model()); + } + + // AuthenticatorRequestSheetView: + std::unique_ptr<views::View> BuildStepSpecificContent() override; + + // TransportListView::Delegate: + void OnListItemSelected(AuthenticatorTransport transport) override; + + DISALLOW_COPY_AND_ASSIGN(AuthenticatorTransportSelectorSheetView); +}; + +#endif // CHROME_BROWSER_UI_VIEWS_WEBAUTHN_AUTHENTICATOR_TRANSPORT_SELECTOR_SHEET_VIEW_H_
diff --git a/chrome/browser/ui/views/webauthn/sheet_view_factory.cc b/chrome/browser/ui/views/webauthn/sheet_view_factory.cc index 5232194..c2c513a 100644 --- a/chrome/browser/ui/views/webauthn/sheet_view_factory.cc +++ b/chrome/browser/ui/views/webauthn/sheet_view_factory.cc
@@ -6,6 +6,7 @@ #include "base/logging.h" #include "chrome/browser/ui/views/webauthn/authenticator_request_sheet_view.h" +#include "chrome/browser/ui/views/webauthn/authenticator_transport_selector_sheet_view.h" #include "chrome/browser/ui/webauthn/sheet_models.h" #include "chrome/browser/webauthn/authenticator_request_dialog_model.h" @@ -37,6 +38,10 @@ std::make_unique<AuthenticatorInitialSheetModel>(dialog_model)); break; case Step::kTransportSelection: + sheet_view = std::make_unique<AuthenticatorTransportSelectorSheetView>( + std::make_unique<AuthenticatorTransportSelectorSheetModel>( + dialog_model)); + break; case Step::kErrorTimedOut: case Step::kCompleted: case Step::kUsbInsert:
diff --git a/chrome/browser/ui/views/webauthn/transport_list_view.cc b/chrome/browser/ui/views/webauthn/transport_list_view.cc new file mode 100644 index 0000000..6a6f926a --- /dev/null +++ b/chrome/browser/ui/views/webauthn/transport_list_view.cc
@@ -0,0 +1,160 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/views/webauthn/transport_list_view.h" + +#include "base/logging.h" +#include "base/strings/string16.h" +#include "chrome/app/vector_icons/vector_icons.h" +#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" +#include "chrome/browser/ui/views/harmony/chrome_typography.h" +#include "chrome/browser/ui/views/hover_button.h" +#include "chrome/grit/generated_resources.h" +#include "components/vector_icons/vector_icons.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/gfx/color_palette.h" +#include "ui/gfx/color_utils.h" +#include "ui/gfx/paint_vector_icon.h" +#include "ui/views/controls/label.h" +#include "ui/views/controls/separator.h" +#include "ui/views/layout/box_layout.h" +#include "ui/views/vector_icons.h" + +namespace { + +// Gets the message ID for the human readable name of |transport|. +int GetHumanReadableTransportNameMessageId(AuthenticatorTransport transport) { + switch (transport) { + case AuthenticatorTransport::kBluetoothLowEnergy: + return IDS_WEBAUTHN_TRANSPORT_BLE; + case AuthenticatorTransport::kNearFieldCommunication: + return IDS_WEBAUTHN_TRANSPORT_NFC; + case AuthenticatorTransport::kUsb: + return IDS_WEBAUTHN_TRANSPORT_USB; + case AuthenticatorTransport::kInternal: + return IDS_WEBAUTHN_TRANSPORT_INTERNAL; + case AuthenticatorTransport::kCloudAssistedBluetoothLowEnergy: + return IDS_WEBAUTHN_TRANSPORT_CABLE; + } + NOTREACHED(); + return 0; +} + +// Gets the vector icon depicting the given |transport|. +const gfx::VectorIcon& GetTransportVectorIcon( + AuthenticatorTransport transport) { + switch (transport) { + case AuthenticatorTransport::kBluetoothLowEnergy: + return kBluetoothIcon; + case AuthenticatorTransport::kNearFieldCommunication: + return kNfcIcon; + case AuthenticatorTransport::kUsb: + return vector_icons::kUsbIcon; + case AuthenticatorTransport::kInternal: + return kFingerprintIcon; + case AuthenticatorTransport::kCloudAssistedBluetoothLowEnergy: + return kSmartphoneIcon; + } + NOTREACHED(); + return kFingerprintIcon; +} + +// Creates, for a given transport, the corresponding row in the transport list, +// containing an icon, a human-readable name, and a chevron at the right: +// +// +--------------------------------+ +// | ICON | Transport name | > | +// +--------------------------------+ +// +std::unique_ptr<HoverButton> CreateTransportListItemView( + AuthenticatorTransport transport, + views::ButtonListener* listener) { + // Derive the icon color from the text color of an enabled label. + auto color_reference_label = std::make_unique<views::Label>( + base::string16(), CONTEXT_BODY_TEXT_SMALL, views::style::STYLE_PRIMARY); + const SkColor icon_color = color_utils::DeriveDefaultIconColor( + color_reference_label->enabled_color()); + + constexpr int kTransportIconSize = 24; + auto transport_image = std::make_unique<views::ImageView>(); + transport_image->SetImage(gfx::CreateVectorIcon( + GetTransportVectorIcon(transport), kTransportIconSize, icon_color)); + + base::string16 transport_name = l10n_util::GetStringUTF16( + GetHumanReadableTransportNameMessageId(transport)); + + auto chevron_image = std::make_unique<views::ImageView>(); + chevron_image->SetImage( + gfx::CreateVectorIcon(views::kSubmenuArrowIcon, icon_color)); + + auto hover_button = std::make_unique<HoverButton>( + listener, std::move(transport_image), transport_name, + base::string16() /* subtitle */, std::move(chevron_image)); + hover_button->set_tag(static_cast<int>(transport)); + return hover_button; +} + +void AddSeparatorAsChild(views::View* view) { + auto separator = std::make_unique<views::Separator>(); + separator->SetColor(gfx::kGoogleGrey900); + view->AddChildView(separator.release()); +} + +} // namespace + +// TransportListView --------------------------------------------------------- + +TransportListView::TransportListView(TransportListModel* model, + Delegate* delegate) + : model_(model), delegate_(delegate) { + DCHECK(model_); + model_->AddObserver(this); + + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::kVertical, gfx::Insets(), 0)); + AddSeparatorAsChild(this); + for (size_t index = 0; index < model_->transports().size(); ++index) { + const std::vector<AuthenticatorTransport>& transports = + model_->transports(); + AddViewForListItem(index, transports[index]); + } +} + +TransportListView::~TransportListView() { + if (model_) { + model_->RemoveObserver(this); + model_ = nullptr; + } +} + +void TransportListView::AddViewForListItem(size_t index, + AuthenticatorTransport transport) { + std::unique_ptr<HoverButton> list_item_view = + CreateTransportListItemView(transport, this); + AddChildView(list_item_view.release()); + AddSeparatorAsChild(this); +} + +void TransportListView::OnModelDestroyed() { + model_ = nullptr; +} + +void TransportListView::OnTransportAppended() { + DCHECK(!model_->transports().empty()); + AddViewForListItem(model_->transports().size() - 1, + model_->transports().back()); + + // TODO(engedy): The enclosing dialog may also need to be resized, similarly + // to what is done in AuthenticatorRequestDialogView::ReplaceSheetWith(). + Layout(); +} + +void TransportListView::ButtonPressed(views::Button* sender, + const ui::Event& event) { + if (!delegate_) + return; + + auto transport = static_cast<AuthenticatorTransport>(sender->tag()); + delegate_->OnListItemSelected(transport); +}
diff --git a/chrome/browser/ui/views/webauthn/transport_list_view.h b/chrome/browser/ui/views/webauthn/transport_list_view.h new file mode 100644 index 0000000..13f6f60 --- /dev/null +++ b/chrome/browser/ui/views/webauthn/transport_list_view.h
@@ -0,0 +1,57 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_WEBAUTHN_TRANSPORT_LIST_VIEW_H_ +#define CHROME_BROWSER_UI_VIEWS_WEBAUTHN_TRANSPORT_LIST_VIEW_H_ + +#include <stddef.h> + +#include "base/macros.h" +#include "chrome/browser/webauthn/transport_list_model.h" +#include "ui/views/controls/button/button.h" +#include "ui/views/view.h" + +// Represents a view that shows a list of transports available on a platform. +// +// +----------------------------------+ +// | ICON1 | Transport 1 name | > | +// +----------------------------------+ +// | ICON2 | Transport 2 name | > | +// +----------------------------------+ +// | ICON3 | Transport 3 name | > | +// +----------------------------------+ +// +class TransportListView : public views::View, + public views::ButtonListener, + public TransportListModel::Observer { + public: + // Interface that the client should implement to learn when the user clicks on + // one of the items. + class Delegate { + public: + virtual void OnListItemSelected(AuthenticatorTransport transport) = 0; + }; + + // The |model| and |delegate| must outlive this object, but the |delegate| may + // be a nullptr. + TransportListView(TransportListModel* model, Delegate* delegate); + ~TransportListView() override; + + private: + void AddViewForListItem(size_t index, AuthenticatorTransport transport); + + // TransportListModel::Observer: + void OnModelDestroyed() override; + void OnTransportAppended() override; + + // views::ButtonListener: + void ButtonPressed(views::Button* sender, const ui::Event& event) override; + + TransportListModel* model_; // Weak. + Delegate* const delegate_; // Weak, may be nullptr. + + DISALLOW_COPY_AND_ASSIGN(TransportListView); +}; + +#endif // CHROME_BROWSER_UI_VIEWS_WEBAUTHN_TRANSPORT_LIST_VIEW_H_
diff --git a/chrome/browser/ui/webauthn/authenticator_dialog_browsertest.cc b/chrome/browser/ui/webauthn/authenticator_dialog_browsertest.cc index f68d7345..c9e5bb2d 100644 --- a/chrome/browser/ui/webauthn/authenticator_dialog_browsertest.cc +++ b/chrome/browser/ui/webauthn/authenticator_dialog_browsertest.cc
@@ -22,8 +22,18 @@ // The dialog should immediately close as soon as it is displayed. if (name == "completed") { - model->set_current_step( - AuthenticatorRequestDialogModel::Step::kCompleted); + model->SetCurrentStep(AuthenticatorRequestDialogModel::Step::kCompleted); + } else if (name == "transports") { + TransportListModel* transports = model->transport_list_model(); + transports->AppendTransport(AuthenticatorTransport::kBluetoothLowEnergy); + transports->AppendTransport(AuthenticatorTransport::kUsb); + transports->AppendTransport( + AuthenticatorTransport::kNearFieldCommunication); + transports->AppendTransport(AuthenticatorTransport::kInternal); + transports->AppendTransport( + AuthenticatorTransport::kCloudAssistedBluetoothLowEnergy); + model->SetCurrentStep( + AuthenticatorRequestDialogModel::Step::kTransportSelection); } ShowAuthenticatorRequestDialog( @@ -44,3 +54,7 @@ IN_PROC_BROWSER_TEST_F(AuthenticatorDialogTest, InvokeUi_completed) { ShowAndVerifyUi(); } + +IN_PROC_BROWSER_TEST_F(AuthenticatorDialogTest, InvokeUi_transports) { + ShowAndVerifyUi(); +}
diff --git a/chrome/browser/ui/webauthn/sheet_models.cc b/chrome/browser/ui/webauthn/sheet_models.cc index 576987e..682d397 100644 --- a/chrome/browser/ui/webauthn/sheet_models.cc +++ b/chrome/browser/ui/webauthn/sheet_models.cc
@@ -78,3 +78,19 @@ base::string16 AuthenticatorInitialSheetModel::GetStepDescription() const { return l10n_util::GetStringUTF16(IDS_WEBAUTHN_DIALOG_DESCRIPTION); } + +// AuthenticatorTransportSelectorSheetModel ----------------------------------- + +base::string16 AuthenticatorTransportSelectorSheetModel::GetStepTitle() const { + return l10n_util::GetStringUTF16(IDS_WEBAUTHN_DIALOG_TITLE); +} + +base::string16 AuthenticatorTransportSelectorSheetModel::GetStepDescription() + const { + return l10n_util::GetStringUTF16(IDS_WEBAUTHN_DIALOG_DESCRIPTION); +} + +void AuthenticatorTransportSelectorSheetModel::OnTransportSelected( + AuthenticatorTransport transport) { + dialog_model()->StartGuidedFlowForTransport(transport); +}
diff --git a/chrome/browser/ui/webauthn/sheet_models.h b/chrome/browser/ui/webauthn/sheet_models.h index 86758b3..028c650 100644 --- a/chrome/browser/ui/webauthn/sheet_models.h +++ b/chrome/browser/ui/webauthn/sheet_models.h
@@ -8,6 +8,7 @@ #include "base/macros.h" #include "chrome/browser/ui/webauthn/authenticator_request_sheet_model.h" #include "chrome/browser/webauthn/authenticator_request_dialog_model.h" +#include "chrome/browser/webauthn/transport_list_model.h" // Base class for sheets, implementing the shared behavior used on most sheets, // as well as maintaining a weak pointer to the dialog model. @@ -19,11 +20,11 @@ AuthenticatorRequestDialogModel* dialog_model); ~AuthenticatorSheetModelBase() override; - protected: AuthenticatorRequestDialogModel* dialog_model() const { return dialog_model_; } + protected: // AuthenticatorRequestSheetModel: bool IsBackButtonVisible() const override; bool IsCancelButtonVisible() const override; @@ -55,4 +56,21 @@ base::string16 GetStepDescription() const override; }; +// The sheet shown for selecting the transport over which the security key +// should be accessed. +class AuthenticatorTransportSelectorSheetModel + : public AuthenticatorSheetModelBase { + public: + using AuthenticatorSheetModelBase::AuthenticatorSheetModelBase; + + // Initiates the step-by-step flow with the the transport at the given |index| + // selected by the user. + void OnTransportSelected(AuthenticatorTransport transport); + + private: + // AuthenticatorSheetModelBase: + base::string16 GetStepTitle() const override; + base::string16 GetStepDescription() const override; +}; + #endif // CHROME_BROWSER_UI_WEBAUTHN_SHEET_MODELS_H_
diff --git a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.cc b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.cc index 8517d88..1ad7ece 100644 --- a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.cc +++ b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.cc
@@ -20,8 +20,7 @@ #include "chrome/browser/printing/cloud_print/privet_device_lister_impl.h" #include "chrome/browser/printing/cloud_print/privet_http_asynchronous_factory.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" -#include "chrome/browser/signin/signin_manager_factory.h" +#include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/chrome_pages.h" @@ -29,7 +28,6 @@ #include "chrome/grit/generated_resources.h" #include "components/cloud_devices/common/cloud_devices_urls.h" #include "components/prefs/pref_service.h" -#include "components/signin/core/browser/profile_oauth2_token_service.h" #include "content/public/browser/web_ui.h" #include "printing/buildflags/buildflags.h" #include "ui/base/l10n/l10n_util.h" @@ -104,10 +102,10 @@ LocalDiscoveryUIHandler::~LocalDiscoveryUIHandler() { Profile* profile = Profile::FromWebUI(web_ui()); - SigninManagerBase* signin_manager = - SigninManagerFactory::GetInstance()->GetForProfile(profile); - if (signin_manager) - signin_manager->RemoveObserver(this); + identity::IdentityManager* identity_manager = + IdentityManagerFactory::GetForProfile(profile); + if (identity_manager) + identity_manager->RemoveObserver(this); ResetCurrentRegistration(); SetIsVisible(false); } @@ -174,10 +172,10 @@ cloud_print::PrivetHTTPAsynchronousFactory::CreateInstance( profile->GetRequestContext()); - SigninManagerBase* signin_manager = - SigninManagerFactory::GetInstance()->GetForProfile(profile); - if (signin_manager) - signin_manager->AddObserver(this); + identity::IdentityManager* identity_manager = + IdentityManagerFactory::GetForProfile(profile); + if (identity_manager) + identity_manager->AddObserver(this); } privet_lister_->Start(); @@ -403,14 +401,13 @@ CheckListingDone(); } -void LocalDiscoveryUIHandler::GoogleSigninSucceeded( - const std::string& account_id, - const std::string& username) { +void LocalDiscoveryUIHandler::OnPrimaryAccountSet( + const AccountInfo& primary_account_info) { CheckUserLoggedIn(); } -void LocalDiscoveryUIHandler::GoogleSignedOut(const std::string& account_id, - const std::string& username) { +void LocalDiscoveryUIHandler::OnPrimaryAccountCleared( + const AccountInfo& previous_primary_account_info) { CheckUserLoggedIn(); } @@ -457,12 +454,12 @@ std::string LocalDiscoveryUIHandler::GetSyncAccount() const { Profile* profile = Profile::FromWebUI(web_ui()); - SigninManagerBase* signin_manager = - SigninManagerFactory::GetForProfileIfExists(profile); + identity::IdentityManager* identity_manager = + IdentityManagerFactory::GetForProfile(profile); std::string email; - if (signin_manager) - email = signin_manager->GetAuthenticatedAccountInfo().email; + if (identity_manager && identity_manager->HasPrimaryAccount()) + email = identity_manager->GetPrimaryAccountInfo().email; return email; } @@ -514,19 +511,12 @@ if (!profile) return std::unique_ptr<GCDApiFlow>(); - ProfileOAuth2TokenService* token_service = - ProfileOAuth2TokenServiceFactory::GetForProfile(profile); - if (!token_service) + identity::IdentityManager* identity_manager = + IdentityManagerFactory::GetForProfile(profile); + if (!(identity_manager && identity_manager->HasPrimaryAccount())) return std::unique_ptr<GCDApiFlow>(); - SigninManagerBase* signin_manager = - SigninManagerFactory::GetInstance()->GetForProfile(profile); - if (!signin_manager) - return std::unique_ptr<GCDApiFlow>(); - - return GCDApiFlow::Create(profile->GetRequestContext(), - token_service, - signin_manager->GetAuthenticatedAccountId()); + return GCDApiFlow::Create(profile->GetRequestContext(), identity_manager); } bool LocalDiscoveryUIHandler::IsUserSupervisedOrOffTheRecord() {
diff --git a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.h b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.h index 29baef116..cca4463 100644 --- a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.h +++ b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.h
@@ -14,9 +14,9 @@ #include "chrome/browser/printing/cloud_print/cloud_print_printer_list.h" #include "chrome/browser/printing/cloud_print/privet_device_lister.h" #include "chrome/browser/printing/cloud_print/privet_http.h" -#include "components/signin/core/browser/signin_manager.h" #include "content/public/browser/web_ui_message_handler.h" #include "printing/buildflags/buildflags.h" +#include "services/identity/public/cpp/identity_manager.h" #if BUILDFLAG(ENABLE_PRINT_PREVIEW) && !defined(OS_CHROMEOS) #define CLOUD_PRINT_CONNECTOR_UI_AVAILABLE @@ -43,7 +43,7 @@ public cloud_print::PrivetRegisterOperation::Delegate, public cloud_print::PrivetDeviceLister::Delegate, public cloud_print::CloudPrintPrinterList::Delegate, - public SigninManagerBase::Observer { + public identity::IdentityManager::Observer { public: LocalDiscoveryUIHandler(); ~LocalDiscoveryUIHandler() override; @@ -78,11 +78,10 @@ const cloud_print::CloudPrintPrinterList::DeviceList& devices) override; void OnDeviceListUnavailable() override; - // SigninManagerBase::Observer implementation. - void GoogleSigninSucceeded(const std::string& account_id, - const std::string& username) override; - void GoogleSignedOut(const std::string& account_id, - const std::string& username) override; + // identity::IdentityManager::Observer implementation. + void OnPrimaryAccountSet(const AccountInfo& primary_account_info) override; + void OnPrimaryAccountCleared( + const AccountInfo& previous_primary_account_info) override; private: using DeviceDescriptionMap =
diff --git a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc index d71fefd..3c2af7b1 100644 --- a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc +++ b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
@@ -16,7 +16,7 @@ #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/signin/signin_manager_factory.h" +#include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/themes/theme_properties.h" #include "chrome/browser/themes/theme_service.h" #include "chrome/browser/themes/theme_service_factory.h" @@ -34,13 +34,13 @@ #include "components/bookmarks/common/bookmark_pref_names.h" #include "components/google/core/browser/google_util.h" #include "components/prefs/pref_service.h" -#include "components/signin/core/browser/signin_manager.h" #include "components/strings/grit/components_strings.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/render_process_host.h" #include "extensions/common/extension.h" #include "extensions/common/extension_urls.h" +#include "services/identity/public/cpp/identity_manager.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/template_expressions.h" @@ -457,7 +457,7 @@ load_time_data.SetBoolean( "isUserSignedIn", - SigninManagerFactory::GetForProfile(profile_)->IsAuthenticated()); + IdentityManagerFactory::GetForProfile(profile_)->HasPrimaryAccount()); // Load the new tab page appropriate for this build. base::StringPiece new_tab_html(
diff --git a/chrome/browser/ui/webui/ntp/ntp_resource_cache_factory.cc b/chrome/browser/ui/webui/ntp/ntp_resource_cache_factory.cc index 1f9b0d10..cdd8d43 100644 --- a/chrome/browser/ui/webui/ntp/ntp_resource_cache_factory.cc +++ b/chrome/browser/ui/webui/ntp/ntp_resource_cache_factory.cc
@@ -6,7 +6,7 @@ #include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/signin/signin_manager_factory.h" +#include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/themes/theme_service_factory.h" #include "chrome/browser/ui/webui/ntp/ntp_resource_cache.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" @@ -26,7 +26,7 @@ : BrowserContextKeyedServiceFactory( "NTPResourceCache", BrowserContextDependencyManager::GetInstance()) { - DependsOn(SigninManagerFactory::GetInstance()); + DependsOn(IdentityManagerFactory::GetInstance()); DependsOn(ThemeServiceFactory::GetInstance()); }
diff --git a/chrome/browser/vr/ui_scene_creator.cc b/chrome/browser/vr/ui_scene_creator.cc index 02885c8..92a5f2f 100644 --- a/chrome/browser/vr/ui_scene_creator.cc +++ b/chrome/browser/vr/ui_scene_creator.cc
@@ -1425,6 +1425,7 @@ indicator_bg->SetTranslate(0, kLoadingIndicatorYOffset, 0); indicator_bg->SetCornerRadii( {0, 0, kContentCornerRadius, kContentCornerRadius}); + indicator_bg->SetTransitionedProperties({OPACITY}); VR_BIND_VISIBILITY(indicator_bg, model->loading); VR_BIND_COLOR(model_, indicator_bg.get(), &ColorScheme::loading_indicator_background, &Rect::SetColor);
diff --git a/chrome/browser/vr/ui_unittest.cc b/chrome/browser/vr/ui_unittest.cc index 398e4be..ba2676f 100644 --- a/chrome/browser/vr/ui_unittest.cc +++ b/chrome/browser/vr/ui_unittest.cc
@@ -781,6 +781,7 @@ model_->loading = true; model_->load_progress = 0; + RunForMs(100); EXPECT_TRUE( VerifyVisibility({kLoadingIndicator, kLoadingIndicatorForeground}, true)); EXPECT_EQ(foreground->GetClipRect(), gfx::RectF(0, 0, 0, 1));
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model.cc b/chrome/browser/webauthn/authenticator_request_dialog_model.cc index 200c320..acfe4ac3 100644 --- a/chrome/browser/webauthn/authenticator_request_dialog_model.cc +++ b/chrome/browser/webauthn/authenticator_request_dialog_model.cc
@@ -10,9 +10,16 @@ observer.OnModelDestroyed(); } +void AuthenticatorRequestDialogModel::SetCurrentStep(Step step) { + current_step_ = step; + for (auto& observer : observers_) + observer.OnStepTransition(); +} + void AuthenticatorRequestDialogModel::StartGuidedFlowForTransport( - int transport) { + AuthenticatorTransport transport) { DCHECK_EQ(current_step(), Step::kTransportSelection); + // TODO(engedy): Use transport here. } void AuthenticatorRequestDialogModel::TryIfBleAdapterIsPowered() { @@ -54,11 +61,5 @@ } void AuthenticatorRequestDialogModel::OnRequestComplete() { - current_step_ = Step::kCompleted; - NotifyStepTransition(); -} - -void AuthenticatorRequestDialogModel::NotifyStepTransition() { - for (auto& observer : observers_) - observer.OnStepTransition(); + SetCurrentStep(Step::kCompleted); }
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model.h b/chrome/browser/webauthn/authenticator_request_dialog_model.h index 044aff3..9de07d7 100644 --- a/chrome/browser/webauthn/authenticator_request_dialog_model.h +++ b/chrome/browser/webauthn/authenticator_request_dialog_model.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_WEBAUTHN_AUTHENTICATOR_REQUEST_DIALOG_MODEL_H_ #include "base/observer_list.h" +#include "chrome/browser/webauthn/transport_list_model.h" // Encapsulates the model behind the Web Authentication request dialog's UX // flow. This is essentially a state machine going through the states defined in @@ -56,15 +57,16 @@ AuthenticatorRequestDialogModel(); ~AuthenticatorRequestDialogModel(); - void set_current_step(Step step) { current_step_ = step; } + void SetCurrentStep(Step step); Step current_step() const { return current_step_; } + TransportListModel* transport_list_model() { return &transport_list_model_; } + // Requests that the step-by-step wizard flow commence, guiding the user // through using the Secutity Key with the given |transport|. // // Valid action when at step: kTransportSelection. - // TODO(engedy): Use AuthenticatorTransport type when ready. - void StartGuidedFlowForTransport(int transport); + void StartGuidedFlowForTransport(AuthenticatorTransport transport); // Tries if the BLE adapter is now powered -- the user claims they turned it // on. @@ -117,12 +119,10 @@ void OnRequestComplete(); private: - // Notifies observers when a step transition has occurred. - void NotifyStepTransition(); - // The current step of the request UX flow that is currently shown. Step current_step_ = Step::kInitial; + TransportListModel transport_list_model_; base::ObserverList<Observer> observers_; DISALLOW_COPY_AND_ASSIGN(AuthenticatorRequestDialogModel);
diff --git a/chrome/browser/webauthn/transport_list_model.cc b/chrome/browser/webauthn/transport_list_model.cc new file mode 100644 index 0000000..53d6a72 --- /dev/null +++ b/chrome/browser/webauthn/transport_list_model.cc
@@ -0,0 +1,25 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/webauthn/transport_list_model.h" + +TransportListModel::TransportListModel() = default; +TransportListModel::~TransportListModel() { + for (auto& observer : observer_list_) + observer.OnModelDestroyed(); +} + +void TransportListModel::AppendTransport(AuthenticatorTransport transport) { + transports_.push_back(transport); + for (auto& observer : observer_list_) + observer.OnTransportAppended(); +} + +void TransportListModel::AddObserver(Observer* observer) { + observer_list_.AddObserver(observer); +} + +void TransportListModel::RemoveObserver(Observer* observer) { + observer_list_.RemoveObserver(observer); +}
diff --git a/chrome/browser/webauthn/transport_list_model.h b/chrome/browser/webauthn/transport_list_model.h new file mode 100644 index 0000000..8f99e24 --- /dev/null +++ b/chrome/browser/webauthn/transport_list_model.h
@@ -0,0 +1,55 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_WEBAUTHN_TRANSPORT_LIST_MODEL_H_ +#define CHROME_BROWSER_WEBAUTHN_TRANSPORT_LIST_MODEL_H_ + +#include <vector> + +#include "base/macros.h" +#include "base/observer_list.h" + +// Enumerates transports over which a Security Key can be reached. +enum class AuthenticatorTransport { + kBluetoothLowEnergy, + kUsb, + kNearFieldCommunication, + kInternal, + kCloudAssistedBluetoothLowEnergy +}; + +// An observable list of transports that are supported on the platform. +class TransportListModel { + public: + class Observer { + public: + // Called just before the model is destructed. + virtual void OnModelDestroyed() = 0; + + // Called when a new transport is added to the end of the list. + virtual void OnTransportAppended() {} + }; + + TransportListModel(); + ~TransportListModel(); + + // Appends |transport| at the end of the list. + void AppendTransport(AuthenticatorTransport transport); + + // The |observer| must either outlive |this|, or unregister on destruction. + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + + const std::vector<AuthenticatorTransport>& transports() const { + return transports_; + } + + private: + std::vector<AuthenticatorTransport> transports_; + base::ObserverList<Observer> observer_list_; + + DISALLOW_COPY_AND_ASSIGN(TransportListModel); +}; + +#endif // CHROME_BROWSER_WEBAUTHN_TRANSPORT_LIST_MODEL_H_
diff --git a/chrome/common/prerender_url_loader_throttle.cc b/chrome/common/prerender_url_loader_throttle.cc index a30d11b84..1d52887 100644 --- a/chrome/common/prerender_url_loader_throttle.cc +++ b/chrome/common/prerender_url_loader_throttle.cc
@@ -131,6 +131,7 @@ #endif // OS_ANDROID if (mode_ == PREFETCH_ONLY) { + request->headers.SetHeader(kPurposeHeaderName, kPurposeHeaderValue); detached_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds( content::kDefaultDetachableCancelDelayMs),
diff --git a/chrome/common/prerender_util.cc b/chrome/common/prerender_util.cc index 70282cf510..10b55de8d 100644 --- a/chrome/common/prerender_util.cc +++ b/chrome/common/prerender_util.cc
@@ -46,6 +46,8 @@ } // namespace const char kFollowOnlyWhenPrerenderShown[] = "follow-only-when-prerender-shown"; +const char kPurposeHeaderName[] = "Purpose"; +const char kPurposeHeaderValue[] = "prefetch"; bool DoesURLHaveValidScheme(const GURL& url) { return (url.SchemeIsHTTPOrHTTPS() ||
diff --git a/chrome/common/prerender_util.h b/chrome/common/prerender_util.h index 4fa1436..14a044e 100644 --- a/chrome/common/prerender_util.h +++ b/chrome/common/prerender_util.h
@@ -13,6 +13,8 @@ namespace prerender { extern const char kFollowOnlyWhenPrerenderShown[]; +extern const char kPurposeHeaderName[]; +extern const char kPurposeHeaderValue[]; // Returns true iff the scheme of the URL given is valid for prerendering. bool DoesURLHaveValidScheme(const GURL& url);
diff --git a/chrome/installer/linux/debian/dist_package_versions.json b/chrome/installer/linux/debian/dist_package_versions.json index 15f8c65..9487fb2 100644 --- a/chrome/installer/linux/debian/dist_package_versions.json +++ b/chrome/installer/linux/debian/dist_package_versions.json
@@ -2,26 +2,25 @@ "Debian 10 (Buster)": { "libappindicator3-1": "0.4.92-5", "libasound2": "1.1.3-5", - "libatk-bridge2.0-0": "2.26.2-1", - "libatk1.0-0": "2.28.1-1", - "libc6": "2.27-3", - "libcairo2": "1.15.10-1", - "libcups2": "2.2.7-2", - "libdbus-1-3": "1.12.6-2", + "libatk-bridge2.0-0": "2.26.1-1", + "libatk1.0-0": "2.26.1-3", + "libc6": "2.26-4", + "libcairo2": "1.15.8-3", + "libcups2": "2.2.6-4", + "libdbus-1-3": "1.12.2-1", "libexpat1": "2.2.5-3", - "libgcc1": "1:8-20180402-1", - "libgdk-pixbuf2.0-0": "2.36.11-2", - "libglib2.0-0": "2.56.0-4", - "libgtk-3-0": "3.22.29-3", - "libnspr4": "2:4.18-1", - "libnss3": "2:3.35-2", - "libpango-1.0-0": "1.42.0-1", - "libpangocairo-1.0-0": "1.42.0-1", - "libstdc++6": "8-20180402-1", - "libuuid1": "2.31.1-0.5", - "libx11-6": "2:1.6.5-1", - "libx11-xcb1": "2:1.6.5-1", - "libxcb1": "1.13-1", + "libgcc1": "1:7.2.0-19", + "libgdk-pixbuf2.0-0": "2.36.11-1", + "libglib2.0-0": "2.54.3-2", + "libgtk-3-0": "3.22.26-2", + "libnspr4": "2:4.16-1+b1", + "libnss3": "2:3.34.1-1", + "libpango-1.0-0": "1.40.14-1", + "libpangocairo-1.0-0": "1.40.14-1", + "libstdc++6": "7.2.0-19", + "libx11-6": "2:1.6.4-3", + "libx11-xcb1": "2:1.6.4-3", + "libxcb1": "1.12-1", "libxcomposite1": "1:0.4.4-2", "libxcursor1": "1:1.1.15-1", "libxdamage1": "1:1.1.4-3", @@ -43,7 +42,7 @@ "libcups2": "1.7.5-11+deb8u1", "libdbus-1-3": "1.8.22-0+deb8u1", "libexpat1": "2.1.0-6+deb8u4", - "libgcc1": "1:4.9.2-10+deb8u1", + "libgcc1": "1:4.9.2-10", "libgdk-pixbuf2.0-0": "2.31.1-2+deb8u7", "libglib2.0-0": "2.42.1-1+b1", "libgtk-3-0": "3.14.5-1+deb8u1", @@ -51,8 +50,7 @@ "libnss3": "2:3.26-1+debu8u3", "libpango-1.0-0": "1.36.8-3", "libpangocairo-1.0-0": "1.36.8-3", - "libstdc++6": "4.9.2-10+deb8u1", - "libuuid1": "2.25.2-6", + "libstdc++6": "4.9.2-10", "libx11-6": "2:1.6.2-3+deb8u1", "libx11-xcb1": "2:1.6.2-3+deb8u1", "libxcb1": "1.10-3+b1", @@ -74,10 +72,10 @@ "libatk1.0-0": "2.22.0-1", "libc6": "2.24-11+deb9u1", "libcairo2": "1.14.8-1", - "libcups2": "2.2.1-8+deb9u1", - "libdbus-1-3": "1.10.26-0+deb9u1", + "libcups2": "2.2.1-8", + "libdbus-1-3": "1.10.24-0+deb9u1", "libexpat1": "2.2.0-2+deb9u1", - "libgcc1": "1:6.3.0-18+deb9u1", + "libgcc1": "1:6.3.0-18", "libgdk-pixbuf2.0-0": "2.36.5-2+deb9u2", "libglib2.0-0": "2.50.3-2", "libgtk-3-0": "3.22.11-1", @@ -85,8 +83,7 @@ "libnss3": "2:3.26.2-1.1+deb9u1", "libpango-1.0-0": "1.40.5-1", "libpangocairo-1.0-0": "1.40.5-1", - "libstdc++6": "6.3.0-18+deb9u1", - "libuuid1": "2.29.2-1+deb9u1", + "libstdc++6": "6.3.0-18", "libx11-6": "2:1.6.4-3", "libx11-xcb1": "2:1.6.4-3", "libxcb1": "1.12-1", @@ -108,7 +105,7 @@ "libatk1.0-0": "2.10.0-2ubuntu2", "libc6": "2.19-0ubuntu6.14", "libcairo2": "1.13.0~20140204-0ubuntu1.1", - "libcups2": "1.7.2-0ubuntu1.9", + "libcups2": "1.7.2-0ubuntu1.7", "libdbus-1-3": "1.6.18-0ubuntu4.4", "libexpat1": "2.1.0-4ubuntu1.4", "libgcc1": "1:4.9.3-0ubuntu4", @@ -119,8 +116,7 @@ "libnss3": "2:3.28.4-0ubuntu0.14.04.3", "libpango-1.0-0": "1.36.3-1ubuntu1.1", "libpangocairo-1.0-0": "1.36.3-1ubuntu1.1", - "libstdc++6": "4.8.4-2ubuntu1~14.04.4", - "libuuid1": "2.20.1-5.1ubuntu20.9", + "libstdc++6": "4.8.4-2ubuntu1~14.04.3", "libx11-6": "2:1.6.2-1ubuntu2", "libx11-xcb1": "2:1.6.2-1ubuntu2", "libxcb1": "1.10-2ubuntu1", @@ -142,7 +138,7 @@ "libatk1.0-0": "2.18.0-1", "libc6": "2.23-0ubuntu10", "libcairo2": "1.14.6-1", - "libcups2": "2.1.3-4ubuntu0.4", + "libcups2": "2.1.3-4ubuntu0.3", "libdbus-1-3": "1.10.6-1ubuntu3.1", "libexpat1": "2.1.0-7ubuntu0.16.04.3", "libgcc1": "1:6.0.1-0ubuntu1", @@ -153,8 +149,7 @@ "libnss3": "2:3.28.4-0ubuntu0.16.04.3", "libpango-1.0-0": "1.38.1-1", "libpangocairo-1.0-0": "1.38.1-1", - "libstdc++6": "5.4.0-6ubuntu1~16.04.9", - "libuuid1": "2.27.1-6ubuntu3.4", + "libstdc++6": "5.4.0-6ubuntu1~16.04.4", "libx11-6": "2:1.6.3-1ubuntu2", "libx11-xcb1": "2:1.6.3-1ubuntu2", "libxcb1": "1.11.1-1ubuntu1", @@ -179,7 +174,7 @@ "libcups2": "2.2.4-7ubuntu3", "libdbus-1-3": "1.10.22-1ubuntu1", "libexpat1": "2.2.3-1", - "libgcc1": "1:7.2.0-8ubuntu3.2", + "libgcc1": "1:7.2.0-8ubuntu3", "libgdk-pixbuf2.0-0": "2.36.11-1ubuntu0.1", "libglib2.0-0": "2.54.1-1ubuntu1", "libgtk-3-0": "3.22.25-0ubuntu0.1", @@ -187,8 +182,7 @@ "libnss3": "2:3.32-1ubuntu3", "libpango-1.0-0": "1.40.12-1", "libpangocairo-1.0-0": "1.40.12-1", - "libstdc++6": "7.2.0-8ubuntu3.2", - "libuuid1": "2.30.1-0ubuntu4.1", + "libstdc++6": "7.2.0-8ubuntu3", "libx11-6": "2:1.6.4-3", "libx11-xcb1": "2:1.6.4-3", "libxcb1": "1.12-1ubuntu1",
diff --git a/chrome/installer/linux/debian/update_dist_package_versions.py b/chrome/installer/linux/debian/update_dist_package_versions.py index a3d824e..481dfd7b 100755 --- a/chrome/installer/linux/debian/update_dist_package_versions.py +++ b/chrome/installer/linux/debian/update_dist_package_versions.py
@@ -52,7 +52,6 @@ "libpango-1.0-0", "libpangocairo-1.0-0", "libstdc++6", - "libuuid1", "libx11-6", "libx11-xcb1", "libxcb1",
diff --git a/chrome/installer/linux/rpm/dist_package_provides.json b/chrome/installer/linux/rpm/dist_package_provides.json index 2cc52de..9edf127 100644 --- a/chrome/installer/linux/rpm/dist_package_provides.json +++ b/chrome/installer/linux/rpm/dist_package_provides.json
@@ -236,10 +236,6 @@ "libstdc++.so.6(GLIBCXX_3.4.7)(64bit)", "libstdc++.so.6(GLIBCXX_3.4.8)(64bit)", "libstdc++.so.6(GLIBCXX_3.4.9)(64bit)", - "libuuid.so.1()(64bit)", - "libuuid.so.1(UUIDD_PRIVATE)(64bit)", - "libuuid.so.1(UUID_1.0)(64bit)", - "libuuid.so.1(UUID_2.20)(64bit)", "libxcb.so.1()(64bit)", "rtld(GNU_HASH)" ], @@ -486,10 +482,6 @@ "libstdc++.so.6(GLIBCXX_3.4.7)(64bit)", "libstdc++.so.6(GLIBCXX_3.4.8)(64bit)", "libstdc++.so.6(GLIBCXX_3.4.9)(64bit)", - "libuuid.so.1()(64bit)", - "libuuid.so.1(UUIDD_PRIVATE)(64bit)", - "libuuid.so.1(UUID_1.0)(64bit)", - "libuuid.so.1(UUID_2.20)(64bit)", "libxcb.so.1()(64bit)", "rtld(GNU_HASH)" ], @@ -737,10 +729,6 @@ "libstdc++.so.6(GLIBCXX_3.4.7)(64bit)", "libstdc++.so.6(GLIBCXX_3.4.8)(64bit)", "libstdc++.so.6(GLIBCXX_3.4.9)(64bit)", - "libuuid.so.1()(64bit)", - "libuuid.so.1(UUIDD_PRIVATE)(64bit)", - "libuuid.so.1(UUID_1.0)(64bit)", - "libuuid.so.1(UUID_2.20)(64bit)", "libxcb.so.1()(64bit)", "rtld(GNU_HASH)" ], @@ -1191,14 +1179,6 @@ "libstdc++.so.6(GLIBCXX_3.4.8)(64bit)", "libstdc++.so.6(GLIBCXX_3.4.9)", "libstdc++.so.6(GLIBCXX_3.4.9)(64bit)", - "libuuid.so.1", - "libuuid.so.1()(64bit)", - "libuuid.so.1(UUIDD_PRIVATE)", - "libuuid.so.1(UUIDD_PRIVATE)(64bit)", - "libuuid.so.1(UUID_1.0)", - "libuuid.so.1(UUID_1.0)(64bit)", - "libuuid.so.1(UUID_2.20)", - "libuuid.so.1(UUID_2.20)(64bit)", "libxcb.so.1", "libxcb.so.1()(64bit)", "rtld(GNU_HASH)" @@ -1658,14 +1638,6 @@ "libstdc++.so.6(GLIBCXX_3.4.8)(64bit)", "libstdc++.so.6(GLIBCXX_3.4.9)", "libstdc++.so.6(GLIBCXX_3.4.9)(64bit)", - "libuuid.so.1", - "libuuid.so.1()(64bit)", - "libuuid.so.1(UUIDD_PRIVATE)", - "libuuid.so.1(UUIDD_PRIVATE)(64bit)", - "libuuid.so.1(UUID_1.0)", - "libuuid.so.1(UUID_1.0)(64bit)", - "libuuid.so.1(UUID_2.20)", - "libuuid.so.1(UUID_2.20)(64bit)", "libxcb.so.1", "libxcb.so.1()(64bit)", "rtld(GNU_HASH)"
diff --git a/chrome/installer/linux/rpm/update_package_provides.py b/chrome/installer/linux/rpm/update_package_provides.py index 78424647..4ce3001 100755 --- a/chrome/installer/linux/rpm/update_package_provides.py +++ b/chrome/installer/linux/rpm/update_package_provides.py
@@ -54,7 +54,6 @@ "librt.so", "libsmime3.so", "libstdc++.so", - "libuuid.so", "libxcb.so", "rtld(GNU_HASH)", ]
diff --git a/chrome/renderer/page_load_metrics/metrics_render_frame_observer.cc b/chrome/renderer/page_load_metrics/metrics_render_frame_observer.cc index 1b0a7249..8e87341 100644 --- a/chrome/renderer/page_load_metrics/metrics_render_frame_observer.cc +++ b/chrome/renderer/page_load_metrics/metrics_render_frame_observer.cc
@@ -85,6 +85,20 @@ } } +void MetricsRenderFrameObserver::DidStartResponse( + int request_id, + const network::ResourceResponseHead& response_head) {} + +void MetricsRenderFrameObserver::DidCompleteResponse( + int request_id, + const network::URLLoaderCompletionStatus& status) {} + +void MetricsRenderFrameObserver::DidCancelResponse(int request_id) {} + +void MetricsRenderFrameObserver::DidReceiveTransferSizeUpdate( + int request_id, + int received_data_length) {} + void MetricsRenderFrameObserver::FrameDetached() { page_timing_metrics_sender_.reset(); }
diff --git a/chrome/renderer/page_load_metrics/metrics_render_frame_observer.h b/chrome/renderer/page_load_metrics/metrics_render_frame_observer.h index 7eb65fe6..1e67cb9 100644 --- a/chrome/renderer/page_load_metrics/metrics_render_frame_observer.h +++ b/chrome/renderer/page_load_metrics/metrics_render_frame_observer.h
@@ -38,6 +38,15 @@ void DidObserveNewFeatureUsage(blink::mojom::WebFeature feature) override; void DidObserveNewCssPropertyUsage(int css_property, bool is_animated) override; + void DidStartResponse( + int request_id, + const network::ResourceResponseHead& response_head) override; + void DidReceiveTransferSizeUpdate(int request_id, + int received_data_length) override; + void DidCompleteResponse( + int request_id, + const network::URLLoaderCompletionStatus& status) override; + void DidCancelResponse(int request_id) override; void DidCommitProvisionalLoad(bool is_new_navigation, bool is_same_document_navigation) override; void OnDestruct() override;
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 2c12fa4..f2a22f3 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2619,6 +2619,7 @@ "../browser/ui/autofill/popup_view_common_unittest.cc", "../browser/ui/autofill/popup_view_test_helpers.cc", "../browser/ui/autofill/popup_view_test_helpers.h", + "../browser/ui/bloated_renderer/bloated_renderer_tab_helper_unittest.cc", "../browser/ui/blocked_content/popup_opener_tab_helper_unittest.cc", "../browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc", "../browser/ui/blocked_content/scoped_visibility_tracker_unittest.cc",
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc index de29041..dc8fb0b 100644 --- a/chrome/test/base/testing_profile.cc +++ b/chrome/test/base/testing_profile.cc
@@ -46,6 +46,7 @@ #include "chrome/browser/profiles/storage_partition_descriptor.h" #include "chrome/browser/search_engines/template_url_fetcher_factory.h" #include "chrome/browser/search_engines/template_url_service_factory.h" +#include "chrome/browser/sync/bookmark_sync_service_factory.h" #include "chrome/browser/sync/glue/sync_start_util.h" #include "chrome/browser/web_data_service_factory.h" #include "chrome/common/buildflags.h" @@ -207,7 +208,8 @@ Profile* profile = Profile::FromBrowserContext(context); std::unique_ptr<BookmarkModel> bookmark_model( new BookmarkModel(std::make_unique<ChromeBookmarkClient>( - profile, ManagedBookmarkServiceFactory::GetForProfile(profile)))); + profile, ManagedBookmarkServiceFactory::GetForProfile(profile), + BookmarkSyncServiceFactory::GetForProfile(profile)))); bookmark_model->Load(profile->GetPrefs(), profile->GetPath(), profile->GetIOTaskRunner(), content::BrowserThread::GetTaskRunnerForThread(
diff --git a/chromecast/browser/DEPS b/chromecast/browser/DEPS index 0b0b9eaf..aea8f3b 100644 --- a/chromecast/browser/DEPS +++ b/chromecast/browser/DEPS
@@ -21,6 +21,7 @@ "+components/version_info", "+components/viz/common/switches.h", "+components/zoom", + "+content/common/net", "+content/public/android", "+content/public/browser", "+content/public/common",
diff --git a/chromecast/browser/extension_request_protocol_handler.cc b/chromecast/browser/extension_request_protocol_handler.cc index c4f533b..5a356ab 100644 --- a/chromecast/browser/extension_request_protocol_handler.cc +++ b/chromecast/browser/extension_request_protocol_handler.cc
@@ -5,6 +5,7 @@ #include "chromecast/browser/extension_request_protocol_handler.h" #include "chromecast/common/cast_redirect_manifest_handler.h" +#include "content/common/net/url_request_user_data.h" #include "extensions/browser/extension_protocols.h" #include "extensions/browser/extension_system.h" #include "extensions/browser/info_map.h" @@ -86,7 +87,15 @@ : net::URLRequestJob(request, network_delegate), sub_request_(request->context()->CreateRequest(redirect_url, request->priority(), - this)) {} + this)) { + content::URLRequestUserData* user_data = + static_cast<content::URLRequestUserData*>( + request->GetUserData(content::URLRequestUserData::kUserDataKey)); + sub_request_->SetUserData( + content::URLRequestUserData::kUserDataKey, + std::make_unique<content::URLRequestUserData>( + user_data->render_process_id(), user_data->render_frame_id())); +} CastExtensionURLRequestJob::~CastExtensionURLRequestJob() {}
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 964bf91..05dc81b 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -10790.0.0 \ No newline at end of file +10796.0.0 \ No newline at end of file
diff --git a/chromeos/account_manager/account_manager.cc b/chromeos/account_manager/account_manager.cc index 2bf96ac..0b15c2d 100644 --- a/chromeos/account_manager/account_manager.cc +++ b/chromeos/account_manager/account_manager.cc
@@ -4,6 +4,7 @@ #include "chromeos/account_manager/account_manager.h" +#include <algorithm> #include <utility> #include "base/bind.h" @@ -14,7 +15,12 @@ #include "base/sequenced_task_runner.h" #include "base/task_runner_util.h" #include "base/task_scheduler/post_task.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "google_apis/gaia/gaia_auth_consumer.h" +#include "google_apis/gaia/gaia_auth_fetcher.h" +#include "google_apis/gaia/gaia_constants.h" #include "google_apis/gaia/oauth2_access_token_fetcher_impl.h" +#include "net/url_request/url_request_context_getter.h" #include "third_party/protobuf/src/google/protobuf/message_lite.h" namespace chromeos { @@ -88,6 +94,57 @@ } // namespace +class AccountManager::GaiaTokenRevocationRequest : public GaiaAuthConsumer { + public: + GaiaTokenRevocationRequest( + net::URLRequestContextGetter* request_context, + AccountManager::DelayNetworkCallRunner delay_network_call_runner, + const std::string& refresh_token, + base::WeakPtr<AccountManager> account_manager) + : account_manager_(account_manager), + refresh_token_(refresh_token), + weak_factory_(this) { + DCHECK(!refresh_token_.empty()); + gaia_auth_fetcher_ = std::make_unique<GaiaAuthFetcher>( + this, GaiaConstants::kChromeOSSource, request_context); + base::RepeatingClosure start_revoke_token = base::BindRepeating( + &GaiaTokenRevocationRequest::Start, weak_factory_.GetWeakPtr()); + delay_network_call_runner.Run(start_revoke_token); + } + + ~GaiaTokenRevocationRequest() override = default; + + // GaiaAuthConsumer overrides. + void OnOAuth2RevokeTokenCompleted(TokenRevocationStatus status) override { + VLOG(1) << "GaiaTokenRevocationRequest::OnOAuth2RevokeTokenCompleted"; + // We cannot call |AccountManager::DeletePendingTokenRevocationRequest| + // directly because it will immediately start deleting |this|, before the + // method has had a chance to return. + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(&AccountManager::DeletePendingTokenRevocationRequest, + account_manager_, this)); + } + + private: + // Starts the actual work of sending a network request to revoke a token. + void Start() { gaia_auth_fetcher_->StartRevokeOAuth2Token(refresh_token_); } + + // A weak pointer to |AccountManager|. The only purpose is to signal + // the completion of work through + // |AccountManager::DeletePendingTokenRevocationRequest|. + base::WeakPtr<AccountManager> account_manager_; + + // Does the actual work of revoking a token. + std::unique_ptr<GaiaAuthFetcher> gaia_auth_fetcher_; + + // Refresh token to be revoked from GAIA. + std::string refresh_token_; + + base::WeakPtrFactory<GaiaTokenRevocationRequest> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(GaiaTokenRevocationRequest); +}; + bool AccountManager::AccountKey::IsValid() const { return !id.empty() && account_type != account_manager::AccountType::ACCOUNT_TYPE_UNSPECIFIED; @@ -111,14 +168,20 @@ AccountManager::AccountManager() : weak_factory_(this) {} -void AccountManager::Initialize(const base::FilePath& home_dir) { - Initialize(home_dir, base::CreateSequencedTaskRunnerWithTraits( - {base::TaskShutdownBehavior::BLOCK_SHUTDOWN, - base::MayBlock()})); +void AccountManager::Initialize( + const base::FilePath& home_dir, + net::URLRequestContextGetter* request_context, + DelayNetworkCallRunner delay_network_call_runner) { + Initialize( + home_dir, request_context, std::move(delay_network_call_runner), + base::CreateSequencedTaskRunnerWithTraits( + {base::TaskShutdownBehavior::BLOCK_SHUTDOWN, base::MayBlock()})); } void AccountManager::Initialize( const base::FilePath& home_dir, + net::URLRequestContextGetter* request_context, + DelayNetworkCallRunner delay_network_call_runner, scoped_refptr<base::SequencedTaskRunner> task_runner) { VLOG(1) << "AccountManager::Initialize"; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -133,6 +196,8 @@ } init_state_ = InitializationState::kInProgress; + request_context_ = request_context; + delay_network_call_runner_ = std::move(delay_network_call_runner); task_runner_ = task_runner; writer_ = std::make_unique<base::ImportantFileWriter>( home_dir.Append(kTokensFileName), task_runner_); @@ -211,9 +276,21 @@ return; } + const std::string token = std::move(it->second); tokens_.erase(it); PersistTokensAsync(); NotifyAccountRemovalObservers(account_key); + + // Revoke the token iff it is a GAIA account and the token is not empty. + // Stored tokens can be empty for accounts recently migrated to + // AccountManager, for which we do not have LSTs yet. These accounts require + // re-authentication from the user, but are in a valid state (and hence don't + // do a DCHECK here for |!token.empty()|). + if (account_key.account_type == + account_manager::AccountType::ACCOUNT_TYPE_GAIA && + !token.empty()) { + RevokeGaiaTokenOnServer(token); + } } void AccountManager::UpsertToken(const AccountKey& account_key, @@ -274,6 +351,11 @@ observers_.RemoveObserver(observer); } +net::URLRequestContextGetter* AccountManager::GetUrlRequestContext() { + DCHECK(request_context_); + return request_context_; +} + std::unique_ptr<OAuth2AccessTokenFetcher> AccountManager::CreateAccessTokenFetcher( const AccountKey& account_key, @@ -297,6 +379,29 @@ return it != tokens_.end() && !it->second.empty(); } +void AccountManager::RevokeGaiaTokenOnServer(const std::string& refresh_token) { + pending_token_revocation_requests_.emplace_back( + std::make_unique<GaiaTokenRevocationRequest>( + GetUrlRequestContext(), delay_network_call_runner_, refresh_token, + weak_factory_.GetWeakPtr())); +} + +void AccountManager::DeletePendingTokenRevocationRequest( + GaiaTokenRevocationRequest* request) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + auto it = std::find_if( + pending_token_revocation_requests_.begin(), + pending_token_revocation_requests_.end(), + [&request]( + const std::unique_ptr<GaiaTokenRevocationRequest>& pending_request) + -> bool { return pending_request.get() == request; }); + + if (it != pending_token_revocation_requests_.end()) { + pending_token_revocation_requests_.erase(it); + } +} + CHROMEOS_EXPORT std::ostream& operator<<( std::ostream& os, const AccountManager::AccountKey& account_key) {
diff --git a/chromeos/account_manager/account_manager.h b/chromeos/account_manager/account_manager.h index 3b5b0740..a13c048 100644 --- a/chromeos/account_manager/account_manager.h +++ b/chromeos/account_manager/account_manager.h
@@ -58,6 +58,9 @@ // A callback for list of |AccountKey|s. using AccountListCallback = base::OnceCallback<void(std::vector<AccountKey>)>; + using DelayNetworkCallRunner = + base::RepeatingCallback<void(const base::RepeatingClosure&)>; + class Observer { public: Observer(); @@ -85,11 +88,18 @@ // Note: |Initialize| MUST be called at least once on this object. AccountManager(); - ~AccountManager(); + virtual ~AccountManager(); // |home_dir| is the path of the Device Account's home directory (root of the - // user's cryptohome). This method MUST be called at least once. - void Initialize(const base::FilePath& home_dir); + // user's cryptohome). + // |request_context| is a non-owning pointer. + // |delay_network_call_runner| is basically a wrapper for + // |chromeos::DelayNetworkCall|. Cannot use |chromeos::DelayNetworkCall| due + // to linking/dependency constraints. + // This method MUST be called at least once in the lifetime of AccountManager. + void Initialize(const base::FilePath& home_dir, + net::URLRequestContextGetter* request_context, + DelayNetworkCallRunner delay_network_call_runner); // Gets (async) a list of account keys known to |AccountManager|. void GetAccounts(AccountListCallback callback); @@ -98,6 +108,9 @@ // |AccountManager|. // Observers are notified about an account removal through // |Observer::OnAccountRemoved|. + // If the account being removed is a GAIA account, a token revocation with + // GAIA is also attempted, on a best effort basis. Even if token revocation + // with GAIA fails, AccountManager will forget the account. void RemoveAccount(const AccountKey& account_key); // Updates or inserts a token, for the account corresponding to the given @@ -111,6 +124,9 @@ // not in the list of known observers. void RemoveObserver(Observer* observer); + // Gets AccountManager's URL Request Context. + net::URLRequestContextGetter* GetUrlRequestContext(); + // Creates and returns an |OAuth2AccessTokenFetcher| using the refresh token // stored for |account_key|. |IsTokenAvailable| should be |true| for // |account_key|, otherwise a |nullptr| is returned. @@ -133,14 +149,17 @@ kInitialized, // Initialization was successfully completed }; + // A util class to revoke Gaia tokens on server. This class is meant to be + // used for a single request. + class GaiaTokenRevocationRequest; + friend class AccountManagerTest; FRIEND_TEST_ALL_PREFIXES(AccountManagerTest, TestInitialization); - FRIEND_TEST_ALL_PREFIXES(AccountManagerTest, TestPersistence); - FRIEND_TEST_ALL_PREFIXES(AccountManagerTest, AccountRemovalIsPersistedToDisk); - // Initializes |AccountManager| with the provided |task_runner| and location - // of the user's home directory. + // Same as the public |Initialize| except for a |task_runner|. void Initialize(const base::FilePath& home_dir, + net::URLRequestContextGetter* request_context, + DelayNetworkCallRunner delay_network_call_runner, scoped_refptr<base::SequencedTaskRunner> task_runner); // Reads tokens from |tokens| and inserts them in |tokens_| and runs all @@ -175,9 +194,25 @@ // Notify |Observer|s about an account removal. void NotifyAccountRemovalObservers(const AccountKey& account_key); + // Revokes |refresh_token| with GAIA. Virtual for testing. + virtual void RevokeGaiaTokenOnServer(const std::string& refresh_token); + + // Called by |GaiaTokenRevocationRequest| to notify its request completion. + // Deletes |request| from |pending_token_revocation_requests_|, if present. + void DeletePendingTokenRevocationRequest(GaiaTokenRevocationRequest* request); + // Status of this object's initialization. InitializationState init_state_ = InitializationState::kNotStarted; + // All tokens, if channel bound, are bound to |request_context_|. This is a + // non-owning pointer. + net::URLRequestContextGetter* request_context_ = nullptr; + + // An indirect way to access |chromeos::DelayNetworkCall|. We cannot use + // |chromeos::DelayNetworkCall| directly here due to linking/dependency + // issues. + DelayNetworkCallRunner delay_network_call_runner_; + // A task runner for disk I/O. scoped_refptr<base::SequencedTaskRunner> task_runner_; std::unique_ptr<base::ImportantFileWriter> writer_; @@ -192,6 +227,13 @@ // Verifies that the list is empty on destruction. base::ObserverList<Observer, true /* check_empty */> observers_; + // A list of pending token revocation requests. + // |AccountManager| is a long living object in general and these requests are + // basically one shot fire-and-forget requests but for ASAN tests, we do not + // want to have dangling pointers to pending requests. + std::vector<std::unique_ptr<GaiaTokenRevocationRequest>> + pending_token_revocation_requests_; + SEQUENCE_CHECKER(sequence_checker_); base::WeakPtrFactory<AccountManager> weak_factory_;
diff --git a/chromeos/account_manager/account_manager_unittest.cc b/chromeos/account_manager/account_manager_unittest.cc index 58a8a83e..3d8d4a3 100644 --- a/chromeos/account_manager/account_manager_unittest.cc +++ b/chromeos/account_manager/account_manager_unittest.cc
@@ -12,13 +12,29 @@ #include "base/bind.h" #include "base/files/scoped_temp_dir.h" #include "base/macros.h" +#include "base/memory/scoped_refptr.h" #include "base/run_loop.h" #include "base/test/scoped_task_environment.h" #include "base/threading/sequenced_task_runner_handle.h" +#include "net/url_request/url_request_test_util.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using ::testing::_; + namespace chromeos { +class AccountManagerSpy : public AccountManager { + public: + AccountManagerSpy() = default; + ~AccountManagerSpy() override = default; + + MOCK_METHOD1(RevokeGaiaTokenOnServer, void(const std::string& refresh_token)); + + private: + DISALLOW_COPY_AND_ASSIGN(AccountManagerSpy); +}; + class AccountManagerTest : public testing::Test { public: AccountManagerTest() = default; @@ -27,9 +43,9 @@ protected: void SetUp() override { ASSERT_TRUE(tmp_dir_.CreateUniqueTempDir()); - account_manager_ = std::make_unique<AccountManager>(); - account_manager_->Initialize(tmp_dir_.GetPath(), - base::SequencedTaskRunnerHandle::Get()); + request_context_ = new net::TestURLRequestContextGetter( + scoped_task_environment_.GetMainThreadTaskRunner()); + ResetAndInitializeAccountManager(); } // Gets the list of accounts stored in |account_manager_|. @@ -50,13 +66,26 @@ return accounts; } + // Helper method to reset and initialize |account_manager_| with default + // parameters. + void ResetAndInitializeAccountManager() { + account_manager_ = std::make_unique<AccountManagerSpy>(); + account_manager_->Initialize(tmp_dir_.GetPath(), request_context_.get(), + immediate_callback_runner_, + base::SequencedTaskRunnerHandle::Get()); + } + // Check base/test/scoped_task_environment.h. This must be the first member / // declared before any member that cares about tasks. base::test::ScopedTaskEnvironment scoped_task_environment_; base::ScopedTempDir tmp_dir_; - std::unique_ptr<AccountManager> account_manager_; + scoped_refptr<net::URLRequestContextGetter> request_context_; + std::unique_ptr<AccountManagerSpy> account_manager_; const AccountManager::AccountKey kAccountKey_{ "111", account_manager::AccountType::ACCOUNT_TYPE_GAIA}; + AccountManager::DelayNetworkCallRunner immediate_callback_runner_ = + base::BindRepeating( + [](const base::RepeatingClosure& closure) -> void { closure.Run(); }); private: DISALLOW_COPY_AND_ASSIGN(AccountManagerTest); @@ -105,7 +134,8 @@ EXPECT_EQ(account_manager.init_state_, AccountManager::InitializationState::kNotStarted); - account_manager.Initialize(tmp_dir_.GetPath(), + account_manager.Initialize(tmp_dir_.GetPath(), request_context_.get(), + immediate_callback_runner_, base::SequencedTaskRunnerHandle::Get()); scoped_task_environment_.RunUntilIdle(); EXPECT_EQ(account_manager.init_state_, @@ -125,10 +155,7 @@ account_manager_->UpsertToken(kAccountKey_, "123"); scoped_task_environment_.RunUntilIdle(); - account_manager_ = std::make_unique<AccountManager>(); - account_manager_->Initialize(tmp_dir_.GetPath(), - base::SequencedTaskRunnerHandle::Get()); - + ResetAndInitializeAccountManager(); std::vector<AccountManager::AccountKey> accounts = GetAccountsBlocking(); EXPECT_EQ(1UL, accounts.size()); @@ -201,9 +228,7 @@ account_manager_->RemoveAccount(kAccountKey_); scoped_task_environment_.RunUntilIdle(); - account_manager_ = std::make_unique<AccountManager>(); - account_manager_->Initialize(tmp_dir_.GetPath(), - base::SequencedTaskRunnerHandle::Get()); + ResetAndInitializeAccountManager(); std::vector<AccountManager::AccountKey> accounts = GetAccountsBlocking(); @@ -224,4 +249,37 @@ account_manager_->RemoveObserver(observer.get()); } +TEST_F(AccountManagerTest, TokenRevocationIsAttemptedForGaiaAccounts) { + const std::string kToken = "123"; + ResetAndInitializeAccountManager(); + EXPECT_CALL(*account_manager_.get(), RevokeGaiaTokenOnServer(kToken)); + + account_manager_->UpsertToken(kAccountKey_, kToken); + scoped_task_environment_.RunUntilIdle(); + + account_manager_->RemoveAccount(kAccountKey_); +} + +TEST_F(AccountManagerTest, TokenRevocationIsNotAttemptedForNonGaiaAccounts) { + ResetAndInitializeAccountManager(); + EXPECT_CALL(*account_manager_.get(), RevokeGaiaTokenOnServer(_)).Times(0); + + const AccountManager::AccountKey adAccountKey{ + "999", account_manager::AccountType::ACCOUNT_TYPE_ACTIVE_DIRECTORY}; + account_manager_->UpsertToken(adAccountKey, "123"); + scoped_task_environment_.RunUntilIdle(); + + account_manager_->RemoveAccount(adAccountKey); +} + +TEST_F(AccountManagerTest, TokenRevocationIsNotAttemptedForEmptyTokens) { + ResetAndInitializeAccountManager(); + EXPECT_CALL(*account_manager_.get(), RevokeGaiaTokenOnServer(_)).Times(0); + + account_manager_->UpsertToken(kAccountKey_, std::string()); + scoped_task_environment_.RunUntilIdle(); + + account_manager_->RemoveAccount(kAccountKey_); +} + } // namespace chromeos
diff --git a/chromeos/services/secure_channel/BUILD.gn b/chromeos/services/secure_channel/BUILD.gn index 300c927..1cb4a952 100644 --- a/chromeos/services/secure_channel/BUILD.gn +++ b/chromeos/services/secure_channel/BUILD.gn
@@ -179,6 +179,7 @@ deps = [ ":secure_channel", "//base", + "//base/test:test_support", "//chromeos/services/secure_channel/public/cpp/shared", "//chromeos/services/secure_channel/public/cpp/shared:connection_priority", "//chromeos/services/secure_channel/public/mojom",
diff --git a/components/autofill/content/common/autofill_types.mojom b/components/autofill/content/common/autofill_types.mojom index 82c9601..71e5244 100644 --- a/components/autofill/content/common/autofill_types.mojom +++ b/components/autofill/content/common/autofill_types.mojom
@@ -143,6 +143,7 @@ bool is_formless_checkout; uint32 unique_renderer_id; array<FormFieldData> fields; + array<uint32> username_predictions; }; // autofill::FormFieldDataPredictions
diff --git a/components/autofill/content/common/autofill_types_struct_traits.cc b/components/autofill/content/common/autofill_types_struct_traits.cc index 23bdb8f..f0cb980 100644 --- a/components/autofill/content/common/autofill_types_struct_traits.cc +++ b/components/autofill/content/common/autofill_types_struct_traits.cc
@@ -615,6 +615,9 @@ if (!data.ReadFields(&out->fields)) return false; + if (!data.ReadUsernamePredictions(&out->username_predictions)) + return false; + return true; }
diff --git a/components/autofill/content/common/autofill_types_struct_traits.h b/components/autofill/content/common/autofill_types_struct_traits.h index b3a9a0d2..2f4cdc23 100644 --- a/components/autofill/content/common/autofill_types_struct_traits.h +++ b/components/autofill/content/common/autofill_types_struct_traits.h
@@ -264,6 +264,11 @@ return r.fields; } + static const std::vector<uint32_t>& username_predictions( + const autofill::FormData& r) { + return r.username_predictions; + } + static bool Read(autofill::mojom::FormDataDataView data, autofill::FormData* out); };
diff --git a/components/autofill/content/common/autofill_types_struct_traits_unittest.cc b/components/autofill/content/common/autofill_types_struct_traits_unittest.cc index b243645..ea65d12 100644 --- a/components/autofill/content/common/autofill_types_struct_traits_unittest.cc +++ b/components/autofill/content/common/autofill_types_struct_traits_unittest.cc
@@ -341,6 +341,7 @@ TEST_F(AutofillTypeTraitsTestImpl, PassFormData) { FormData input; test::CreateTestAddressFormData(&input); + input.username_predictions = {1, 13, 2}; base::RunLoop loop; mojom::TypeTraitsTestPtr proxy = GetTypeTraitsTestProxy();
diff --git a/components/autofill/content/renderer/password_form_conversion_utils.cc b/components/autofill/content/renderer/password_form_conversion_utils.cc index f535e465..d2809dd 100644 --- a/components/autofill/content/renderer/password_form_conversion_utils.cc +++ b/components/autofill/content/renderer/password_form_conversion_utils.cc
@@ -10,7 +10,6 @@ #include <set> #include <string> -#include "base/containers/flat_set.h" #include "base/i18n/case_conversion.h" #include "base/lazy_instance.h" #include "base/macros.h" @@ -406,20 +405,15 @@ // Find the first element in |username_predictions| (i.e. the most reliable // prediction) that occurs in |possible_usernames|. const FormFieldData* FindUsernameInPredictions( - const std::vector<const FormFieldData*>& username_predictions, + const std::vector<uint32_t>& username_predictions, const std::vector<const FormFieldData*>& possible_usernames) { - // To speed-up the matching for-loop below, convert |possible_usernames| to a - // set. Creating is O(N log N) for N=possible_usernames.size(). Retrieval is - // O(log N), so the whole for-loop is O(M log N) for - // M=username_predictions.size(). Use flat_set, because of cache locality (the - // M and N are likely small, so this can make a difference) and less heap - // allocations. - const base::flat_set<const FormFieldData*> usernames( - possible_usernames.begin(), possible_usernames.end()); - - for (const FormFieldData* prediction : username_predictions) { - auto iter = usernames.find(prediction); - if (iter != usernames.end()) { + for (uint32_t predicted_id : username_predictions) { + auto iter = + std::find_if(possible_usernames.begin(), possible_usernames.end(), + [predicted_id](const FormFieldData* field) { + return field->unique_renderer_id == predicted_id; + }); + if (iter != possible_usernames.end()) { return *iter; } } @@ -430,11 +424,11 @@ // elements of the form, |form_data| should be the already extracted FormData // representation of that form. |username_detector_cache| is optional, and can // be used to spare recomputation if called multiple times for the same form. -std::vector<const FormFieldData*> GetUsernamePredictions( +std::vector<uint32_t> GetUsernamePredictions( const std::vector<blink::WebFormControlElement>& control_elements, const FormData& form_data, UsernameDetectorCache* username_detector_cache) { - std::vector<const FormFieldData*> username_predictions; + std::vector<uint32_t> username_predictions; // Dummy cache stores the predictions in case no real cache was passed to // here. UsernameDetectorCache dummy_cache; @@ -445,21 +439,8 @@ GetPredictionsFieldBasedOnHtmlAttributes(control_elements, form_data, username_detector_cache); username_predictions.reserve(username_predictions_dom.size()); - - // Convert the DOM elements to FormFieldData. - std::map<uint32_t, const FormFieldData*> id_to_fields; - for (const FormFieldData& field : form_data.fields) { - auto insert_result = - id_to_fields.insert({field.unique_renderer_id, &field}); - DCHECK(insert_result.second) << "Unique ID is not unique."; - } for (const WebInputElement& element : username_predictions_dom) { - std::map<uint32_t, const FormFieldData*>::const_iterator prediction_it = - id_to_fields.find(element.UniqueRendererFormControlId()); - // Note: some of the |element|s may not have an equivalent in - // |form_data.fields|, e.g., because those are not autofillable. - if (prediction_it != id_to_fields.end()) - username_predictions.push_back(prediction_it->second); + username_predictions.push_back(element.UniqueRendererFormControlId()); } return username_predictions; } @@ -483,11 +464,10 @@ return false; // Evaluate the context of the fields. - std::vector<const FormFieldData*> username_predictions; if (base::FeatureList::IsEnabled( password_manager::features::kHtmlBasedUsernameDetector)) { - username_predictions = GetUsernamePredictions(control_elements, form_data, - username_detector_cache); + password_form->form_data.username_predictions = GetUsernamePredictions( + control_elements, form_data, username_detector_cache); } // Narrow the scope to enabled inputs. @@ -664,8 +644,8 @@ // Use HTML based username detector only if neither server predictions nor // autocomplete attributes were useful to detect the username. if (!predicted_username_field && !username_by_attribute) { - username_field_by_context = - FindUsernameInPredictions(username_predictions, plausible_usernames); + username_field_by_context = FindUsernameInPredictions( + form_data.username_predictions, plausible_usernames); } }
diff --git a/components/autofill/core/browser/autofill_experiments_unittest.cc b/components/autofill/core/browser/autofill_experiments_unittest.cc index 36bb8b7..94a54cb3 100644 --- a/components/autofill/core/browser/autofill_experiments_unittest.cc +++ b/components/autofill/core/browser/autofill_experiments_unittest.cc
@@ -62,7 +62,7 @@ TEST_F(AutofillExperimentsTest, DenyUpload_SyncServiceDoesNotHaveAutofillProfilePreferredDataType) { scoped_feature_list_.InitAndEnableFeature(kAutofillUpstream); - sync_service_.SetPreferredDataTypes(syncer::ModelTypeSet()); + sync_service_.SetDataTypes(syncer::ModelTypeSet()); EXPECT_FALSE(IsCreditCardUploadEnabled()); }
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc index 51bd0ec0..6e83abc9 100644 --- a/components/autofill/core/browser/personal_data_manager_unittest.cc +++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -5692,7 +5692,7 @@ TEST_F(PersonalDataManagerTest, CreateDataForTest) { // Disable sync so the data gets created. - sync_service_.SetPreferredDataTypes(syncer::ModelTypeSet()); + sync_service_.SetDataTypes(syncer::ModelTypeSet()); // By default, the creation of test data is disabled. ResetPersonalDataManager(USER_MODE_NORMAL);
diff --git a/components/autofill/core/browser/test_sync_service.cc b/components/autofill/core/browser/test_sync_service.cc index 0077449b..ec294237 100644 --- a/components/autofill/core/browser/test_sync_service.cc +++ b/components/autofill/core/browser/test_sync_service.cc
@@ -14,8 +14,7 @@ namespace autofill { -TestSyncService::TestSyncService() - : preferred_data_types_(syncer::ModelTypeSet::All()) {} +TestSyncService::TestSyncService() : data_types_(syncer::ModelTypeSet::All()) {} TestSyncService::~TestSyncService() {} @@ -24,7 +23,11 @@ } syncer::ModelTypeSet TestSyncService::GetPreferredDataTypes() const { - return preferred_data_types_; + return data_types_; +} + +syncer::ModelTypeSet TestSyncService::GetActiveDataTypes() const { + return data_types_; } bool TestSyncService::IsEngineInitialized() const {
diff --git a/components/autofill/core/browser/test_sync_service.h b/components/autofill/core/browser/test_sync_service.h index 0bf32d9..f90b97a 100644 --- a/components/autofill/core/browser/test_sync_service.h +++ b/components/autofill/core/browser/test_sync_service.h
@@ -18,6 +18,7 @@ // FakeSyncService: bool CanSyncStart() const override; syncer::ModelTypeSet GetPreferredDataTypes() const override; + syncer::ModelTypeSet GetActiveDataTypes() const override; bool IsEngineInitialized() const override; bool IsUsingSecondaryPassphrase() const override; bool IsSyncActive() const override; @@ -30,8 +31,8 @@ can_sync_start_ = can_sync_start; } - void SetPreferredDataTypes(syncer::ModelTypeSet preferred_data_types) { - preferred_data_types_ = preferred_data_types; + void SetDataTypes(syncer::ModelTypeSet data_types) { + data_types_ = data_types; } void SetIsEngineInitialized(bool is_engine_initialized) { @@ -56,7 +57,8 @@ private: bool can_sync_start_ = true; - syncer::ModelTypeSet preferred_data_types_; + // Used as both "preferred" and "active" data types. + syncer::ModelTypeSet data_types_; bool is_engine_initialized_ = true; bool is_using_secondary_passphrase_ = false; bool is_sync_active_ = true;
diff --git a/components/autofill/core/common/form_data.cc b/components/autofill/core/common/form_data.cc index 3fb7a74..b583c5f 100644 --- a/components/autofill/core/common/form_data.cc +++ b/components/autofill/core/common/form_data.cc
@@ -78,7 +78,8 @@ is_form_tag(data.is_form_tag), is_formless_checkout(data.is_formless_checkout), unique_renderer_id(data.unique_renderer_id), - fields(data.fields) {} + fields(data.fields), + username_predictions(data.username_predictions) {} FormData::~FormData() { } @@ -114,7 +115,8 @@ unique_renderer_id == form.unique_renderer_id && is_form_tag == form.is_form_tag && is_formless_checkout == form.is_formless_checkout && - fields == form.fields; + fields == form.fields && + username_predictions == form.username_predictions; } bool FormData::operator!=(const FormData& form) const {
diff --git a/components/autofill/core/common/form_data.h b/components/autofill/core/common/form_data.h index d817c21..33ee62b 100644 --- a/components/autofill/core/common/form_data.h +++ b/components/autofill/core/common/form_data.h
@@ -61,6 +61,12 @@ uint32_t unique_renderer_id = kNotSetFormRendererId; // A vector of all the input fields in the form. std::vector<FormFieldData> fields; + // Contains unique renderer IDs of text elements which are predicted to be + // usernames. The order matters: elements are sorted in descending likelihood + // of being a username (the first one is the most likely username). Can + // contain IDs of elements which are not in |fields|. This is only used during + // parsing into PasswordForm, and hence not serialised for storage. + std::vector<uint32_t> username_predictions; }; // For testing.
diff --git a/components/bookmarks/browser/bookmark_client.h b/components/bookmarks/browser/bookmark_client.h index 348f660..a999669 100644 --- a/components/bookmarks/browser/bookmark_client.h +++ b/components/bookmarks/browser/bookmark_client.h
@@ -89,6 +89,19 @@ // should give the client a means to temporarily disable those checks. // http://crbug.com/49598 virtual bool CanBeEditedByUser(const BookmarkNode* node) = 0; + + // Encodes the bookmark sync data into a string blob. It's used by the + // bookmark model to persist the sync metadata together with the bookmark + // model. + virtual std::string EncodeBookmarkSyncMetadata() = 0; + + // Decodes a string represeting the sync metadata stored in |metadata_str|. + // The model calls this method after it has loaded the model data. + // |schedule_save_closure| is a repeating call back to trigger a model and + // metadata persistence process. + virtual void DecodeBookmarkSyncMetadata( + const std::string& metadata_str, + const base::RepeatingClosure& schedule_save_closure) = 0; }; } // namespace bookmarks
diff --git a/components/bookmarks/browser/bookmark_codec.cc b/components/bookmarks/browser/bookmark_codec.cc index 04adafb..40a6a43 100644 --- a/components/bookmarks/browser/bookmark_codec.cc +++ b/components/bookmarks/browser/bookmark_codec.cc
@@ -10,6 +10,7 @@ #include <memory> #include <utility> +#include "base/base64.h" #include "base/json/json_string_value_serializer.h" #include "base/memory/ptr_util.h" #include "base/strings/string_number_conversions.h" @@ -43,6 +44,7 @@ "sync_transaction_version"; const char BookmarkCodec::kTypeURL[] = "url"; const char BookmarkCodec::kTypeFolder[] = "folder"; +const char BookmarkCodec::kSyncMetadata[] = "sync_metadata"; // Current version of the file. static const int kCurrentVersion = 1; @@ -57,12 +59,13 @@ BookmarkCodec::~BookmarkCodec() {} -std::unique_ptr<base::Value> BookmarkCodec::Encode(BookmarkModel* model) { - return Encode(model->bookmark_bar_node(), - model->other_node(), - model->mobile_node(), - model->root_node()->GetMetaInfoMap(), - model->root_node()->sync_transaction_version()); +std::unique_ptr<base::Value> BookmarkCodec::Encode( + BookmarkModel* model, + const std::string& sync_metadata_str) { + return Encode(model->bookmark_bar_node(), model->other_node(), + model->mobile_node(), model->root_node()->GetMetaInfoMap(), + model->root_node()->sync_transaction_version(), + sync_metadata_str); } std::unique_ptr<base::Value> BookmarkCodec::Encode( @@ -70,7 +73,8 @@ const BookmarkNode* other_folder_node, const BookmarkNode* mobile_folder_node, const BookmarkNode::MetaInfoMap* model_meta_info_map, - int64_t sync_transaction_version) { + int64_t sync_transaction_version, + const std::string& sync_metadata_str) { ids_reassigned_ = false; InitializeChecksum(); auto roots = std::make_unique<base::DictionaryValue>(); @@ -92,14 +96,20 @@ stored_checksum_ = computed_checksum_; main->SetString(kChecksumKey, computed_checksum_); main->Set(kRootsKey, std::move(roots)); + if (!sync_metadata_str.empty()) { + std::string sync_metadata_str_base64; + base::Base64Encode(sync_metadata_str, &sync_metadata_str_base64); + main->SetString(kSyncMetadata, std::move(sync_metadata_str_base64)); + } return std::move(main); } -bool BookmarkCodec::Decode(BookmarkNode* bb_node, +bool BookmarkCodec::Decode(const base::Value& value, + BookmarkNode* bb_node, BookmarkNode* other_folder_node, BookmarkNode* mobile_folder_node, int64_t* max_id, - const base::Value& value) { + std::string* sync_metadata_str) { ids_.clear(); ids_reassigned_ = false; ids_valid_ = true; @@ -107,7 +117,7 @@ stored_checksum_.clear(); InitializeChecksum(); bool success = DecodeHelper(bb_node, other_folder_node, mobile_folder_node, - value); + value, sync_metadata_str); FinalizeChecksum(); // If either the checksums differ or some IDs were missing/not unique, // reassign IDs. @@ -167,7 +177,8 @@ bool BookmarkCodec::DecodeHelper(BookmarkNode* bb_node, BookmarkNode* other_folder_node, BookmarkNode* mobile_folder_node, - const base::Value& value) { + const base::Value& value, + std::string* sync_metadata_str) { const base::DictionaryValue* d_value = nullptr; if (!value.GetAsDictionary(&d_value)) return false; // Unexpected type. @@ -234,6 +245,12 @@ &model_sync_transaction_version_)) return false; + std::string sync_metadata_str_base64; + if (sync_metadata_str && + d_value->GetString(kSyncMetadata, &sync_metadata_str_base64)) { + base::Base64Decode(sync_metadata_str_base64, sync_metadata_str); + } + // Need to reset the type as decoding resets the type to FOLDER. Similarly // we need to reset the title as the title is persisted and restored from // the file.
diff --git a/components/bookmarks/browser/bookmark_codec.h b/components/bookmarks/browser/bookmark_codec.h index 313729ef..e3fee209 100644 --- a/components/bookmarks/browser/bookmark_codec.h +++ b/components/bookmarks/browser/bookmark_codec.h
@@ -42,7 +42,8 @@ // returned object. This is invoked to encode the contents of the bookmark bar // model and is currently a convenience to invoking Encode that takes the // bookmark bar node and other folder node. - std::unique_ptr<base::Value> Encode(BookmarkModel* model); + std::unique_ptr<base::Value> Encode(BookmarkModel* model, + const std::string& sync_metadata_str); // Encodes the bookmark bar and other folders returning the JSON value. std::unique_ptr<base::Value> Encode( @@ -50,18 +51,20 @@ const BookmarkNode* other_folder_node, const BookmarkNode* mobile_folder_node, const BookmarkNode::MetaInfoMap* model_meta_info_map, - int64_t sync_transaction_version); + int64_t sync_transaction_version, + const std::string& sync_metadata_str); // Decodes the previously encoded value to the specified nodes as well as // setting |max_node_id| to the greatest node id. Returns true on success, // false otherwise. If there is an error (such as unexpected version) all // children are removed from the bookmark bar and other folder nodes. On exit // |max_node_id| is set to the max id of the nodes. - bool Decode(BookmarkNode* bb_node, + bool Decode(const base::Value& value, + BookmarkNode* bb_node, BookmarkNode* other_folder_node, BookmarkNode* mobile_folder_node, int64_t* max_node_id, - const base::Value& value); + std::string* sync_metadata_str); // Returns the checksum computed during last encoding/decoding call. const std::string& computed_checksum() const { return computed_checksum_; } @@ -103,6 +106,9 @@ static const char kChildrenKey[]; static const char kMetaInfo[]; static const char kSyncTransactionVersion[]; + // Allows the BookmarkClient to read and a write a string blob from the JSON + // file. That string captures the bookmarks sync metadata. + static const char kSyncMetadata[]; // Possible values for kTypeKey. static const char kTypeURL[]; @@ -120,7 +126,8 @@ bool DecodeHelper(BookmarkNode* bb_node, BookmarkNode* other_folder_node, BookmarkNode* mobile_folder_node, - const base::Value& value); + const base::Value& value, + std::string* sync_metadata_str); // Decodes the children of the specified node. Returns true on success. bool DecodeChildren(const base::ListValue& child_value_list,
diff --git a/components/bookmarks/browser/bookmark_codec_unittest.cc b/components/bookmarks/browser/bookmark_codec_unittest.cc index 11d51d5a..8040fd6 100644 --- a/components/bookmarks/browser/bookmark_codec_unittest.cc +++ b/components/bookmarks/browser/bookmark_codec_unittest.cc
@@ -145,13 +145,17 @@ child_value->GetAsDictionary(result_value); } - base::Value* EncodeHelper(BookmarkModel* model, std::string* checksum) { + std::unique_ptr<base::Value> EncodeHelper( + BookmarkModel* model, + const std::string& sync_metadata_str, + std::string* checksum) { BookmarkCodec encoder; // Computed and stored checksums should be empty. EXPECT_EQ("", encoder.computed_checksum()); EXPECT_EQ("", encoder.stored_checksum()); - std::unique_ptr<base::Value> value(encoder.Encode(model)); + std::unique_ptr<base::Value> value( + encoder.Encode(model, sync_metadata_str)); const std::string& computed_checksum = encoder.computed_checksum(); const std::string& stored_checksum = encoder.stored_checksum(); @@ -161,18 +165,18 @@ EXPECT_EQ(computed_checksum, stored_checksum); *checksum = computed_checksum; - return value.release(); + return value; } bool Decode(BookmarkCodec* codec, + const base::Value& value, BookmarkModel* model, - const base::Value& value) { + std::string* sync_metadata_str) { int64_t max_id; - bool result = codec->Decode(AsMutable(model->bookmark_bar_node()), + bool result = codec->Decode(value, AsMutable(model->bookmark_bar_node()), AsMutable(model->other_node()), - AsMutable(model->mobile_node()), - &max_id, - value); + AsMutable(model->mobile_node()), &max_id, + sync_metadata_str); model->set_next_node_id(max_id); AsMutable(model->root_node())->SetMetaInfoMap(codec->model_meta_info_map()); AsMutable(model->root_node()) @@ -181,17 +185,20 @@ return result; } - BookmarkModel* DecodeHelper(const base::Value& value, - const std::string& expected_stored_checksum, - std::string* computed_checksum, - bool expected_changes) { + std::unique_ptr<BookmarkModel> DecodeHelper( + const base::Value& value, + const std::string& expected_stored_checksum, + std::string* computed_checksum, + bool expected_changes, + std::string* sync_metadata_str) { BookmarkCodec decoder; // Computed and stored checksums should be empty. EXPECT_EQ("", decoder.computed_checksum()); EXPECT_EQ("", decoder.stored_checksum()); std::unique_ptr<BookmarkModel> model(TestBookmarkClient::CreateModel()); - EXPECT_TRUE(Decode(&decoder, model.get(), value)); + EXPECT_TRUE(Decode(&decoder, value, model.get(), + /*sync_metadata_str=*/sync_metadata_str)); *computed_checksum = decoder.computed_checksum(); const std::string& stored_checksum = decoder.stored_checksum(); @@ -210,7 +217,7 @@ else EXPECT_EQ(*computed_checksum, stored_checksum); - return model.release(); + return model; } void CheckIDs(const BookmarkNode* node, std::set<int64_t>* assigned_ids) { @@ -233,14 +240,16 @@ TEST_F(BookmarkCodecTest, ChecksumEncodeDecodeTest) { std::unique_ptr<BookmarkModel> model_to_encode(CreateTestModel1()); std::string enc_checksum; - std::unique_ptr<base::Value> value( - EncodeHelper(model_to_encode.get(), &enc_checksum)); + std::unique_ptr<base::Value> value = + EncodeHelper(model_to_encode.get(), /*sync_metadata_str=*/std::string(), + &enc_checksum); EXPECT_TRUE(value.get() != nullptr); std::string dec_checksum; - std::unique_ptr<BookmarkModel> decoded_model( - DecodeHelper(*value.get(), enc_checksum, &dec_checksum, false)); + std::unique_ptr<BookmarkModel> decoded_model = + DecodeHelper(*value.get(), enc_checksum, &dec_checksum, false, + /*sync_metadata_str=*/nullptr); } TEST_F(BookmarkCodecTest, ChecksumEncodeIdenticalModelsTest) { @@ -248,14 +257,14 @@ // as the data is the same. std::unique_ptr<BookmarkModel> model1(CreateTestModel1()); std::string enc_checksum1; - std::unique_ptr<base::Value> value1( - EncodeHelper(model1.get(), &enc_checksum1)); + std::unique_ptr<base::Value> value1 = EncodeHelper( + model1.get(), /*sync_metadata_str=*/std::string(), &enc_checksum1); EXPECT_TRUE(value1.get() != nullptr); std::unique_ptr<BookmarkModel> model2(CreateTestModel1()); std::string enc_checksum2; - std::unique_ptr<base::Value> value2( - EncodeHelper(model2.get(), &enc_checksum2)); + std::unique_ptr<base::Value> value2 = EncodeHelper( + model2.get(), /*sync_metadata_str=*/std::string(), &enc_checksum2); EXPECT_TRUE(value2.get() != nullptr); ASSERT_EQ(enc_checksum1, enc_checksum2); @@ -264,8 +273,9 @@ TEST_F(BookmarkCodecTest, ChecksumManualEditTest) { std::unique_ptr<BookmarkModel> model_to_encode(CreateTestModel1()); std::string enc_checksum; - std::unique_ptr<base::Value> value( - EncodeHelper(model_to_encode.get(), &enc_checksum)); + std::unique_ptr<base::Value> value = + EncodeHelper(model_to_encode.get(), /*sync_metadata_str=*/std::string(), + &enc_checksum); EXPECT_TRUE(value.get() != nullptr); @@ -277,13 +287,15 @@ child1_value->SetString(BookmarkCodec::kNameKey, title + "1"); std::string dec_checksum; - std::unique_ptr<BookmarkModel> decoded_model1( - DecodeHelper(*value.get(), enc_checksum, &dec_checksum, true)); + std::unique_ptr<BookmarkModel> decoded_model1 = + DecodeHelper(*value.get(), enc_checksum, &dec_checksum, true, + /*sync_metadata_str=*/nullptr); // Undo the change and make sure the checksum is same as original. child1_value->SetString(BookmarkCodec::kNameKey, title); - std::unique_ptr<BookmarkModel> decoded_model2( - DecodeHelper(*value.get(), enc_checksum, &dec_checksum, false)); + std::unique_ptr<BookmarkModel> decoded_model2 = + DecodeHelper(*value.get(), enc_checksum, &dec_checksum, false, + /*sync_metadata_str=*/nullptr); } TEST_F(BookmarkCodecTest, ChecksumManualEditIDsTest) { @@ -295,8 +307,9 @@ ASSERT_GT(bb_child_count, 1); std::string enc_checksum; - std::unique_ptr<base::Value> value( - EncodeHelper(model_to_encode.get(), &enc_checksum)); + std::unique_ptr<base::Value> value = + EncodeHelper(model_to_encode.get(), /*sync_metadata_str=*/std::string(), + &enc_checksum); EXPECT_TRUE(value.get() != nullptr); @@ -310,8 +323,9 @@ } std::string dec_checksum; - std::unique_ptr<BookmarkModel> decoded_model( - DecodeHelper(*value.get(), enc_checksum, &dec_checksum, true)); + std::unique_ptr<BookmarkModel> decoded_model = + DecodeHelper(*value.get(), enc_checksum, &dec_checksum, true, + /*sync_metadata_str=*/nullptr); ExpectIDsUnique(decoded_model.get()); @@ -329,12 +343,13 @@ std::unique_ptr<BookmarkModel> model_to_encode(CreateTestModel3()); BookmarkCodec encoder; std::unique_ptr<base::Value> model_value( - encoder.Encode(model_to_encode.get())); + encoder.Encode(model_to_encode.get(), std::string())); std::unique_ptr<BookmarkModel> decoded_model( TestBookmarkClient::CreateModel()); BookmarkCodec decoder; - ASSERT_TRUE(Decode(&decoder, decoded_model.get(), *model_value.get())); + ASSERT_TRUE(Decode(&decoder, *model_value.get(), decoded_model.get(), + /*sync_metadata_str=*/nullptr)); ASSERT_NO_FATAL_FAILURE( AssertModelsEqual(model_to_encode.get(), decoded_model.get())); @@ -352,12 +367,13 @@ BookmarkCodec encoder2; std::unique_ptr<base::Value> model_value2( - encoder2.Encode(decoded_model.get())); + encoder2.Encode(decoded_model.get(), std::string())); std::unique_ptr<BookmarkModel> decoded_model2( TestBookmarkClient::CreateModel()); BookmarkCodec decoder2; - ASSERT_TRUE(Decode(&decoder2, decoded_model2.get(), *model_value2.get())); + ASSERT_TRUE(Decode(&decoder2, *model_value2.get(), decoded_model2.get(), + /*sync_metadata_str=*/nullptr)); ASSERT_NO_FATAL_FAILURE( AssertModelsEqual(decoded_model.get(), decoded_model2.get())); } @@ -374,7 +390,8 @@ std::unique_ptr<BookmarkModel> decoded_model( TestBookmarkClient::CreateModel()); BookmarkCodec decoder; - ASSERT_TRUE(Decode(&decoder, decoded_model.get(), *root.get())); + ASSERT_TRUE(Decode(&decoder, *root.get(), decoded_model.get(), + /*sync_metadata_str=*/nullptr)); ExpectIDsUnique(decoded_model.get()); const BookmarkNode* bbn = decoded_model->bookmark_bar_node(); @@ -411,11 +428,13 @@ model->SetNodeMetaInfo( model->bookmark_bar_node()->GetChild(0), "node_info", "value2"); std::string checksum; - std::unique_ptr<base::Value> value(EncodeHelper(model.get(), &checksum)); + std::unique_ptr<base::Value> value = + EncodeHelper(model.get(), /*sync_metadata_str=*/std::string(), &checksum); ASSERT_TRUE(value.get() != nullptr); // Decode and check for meta info. - model.reset(DecodeHelper(*value, checksum, &checksum, false)); + model = DecodeHelper(*value, checksum, &checksum, false, + /*sync_metadata_str=*/nullptr); std::string meta_value; EXPECT_TRUE(model->root_node()->GetMetaInfo("model_info", &meta_value)); EXPECT_EQ("value1", meta_value); @@ -436,11 +455,13 @@ model->SetNodeSyncTransactionVersion(bbn->GetChild(1), 42); std::string checksum; - std::unique_ptr<base::Value> value(EncodeHelper(model.get(), &checksum)); + std::unique_ptr<base::Value> value = + EncodeHelper(model.get(), /*sync_metadata_str=*/std::string(), &checksum); ASSERT_TRUE(value.get() != nullptr); // Decode and verify. - model.reset(DecodeHelper(*value, checksum, &checksum, false)); + model = DecodeHelper(*value, checksum, &checksum, false, + /*sync_metadata_str=*/nullptr); EXPECT_EQ(1, model->root_node()->sync_transaction_version()); bbn = model->bookmark_bar_node(); EXPECT_EQ(42, bbn->GetChild(1)->sync_transaction_version()); @@ -461,7 +482,8 @@ std::unique_ptr<BookmarkModel> model(TestBookmarkClient::CreateModel()); BookmarkCodec decoder; - ASSERT_TRUE(Decode(&decoder, model.get(), *root.get())); + ASSERT_TRUE(Decode(&decoder, *root.get(), model.get(), + /*sync_metadata_str=*/nullptr)); EXPECT_EQ(1, model->root_node()->sync_transaction_version()); const BookmarkNode* bbn = model->bookmark_bar_node(); @@ -485,4 +507,20 @@ EXPECT_EQ("value3", meta_value); } +TEST_F(BookmarkCodecTest, EncodeAndDecodeSyncMetadata) { + std::unique_ptr<BookmarkModel> model(CreateTestModel1()); + + // Since metadata str serialized proto, it could contain no ASCII characters. + std::string sync_metadata_str("a/2'\""); + std::string checksum; + std::unique_ptr<base::Value> value = + EncodeHelper(model.get(), sync_metadata_str, &checksum); + ASSERT_TRUE(value.get() != nullptr); + + std::string decoded_sync_metadata_str; + // Decode and verify. + DecodeHelper(*value, checksum, &checksum, false, &decoded_sync_metadata_str); + EXPECT_EQ(sync_metadata_str, decoded_sync_metadata_str); +} + } // namespace bookmarks
diff --git a/components/bookmarks/browser/bookmark_model.cc b/components/bookmarks/browser/bookmark_model.cc index 7c905b2..a448ffc6 100644 --- a/components/bookmarks/browser/bookmark_model.cc +++ b/components/bookmarks/browser/bookmark_model.cc
@@ -814,6 +814,11 @@ details->model_sync_transaction_version()); loaded_ = true; + client_->DecodeBookmarkSyncMetadata( + details->sync_metadata_str(), + store_ ? base::BindRepeating(&BookmarkStorage::ScheduleSave, + base::Unretained(store_.get())) + : base::DoNothing()); // Notify our direct observers. for (BookmarkModelObserver& observer : observers_)
diff --git a/components/bookmarks/browser/bookmark_storage.cc b/components/bookmarks/browser/bookmark_storage.cc index 578817e..0cf205f0 100644 --- a/components/bookmarks/browser/bookmark_storage.cc +++ b/components/bookmarks/browser/bookmark_storage.cc
@@ -74,10 +74,13 @@ // Building the index can take a while, so we do it on the background // thread. int64_t max_node_id = 0; + std::string sync_metadata_str; BookmarkCodec codec; TimeTicks start_time = TimeTicks::Now(); - codec.Decode(details->bb_node(), details->other_folder_node(), - details->mobile_folder_node(), &max_node_id, *root); + codec.Decode(*root, details->bb_node(), details->other_folder_node(), + details->mobile_folder_node(), &max_node_id, + &sync_metadata_str); + details->set_sync_metadata_str(std::move(sync_metadata_str)); details->set_max_id(std::max(max_node_id, details->max_id())); details->set_computed_checksum(codec.computed_checksum()); details->set_stored_checksum(codec.stored_checksum()); @@ -243,7 +246,8 @@ bool BookmarkStorage::SerializeData(std::string* output) { BookmarkCodec codec; - std::unique_ptr<base::Value> value(codec.Encode(model_)); + std::unique_ptr<base::Value> value( + codec.Encode(model_, model_->client()->EncodeBookmarkSyncMetadata())); JSONStringValueSerializer serializer(output); serializer.set_pretty_print(true); return serializer.Serialize(*(value.get()));
diff --git a/components/bookmarks/browser/bookmark_storage.h b/components/bookmarks/browser/bookmark_storage.h index 86d37f2c..1abc6da 100644 --- a/components/bookmarks/browser/bookmark_storage.h +++ b/components/bookmarks/browser/bookmark_storage.h
@@ -104,6 +104,13 @@ void set_ids_reassigned(bool value) { ids_reassigned_ = value; } bool ids_reassigned() const { return ids_reassigned_; } + // Returns the string blob representing the sync metadata in the json file. + // The string blob is set during decode time upon the call to Bookmark::Load. + void set_sync_metadata_str(std::string sync_metadata_str) { + sync_metadata_str_ = std::move(sync_metadata_str); + } + const std::string& sync_metadata_str() const { return sync_metadata_str_; } + void CreateUrlIndex(); UrlIndex* url_index() { return url_index_.get(); } @@ -127,6 +134,8 @@ std::string stored_checksum_; bool ids_reassigned_ = false; scoped_refptr<UrlIndex> url_index_; + // A string blob represetning the sync metadata stored in the json file. + std::string sync_metadata_str_; DISALLOW_COPY_AND_ASSIGN(BookmarkLoadDetails); };
diff --git a/components/bookmarks/test/test_bookmark_client.cc b/components/bookmarks/test/test_bookmark_client.cc index 147b801..2adc400 100644 --- a/components/bookmarks/test/test_bookmark_client.cc +++ b/components/bookmarks/test/test_bookmark_client.cc
@@ -95,6 +95,14 @@ return !IsAnExtraNode(node); } +std::string TestBookmarkClient::EncodeBookmarkSyncMetadata() { + return std::string(); +} + +void TestBookmarkClient::DecodeBookmarkSyncMetadata( + const std::string& metadata_str, + const base::RepeatingClosure& schedule_save_closure) {} + // static BookmarkPermanentNodeList TestBookmarkClient::LoadExtraNodes( BookmarkPermanentNodeList extra_nodes,
diff --git a/components/bookmarks/test/test_bookmark_client.h b/components/bookmarks/test/test_bookmark_client.h index ac212bf..40f8e9e 100644 --- a/components/bookmarks/test/test_bookmark_client.h +++ b/components/bookmarks/test/test_bookmark_client.h
@@ -51,6 +51,10 @@ bool CanSetPermanentNodeTitle(const BookmarkNode* permanent_node) override; bool CanSyncNode(const BookmarkNode* node) override; bool CanBeEditedByUser(const BookmarkNode* node) override; + std::string EncodeBookmarkSyncMetadata() override; + void DecodeBookmarkSyncMetadata( + const std::string& metadata_str, + const base::RepeatingClosure& schedule_save_closure) override; // Helpers for GetLoadExtraNodesCallback(). static BookmarkPermanentNodeList LoadExtraNodes(
diff --git a/components/browser_sync/profile_sync_service.cc b/components/browser_sync/profile_sync_service.cc index cfbd4021..caa6ce79 100644 --- a/components/browser_sync/profile_sync_service.cc +++ b/components/browser_sync/profile_sync_service.cc
@@ -59,7 +59,6 @@ #include "components/sync/model_impl/client_tag_based_model_type_processor.h" #include "components/sync/syncable/directory.h" #include "components/sync/syncable/syncable_read_transaction.h" -#include "components/sync_bookmarks/bookmark_model_type_processor.h" #include "components/sync_preferences/pref_service_syncable.h" #include "components/sync_sessions/favicon_cache.h" #include "components/sync_sessions/session_data_type_controller.h" @@ -266,14 +265,6 @@ sync_enabled_weak_factory_.GetWeakPtr())); } - if (base::FeatureList::IsEnabled(switches::kSyncUSSBookmarks)) { - bookmark_model_type_processor_ = - std::make_unique<sync_bookmarks::BookmarkModelTypeProcessor>( - sync_client_->GetBookmarkUndoServiceIfExists()); - bookmark_model_type_processor_->DecodeSyncMetadata( - std::string(), base::DoNothing(), sync_client_->GetBookmarkModel()); - } - device_info_sync_bridge_ = std::make_unique<DeviceInfoSyncBridge>( local_device_.get(), model_type_store_factory_, std::make_unique<ClientTagBasedModelTypeProcessor>( @@ -2049,14 +2040,6 @@ } base::WeakPtr<syncer::ModelTypeControllerDelegate> -ProfileSyncService::GetBookmarkSyncControllerDelegateOnUIThread() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!bookmark_model_type_processor_) - return nullptr; - return bookmark_model_type_processor_->GetWeakPtr(); -} - -base::WeakPtr<syncer::ModelTypeControllerDelegate> ProfileSyncService::GetDeviceInfoSyncControllerDelegateOnUIThread() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return device_info_sync_bridge_->change_processor()
diff --git a/components/browser_sync/profile_sync_service.h b/components/browser_sync/profile_sync_service.h index 463d737..0237a0d 100644 --- a/components/browser_sync/profile_sync_service.h +++ b/components/browser_sync/profile_sync_service.h
@@ -80,10 +80,6 @@ struct UserShare; } // namespace syncer -namespace sync_bookmarks { -class BookmarkModelTypeProcessor; -} - namespace browser_sync { class SyncAuthManager; @@ -319,10 +315,6 @@ base::WeakPtr<syncer::ModelTypeControllerDelegate> GetSessionSyncControllerDelegateOnUIThread(); - // Returns the ModelTypeControllerDelegate for syncer::BOOKMARKS. - virtual base::WeakPtr<syncer::ModelTypeControllerDelegate> - GetBookmarkSyncControllerDelegateOnUIThread(); - // Returns the ModelTypeControllerDelegate for syncer::DEVICE_INFO. virtual base::WeakPtr<syncer::ModelTypeControllerDelegate> GetDeviceInfoSyncControllerDelegateOnUIThread(); @@ -794,11 +786,6 @@ std::unique_ptr<sync_sessions::AbstractSessionsSyncManager> sessions_sync_manager_; - // BookmarkModelTypeProcessor handles communications between sync engine and - // BookmarkModel/HistoryService. - std::unique_ptr<sync_bookmarks::BookmarkModelTypeProcessor> - bookmark_model_type_processor_; - std::unique_ptr<syncer::DeviceInfoSyncBridge> device_info_sync_bridge_; std::unique_ptr<syncer::NetworkResources> network_resources_;
diff --git a/components/component_updater/component_updater_command_line_config_policy.cc b/components/component_updater/component_updater_command_line_config_policy.cc index 00ff80c4..c9b6093 100644 --- a/components/component_updater/component_updater_command_line_config_policy.cc +++ b/components/component_updater/component_updater_command_line_config_policy.cc
@@ -9,6 +9,7 @@ #include "base/command_line.h" #include "base/stl_util.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "base/strings/sys_string_conversions.h" #include "build/build_config.h" @@ -37,6 +38,10 @@ // Disables differential updates. const char kSwitchDisableDeltaUpdates[] = "disable-delta-updates"; +// Configures the initial delay before the first component update check. The +// value is in seconds. +const char kInitialDelay[] = "initial-delay"; + #if defined(OS_WIN) // Disables background downloads. const char kSwitchDisableBackgroundDownloads[] = "disable-background-downloads"; @@ -91,6 +96,12 @@ url_source_override_ = GURL(switch_url_source); DCHECK(url_source_override_.is_valid()); } + + const std::string initial_delay = + GetSwitchArgument(switch_values, kInitialDelay); + int initial_delay_seconds = 0; + if (base::StringToInt(initial_delay, &initial_delay_seconds)) + initial_delay_ = initial_delay_seconds; } bool ComponentUpdaterCommandLineConfigPolicy::BackgroundDownloadsEnabled() @@ -118,4 +129,8 @@ return url_source_override_; } +int ComponentUpdaterCommandLineConfigPolicy::InitialDelay() const { + return initial_delay_; +} + } // namespace component_updater
diff --git a/components/component_updater/component_updater_command_line_config_policy.h b/components/component_updater/component_updater_command_line_config_policy.h index e3dbc67..e2c0370 100644 --- a/components/component_updater/component_updater_command_line_config_policy.h +++ b/components/component_updater/component_updater_command_line_config_policy.h
@@ -29,6 +29,7 @@ bool PingsEnabled() const override; bool TestRequest() const override; GURL UrlSourceOverride() const override; + int InitialDelay() const override; private: bool background_downloads_enabled_ = false; @@ -36,6 +37,11 @@ bool fast_update_ = false; bool pings_enabled_ = true; bool test_request_ = false; + + // If non-zero, time interval in seconds until the first component + // update check. + int initial_delay_ = 0; + GURL url_source_override_; DISALLOW_COPY_AND_ASSIGN(ComponentUpdaterCommandLineConfigPolicy);
diff --git a/components/component_updater/configurator_impl.cc b/components/component_updater/configurator_impl.cc index 4284662..2a63130 100644 --- a/components/component_updater/configurator_impl.cc +++ b/components/component_updater/configurator_impl.cc
@@ -41,7 +41,8 @@ fast_update_(config_policy.FastUpdate()), pings_enabled_(config_policy.PingsEnabled()), require_encryption_(require_encryption), - url_source_override_(config_policy.UrlSourceOverride()) { + url_source_override_(config_policy.UrlSourceOverride()), + initial_delay_(config_policy.InitialDelay()) { if (config_policy.TestRequest()) extra_info_ += "testrequest=\"1\""; } @@ -49,6 +50,8 @@ ConfiguratorImpl::~ConfiguratorImpl() {} int ConfiguratorImpl::InitialDelay() const { + if (initial_delay_) + return initial_delay_; return fast_update_ ? 10 : (6 * kDelayOneMinute); }
diff --git a/components/component_updater/configurator_impl.h b/components/component_updater/configurator_impl.h index 6494190b..73b4d3c3 100644 --- a/components/component_updater/configurator_impl.h +++ b/components/component_updater/configurator_impl.h
@@ -91,12 +91,13 @@ private: std::string extra_info_; - bool background_downloads_enabled_; - bool deltas_enabled_; - bool fast_update_; - bool pings_enabled_; - bool require_encryption_; - GURL url_source_override_; + const bool background_downloads_enabled_; + const bool deltas_enabled_; + const bool fast_update_; + const bool pings_enabled_; + const bool require_encryption_; + const GURL url_source_override_; + const int initial_delay_; DISALLOW_COPY_AND_ASSIGN(ConfiguratorImpl); };
diff --git a/components/component_updater/configurator_impl_unittest.cc b/components/component_updater/configurator_impl_unittest.cc index b0b10f5..5200eb9 100644 --- a/components/component_updater/configurator_impl_unittest.cc +++ b/components/component_updater/configurator_impl_unittest.cc
@@ -88,4 +88,55 @@ CHECK_EQ(10, config->UpdateDelay()); } +TEST_F(ComponentUpdaterConfiguratorImplTest, InitialDelay) { + std::unique_ptr<ConfiguratorImpl> config = std::make_unique<ConfiguratorImpl>( + update_client::CommandLineConfigPolicy(), false); + CHECK_EQ(6 * kDelayOneMinute, config->InitialDelay()); + + class CommandLineConfigPolicy + : public update_client::CommandLineConfigPolicy { + public: + CommandLineConfigPolicy() {} + + // update_client::CommandLineConfigPolicy overrides. + bool BackgroundDownloadsEnabled() const override { return false; } + bool DeltaUpdatesEnabled() const override { return false; } + bool FastUpdate() const override { return fast_update_; } + bool PingsEnabled() const override { return false; } + bool TestRequest() const override { return false; } + GURL UrlSourceOverride() const override { return GURL(); } + int InitialDelay() const override { return initial_delay_; }; + + void set_fast_update(bool fast_update) { fast_update_ = fast_update; } + void set_initial_delay(int initial_delay) { + initial_delay_ = initial_delay; + } + + private: + int initial_delay_ = 0; + bool fast_update_ = false; + }; + + { + CommandLineConfigPolicy clcp; + clcp.set_fast_update(true); + config = std::make_unique<ConfiguratorImpl>(clcp, false); + CHECK_EQ(10, config->InitialDelay()); + } + + { + CommandLineConfigPolicy clcp; + clcp.set_fast_update(false); + config = std::make_unique<ConfiguratorImpl>(clcp, false); + CHECK_EQ(6 * kDelayOneMinute, config->InitialDelay()); + } + + { + CommandLineConfigPolicy clcp; + clcp.set_initial_delay(kDelayOneMinute); + config = std::make_unique<ConfiguratorImpl>(clcp, false); + CHECK_EQ(kDelayOneMinute, config->InitialDelay()); + } +} + } // namespace component_updater
diff --git a/components/consent_auditor/consent_sync_bridge_impl.cc b/components/consent_auditor/consent_sync_bridge_impl.cc index 00371b63..3738b53 100644 --- a/components/consent_auditor/consent_sync_bridge_impl.cc +++ b/components/consent_auditor/consent_sync_bridge_impl.cc
@@ -135,35 +135,38 @@ #if !defined(OS_IOS) // https://crbug.com/834042 DCHECK(!authenticated_account_id_callback_.Run().empty()); #endif // !defined(OS_IOS) - bool was_sync_started = is_sync_starting_or_started_; + DCHECK(!is_sync_starting_or_started_); + is_sync_starting_or_started_ = true; - if (store_ && change_processor()->IsTrackingMetadata() && !was_sync_started) { + if (store_ && change_processor()->IsTrackingMetadata()) { ReadAllDataAndResubmit(); } } -ModelTypeSyncBridge::DisableSyncResponse -ConsentSyncBridgeImpl::ApplyDisableSyncChanges( +ModelTypeSyncBridge::StopSyncResponse +ConsentSyncBridgeImpl::ApplyStopSyncChanges( std::unique_ptr<MetadataChangeList> delete_metadata_change_list) { - // Sync can only be disabled after initialization. + // Sync can only be stopped after initialization. DCHECK(deferred_consents_while_initializing_.empty()); is_sync_starting_or_started_ = false; - // Preserve all consents in the store, but delete their metadata, because it - // may become invalid when the sync is reenabled. It is important to report - // all user consents, thus, they are persisted for some time even after - // signout. We will try to resubmit these consents once the sync is enabled - // again. This may lead to same consent being submitted multiple times, but - // this is allowed. - std::unique_ptr<WriteBatch> batch = store_->CreateWriteBatch(); - batch->TakeMetadataChangesFrom(std::move(delete_metadata_change_list)); + if (delete_metadata_change_list) { + // Preserve all consents in the store, but delete their metadata, because it + // may become invalid when the sync is reenabled. It is important to report + // all user consents, thus, they are persisted for some time even after + // signout. We will try to resubmit these consents once the sync is enabled + // again. This may lead to same consent being submitted multiple times, but + // this is allowed. + std::unique_ptr<WriteBatch> batch = store_->CreateWriteBatch(); + batch->TakeMetadataChangesFrom(std::move(delete_metadata_change_list)); - store_->CommitWriteBatch( - std::move(batch), - base::BindOnce(&ConsentSyncBridgeImpl::OnCommit, base::AsWeakPtr(this))); + store_->CommitWriteBatch(std::move(batch), + base::BindOnce(&ConsentSyncBridgeImpl::OnCommit, + base::AsWeakPtr(this))); + } - return DisableSyncResponse::kModelStillReadyToSync; + return StopSyncResponse::kModelStillReadyToSync; } void ConsentSyncBridgeImpl::ReadAllDataAndResubmit() {
diff --git a/components/consent_auditor/consent_sync_bridge_impl.h b/components/consent_auditor/consent_sync_bridge_impl.h index b7abb9c..c77e9de 100644 --- a/components/consent_auditor/consent_sync_bridge_impl.h +++ b/components/consent_auditor/consent_sync_bridge_impl.h
@@ -43,7 +43,7 @@ void GetAllDataForDebugging(DataCallback callback) override; std::string GetClientTag(const EntityData& entity_data) override; std::string GetStorageKey(const EntityData& entity_data) override; - DisableSyncResponse ApplyDisableSyncChanges( + StopSyncResponse ApplyStopSyncChanges( std::unique_ptr<MetadataChangeList> delete_metadata_change_list) override; // ConsentSyncBridge implementation.
diff --git a/components/consent_auditor/consent_sync_bridge_impl_unittest.cc b/components/consent_auditor/consent_sync_bridge_impl_unittest.cc index 0b96e3e..757b706 100644 --- a/components/consent_auditor/consent_sync_bridge_impl_unittest.cc +++ b/components/consent_auditor/consent_sync_bridge_impl_unittest.cc
@@ -185,8 +185,8 @@ ASSERT_THAT(GetAllData(), SizeIs(1)); EXPECT_THAT( - bridge()->ApplyDisableSyncChanges(WriteBatch::CreateMetadataChangeList()), - Eq(ModelTypeSyncBridge::DisableSyncResponse::kModelStillReadyToSync)); + bridge()->ApplyStopSyncChanges(WriteBatch::CreateMetadataChangeList()), + Eq(ModelTypeSyncBridge::StopSyncResponse::kModelStillReadyToSync)); // The bridge may asynchronously query the store to choose what to delete. base::RunLoop().RunUntilIdle(); @@ -315,8 +315,8 @@ // User disables sync, hovewer, the consent hasn't been submitted yet. It is // preserved to be submitted when sync is re-enabled. EXPECT_THAT( - bridge()->ApplyDisableSyncChanges(WriteBatch::CreateMetadataChangeList()), - Eq(ModelTypeSyncBridge::DisableSyncResponse::kModelStillReadyToSync)); + bridge()->ApplyStopSyncChanges(WriteBatch::CreateMetadataChangeList()), + Eq(ModelTypeSyncBridge::StopSyncResponse::kModelStillReadyToSync)); // The bridge may asynchronously query the store to choose what to delete. base::RunLoop().RunUntilIdle(); @@ -465,8 +465,8 @@ ASSERT_THAT(GetAllData(), SizeIs(1)); EXPECT_THAT( - bridge()->ApplyDisableSyncChanges(WriteBatch::CreateMetadataChangeList()), - Eq(ModelTypeSyncBridge::DisableSyncResponse::kModelStillReadyToSync)); + bridge()->ApplyStopSyncChanges(WriteBatch::CreateMetadataChangeList()), + Eq(ModelTypeSyncBridge::StopSyncResponse::kModelStillReadyToSync)); // The bridge may asynchronously query the store to choose what to delete. base::RunLoop().RunUntilIdle(); @@ -484,8 +484,8 @@ base::RunLoop().RunUntilIdle(); EXPECT_THAT( - bridge()->ApplyDisableSyncChanges(WriteBatch::CreateMetadataChangeList()), - Eq(ModelTypeSyncBridge::DisableSyncResponse::kModelStillReadyToSync)); + bridge()->ApplyStopSyncChanges(WriteBatch::CreateMetadataChangeList()), + Eq(ModelTypeSyncBridge::StopSyncResponse::kModelStillReadyToSync)); base::RunLoop().RunUntilIdle(); // The previous user signs in again and enables sync.
diff --git a/components/exo/pointer.cc b/components/exo/pointer.cc index 6257a956..9484e59d 100644 --- a/components/exo/pointer.cc +++ b/components/exo/pointer.cc
@@ -9,6 +9,7 @@ #include "ash/public/cpp/shell_window_ids.h" #include "components/exo/pointer_delegate.h" #include "components/exo/pointer_gesture_pinch_delegate.h" +#include "components/exo/shell_surface_base.h" #include "components/exo/surface.h" #include "components/exo/wm_helper.h" #include "components/viz/common/frame_sinks/copy_output_request.h" @@ -44,13 +45,8 @@ const double kLocatedEventEpsilonSquared = 1.0 / (2000.0 * 2000.0); -// Synthesized events typically lack floating point precision so to avoid -// generating mouse event jitter we consider the location of these events -// to be the same as |location| if floored values match. -bool SameLocation(const ui::LocatedEvent* event, const gfx::PointF& location) { - if (event->flags() & ui::EF_IS_SYNTHESIZED) - return event->location() == gfx::ToFlooredPoint(location); - +bool SameLocation(const gfx::PointF& location_in_target, + const gfx::PointF& location) { // In general, it is good practice to compare floats using an epsilon. // In particular, the mouse location_f() could differ between the // MOUSE_PRESSED and MOUSE_RELEASED events. At MOUSE_RELEASED, it will have a @@ -58,7 +54,7 @@ // calculate it passing through all the hierarchy of windows, and that could // generate rounding error. std::numeric_limits<float>::epsilon() is not big // enough to catch this rounding error. - gfx::Vector2dF offset = event->location_f() - location; + gfx::Vector2dF offset = location_in_target - location; return offset.LengthSquared() < (2 * kLocatedEventEpsilonSquared); } @@ -203,10 +199,16 @@ void Pointer::OnMouseEvent(ui::MouseEvent* event) { Surface* target = GetEffectiveTargetForEvent(event); + gfx::PointF location_in_target = event->location_f(); + if (target) { + aura::Window::ConvertPointToTarget( + static_cast<aura::Window*>(event->target()), target->window(), + &location_in_target); + } // Update focus if target is different than the current pointer focus. if (target != focus_surface_) - SetFocus(target, event->location_f(), event->button_flags()); + SetFocus(target, location_in_target, event->button_flags()); if (!focus_surface_) return; @@ -218,8 +220,15 @@ // here as mouse movement can generate both "moved" and "entered" events // but OnPointerMotion should only be called if location changed since // OnPointerEnter was called. - if (!SameLocation(event, location_)) { - location_ = event->location_f(); + // For synthesized events, they typically lack floating point precision + // so to avoid generating mouse event jitter we consider the location of + // these events to be the same as |location| if floored values match. + bool same_location = !event->IsSynthesized() + ? SameLocation(location_in_target, location_) + : gfx::ToFlooredPoint(location_in_target) == + gfx::ToFlooredPoint(location_); + if (!same_location) { + location_ = location_in_target; delegate_->OnPointerMotion(event->time_stamp(), location_); delegate_->OnPointerFrame(); } @@ -360,9 +369,9 @@ //////////////////////////////////////////////////////////////////////////////// // Pointer, private: -Surface* Pointer::GetEffectiveTargetForEvent(ui::Event* event) const { - Surface* target = - Surface::AsSurface(static_cast<aura::Window*>(event->target())); +Surface* Pointer::GetEffectiveTargetForEvent(ui::LocatedEvent* event) const { + Surface* target = ShellSurfaceBase::GetTargetSurfaceForLocatedEvent(event); + if (!target) return nullptr;
diff --git a/components/exo/pointer.h b/components/exo/pointer.h index a5dd5c8..ee8dfc1 100644 --- a/components/exo/pointer.h +++ b/components/exo/pointer.h
@@ -27,7 +27,7 @@ } namespace ui { -class Event; +class LocatedEvent; class MouseEvent; } @@ -84,7 +84,7 @@ private: // Returns the effective target for |event|. - Surface* GetEffectiveTargetForEvent(ui::Event* event) const; + Surface* GetEffectiveTargetForEvent(ui::LocatedEvent* event) const; // Change pointer focus to |surface|. void SetFocus(Surface* surface,
diff --git a/components/exo/shell_surface.cc b/components/exo/shell_surface.cc index 960ba6b9..86fea8d 100644 --- a/components/exo/shell_surface.cc +++ b/components/exo/shell_surface.cc
@@ -140,6 +140,17 @@ widget_->SetFullscreen(fullscreen); } +void ShellSurface::SetPopup() { + DCHECK(!widget_); + is_popup_ = true; +} + +void ShellSurface::Grab() { + DCHECK(is_popup_); + DCHECK(!widget_); + has_grab_ = true; +} + void ShellSurface::Resize(int component) { TRACE_EVENT1("exo", "ShellSurface::Resize", "component", component);
diff --git a/components/exo/shell_surface.h b/components/exo/shell_surface.h index 10e7538..e99b17a 100644 --- a/components/exo/shell_surface.h +++ b/components/exo/shell_surface.h
@@ -43,6 +43,12 @@ // Set fullscreen state for shell surface. void SetFullscreen(bool fullscreen); + // Make the shell surface popup type. + void SetPopup(); + + // Set event grab on the surface. + void Grab(); + // Start an interactive resize of surface. |component| is one of the windows // HT constants (see ui/base/hit_test.h) and describes in what direction the // surface should be resized.
diff --git a/components/exo/shell_surface_base.cc b/components/exo/shell_surface_base.cc index 13ed57fb..a5ffebf 100644 --- a/components/exo/shell_surface_base.cc +++ b/components/exo/shell_surface_base.cc
@@ -45,6 +45,7 @@ #include "ui/gfx/geometry/vector2d_conversions.h" #include "ui/gfx/path.h" #include "ui/views/widget/widget.h" +#include "ui/wm/core/capture_controller.h" #include "ui/wm/core/coordinate_conversion.h" #include "ui/wm/core/shadow_controller.h" #include "ui/wm/core/shadow_types.h" @@ -236,7 +237,10 @@ if (!surface) return false; - int component = widget_->non_client_view()->NonClientHitTest(local_point); + int component = + widget_->non_client_view() + ? widget_->non_client_view()->NonClientHitTest(local_point) + : HTNOWHERE; if (component != HTNOWHERE && component != HTCLIENT && component != HTBORDER) { return true; @@ -412,6 +416,8 @@ parent_->RemoveObserver(this); if (root_surface()) root_surface()->RemoveSurfaceObserver(this); + if (has_grab_) + wm::CaptureController::Get()->RemoveObserver(this); } void ShellSurfaceBase::AcknowledgeConfigure(uint32_t serial) { @@ -650,6 +656,41 @@ return window->GetProperty(kMainSurfaceKey); } +// static +Surface* ShellSurfaceBase::GetTargetSurfaceForLocatedEvent( + ui::LocatedEvent* event) { + aura::Window* window = wm::CaptureController::Get()->GetCaptureWindow(); + gfx::PointF location_in_target = event->location_f(); + + if (!window) + return Surface::AsSurface(static_cast<aura::Window*>(event->target())); + + Surface* main_surface = ShellSurfaceBase::GetMainSurface(window); + // Skip if the event is captured by non exo windwows. + if (!main_surface) + return nullptr; + + while (true) { + aura::Window* focused = window->GetEventHandlerForPoint( + gfx::ToFlooredPoint(location_in_target)); + + if (focused) { + aura::Window::ConvertPointToTarget(window, focused, &location_in_target); + return Surface::AsSurface(focused); + } + + aura::Window* parent_window = wm::GetTransientParent(window); + + if (!parent_window) { + location_in_target = event->location_f(); + return main_surface; + } + aura::Window::ConvertPointToTarget(window, parent_window, + &location_in_target); + window = parent_window; + } +} + std::unique_ptr<base::trace_event::TracedValue> ShellSurfaceBase::AsTracedValue() const { std::unique_ptr<base::trace_event::TracedValue> value( @@ -746,6 +787,9 @@ DCHECK(!widget_->IsVisible()); pending_show_widget_ = false; widget_->Show(); + if (has_grab_) + StartCapture(); + if (container_ == ash::kShellWindowId_SystemModalContainer) UpdateSystemModal(); } @@ -970,6 +1014,29 @@ mask->transform(matrix); } +void ShellSurfaceBase::OnCaptureChanged(aura::Window* lost_capture, + aura::Window* gained_capture) { + if (lost_capture == widget_->GetNativeWindow() && is_popup_) { + wm::CaptureController::Get()->RemoveObserver(this); + if (gained_capture && + lost_capture == wm::GetTransientParent(gained_capture)) { + // Don't close if the capture has been transferred to the child popup. + return; + } + aura::Window* parent = wm::GetTransientParent(lost_capture); + if (parent) { + // The capture needs to be transferred to the parent if it had grab. + views::Widget* parent_widget = + views::Widget::GetWidgetForNativeWindow(parent); + ShellSurfaceBase* parent_shell_surface = static_cast<ShellSurfaceBase*>( + parent_widget->widget_delegate()->GetContentsView()); + if (parent_shell_surface->has_grab_) + parent_shell_surface->StartCapture(); + } + widget_->Close(); + } +} + //////////////////////////////////////////////////////////////////////////////// // views::Views overrides: @@ -1178,7 +1245,8 @@ DCHECK(!widget_); views::Widget::InitParams params; - params.type = views::Widget::InitParams::TYPE_WINDOW; + params.type = is_popup_ ? views::Widget::InitParams::TYPE_POPUP + : views::Widget::InitParams::TYPE_WINDOW; params.ownership = views::Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET; params.delegate = this; params.shadow_type = views::Widget::InitParams::SHADOW_TYPE_NONE; @@ -1268,9 +1336,8 @@ uint32_t serial = 0; if (!configure_callback_.is_null()) { if (widget_) { - const views::NonClientView* non_client_view = widget_->non_client_view(); serial = configure_callback_.Run( - non_client_view->frame_view()->GetBoundsForClientView().size(), + GetClientViewBounds().size(), ash::wm::GetWindowState(widget_->GetNativeWindow())->GetStateType(), IsResizing(), widget_->IsActive(), origin_offset); } else { @@ -1349,10 +1416,7 @@ } void ShellSurfaceBase::UpdateSurfaceBounds() { - gfx::Point origin = widget_->non_client_view() - ->frame_view() - ->GetBoundsForClientView() - .origin(); + gfx::Point origin = GetClientViewBounds().origin(); origin += GetSurfaceOrigin().OffsetFromOrigin(); origin -= ToFlooredVector2d(ScaleVector2d( @@ -1413,6 +1477,14 @@ return location; } +gfx::Rect ShellSurfaceBase::GetClientViewBounds() const { + return widget_->non_client_view() + ? widget_->non_client_view() + ->frame_view() + ->GetBoundsForClientView() + : gfx::Rect(widget_->GetWindowBoundsInScreen().size()); +} + gfx::Rect ShellSurfaceBase::GetShadowBounds() const { return shadow_bounds_->IsEmpty() ? gfx::Rect(widget_->GetNativeWindow()->bounds().size()) @@ -1551,8 +1623,11 @@ gfx::Rect ShellSurfaceBase::GetWidgetBounds() const { gfx::Rect visible_bounds = GetVisibleBounds(); gfx::Rect new_widget_bounds = - widget_->non_client_view()->GetWindowBoundsForClientBounds( - visible_bounds); + widget_->non_client_view() + ? widget_->non_client_view()->GetWindowBoundsForClientBounds( + visible_bounds) + : visible_bounds; + if (movement_disabled_) { new_widget_bounds.set_origin(origin_); } else if (resize_component_ == HTCAPTION) { @@ -1574,8 +1649,8 @@ DCHECK(!movement_disabled_ || resize_component_ == HTCAPTION); gfx::Rect visible_bounds = GetVisibleBounds(); - gfx::Rect client_bounds = - widget_->non_client_view()->frame_view()->GetBoundsForClientView(); + gfx::Rect client_bounds = GetClientViewBounds(); + switch (resize_component_) { case HTCAPTION: return gfx::Point() + origin_offset_ - visible_bounds.OffsetFromOrigin(); @@ -1619,4 +1694,11 @@ widget_->OnSizeConstraintsChanged(); } +void ShellSurfaceBase::StartCapture() { + widget_->set_auto_release_capture(false); + wm::CaptureController::Get()->AddObserver(this); + // Just capture on the window. + widget_->SetCapture(nullptr /* view */); +} + } // namespace exo
diff --git a/components/exo/shell_surface_base.h b/components/exo/shell_surface_base.h index c10988b..71609d80 100644 --- a/components/exo/shell_surface_base.h +++ b/components/exo/shell_surface_base.h
@@ -17,6 +17,7 @@ #include "base/strings/string16.h" #include "components/exo/surface_observer.h" #include "components/exo/surface_tree_host.h" +#include "ui/aura/client/capture_client_observer.h" #include "ui/aura/window_observer.h" #include "ui/base/hit_test.h" #include "ui/compositor/compositor_lock.h" @@ -53,6 +54,7 @@ class ShellSurfaceBase : public SurfaceTreeHost, public SurfaceObserver, public aura::WindowObserver, + public aura::client::CaptureClientObserver, public views::WidgetDelegate, public views::View, public wm::ActivationChangeObserver { @@ -166,6 +168,12 @@ // |window| must not be nullptr. static Surface* GetMainSurface(const aura::Window* window); + // Returns the target surface for the located event |event|. If an + // event handling is grabbed by an window, it'll first examine that + // window, then traverse to its transeitn parent if the parent also + // requested grab. + static Surface* GetTargetSurfaceForLocatedEvent(ui::LocatedEvent* event); + // Returns a trace value representing the state of the surface. std::unique_ptr<base::trace_event::TracedValue> AsTracedValue() const; @@ -181,6 +189,10 @@ // Overridden from SurfaceObserver: void OnSurfaceDestroying(Surface* surface) override; + // Overridden from CaptureClientObserver: + void OnCaptureChanged(aura::Window* lost_capture, + aura::Window* gained_capture) override; + // Overridden from views::WidgetDelegate: bool CanResize() const override; bool CanMaximize() const override; @@ -278,6 +290,9 @@ // In the coordinate system of the parent root window. gfx::Point GetMouseLocation() const; + // Returns the bounds of the client area.nnn + gfx::Rect GetClientViewBounds() const; + // In the local coordinate system of the window. virtual gfx::Rect GetShadowBounds() const; @@ -289,6 +304,9 @@ // Set the parent window of this surface. void SetParentWindow(aura::Window* parent); + // Start the event capture on this surface. + void StartCapture(); + const gfx::Rect& geometry() const { return geometry_; } views::Widget* widget_ = nullptr; @@ -316,6 +334,8 @@ // complete. https://crbug.com/801666. bool client_controlled_move_resize_ = true; SurfaceFrameType frame_type_ = SurfaceFrameType::NONE; + bool is_popup_ = false; + bool has_grab_ = false; bool frame_enabled() const { return frame_type_ != SurfaceFrameType::NONE &&
diff --git a/components/exo/shell_surface_unittest.cc b/components/exo/shell_surface_unittest.cc index 79cb6cbe..a262414 100644 --- a/components/exo/shell_surface_unittest.cc +++ b/components/exo/shell_surface_unittest.cc
@@ -33,7 +33,10 @@ #include "ui/display/display.h" #include "ui/display/manager/display_manager.h" #include "ui/display/screen.h" +#include "ui/events/base_event_utils.h" +#include "ui/events/event.h" #include "ui/views/widget/widget.h" +#include "ui/wm/core/capture_controller.h" #include "ui/wm/core/window_util.h" namespace exo { @@ -57,6 +60,18 @@ return serial; } +std::unique_ptr<ShellSurface> CreatePopupShellSurface( + Surface* popup_surface, + ShellSurface* parent, + const gfx::Point& origin) { + auto popup_shell_surface = std::make_unique<ShellSurface>(popup_surface); + popup_shell_surface->DisableMovement(); + popup_shell_surface->SetPopup(); + popup_shell_surface->SetParent(parent); + popup_shell_surface->SetOrigin(origin); + return popup_shell_surface; +} + TEST_F(ShellSurfaceTest, AcknowledgeConfigure) { gfx::Size buffer_size(32, 32); std::unique_ptr<Buffer> buffer( @@ -583,5 +598,86 @@ shell_surface->GetWidget()->GetWindowBoundsInScreen().width()); } +TEST_F(ShellSurfaceTest, Popup) { + gfx::Size buffer_size(256, 256); + std::unique_ptr<Buffer> buffer( + new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); + std::unique_ptr<Surface> surface(new Surface); + std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get())); + + surface->Attach(buffer.get()); + surface->Commit(); + shell_surface->GetWidget()->SetBounds(gfx::Rect(0, 0, 256, 256)); + + std::unique_ptr<Buffer> popup_buffer( + new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); + std::unique_ptr<Surface> popup_surface(new Surface); + popup_surface->Attach(popup_buffer.get()); + std::unique_ptr<ShellSurface> popup_shell_surface(CreatePopupShellSurface( + popup_surface.get(), shell_surface.get(), gfx::Point(50, 50))); + popup_shell_surface->Grab(); + popup_surface->Commit(); + ASSERT_EQ(gfx::Rect(50, 50, 256, 256), + popup_shell_surface->GetWidget()->GetWindowBoundsInScreen()); + + // Verify that created shell surface is popup and has capture. + EXPECT_EQ(aura::client::WINDOW_TYPE_POPUP, + popup_shell_surface->GetWidget()->GetNativeWindow()->type()); + EXPECT_EQ(wm::CaptureController::Get()->GetCaptureWindow(), + popup_shell_surface->GetWidget()->GetNativeWindow()); + + // ShellSurface can capture the event even after it is craeted. + std::unique_ptr<Buffer> sub_popup_buffer( + new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); + std::unique_ptr<Surface> sub_popup_surface(new Surface); + sub_popup_surface->Attach(popup_buffer.get()); + std::unique_ptr<ShellSurface> sub_popup_shell_surface(CreatePopupShellSurface( + sub_popup_surface.get(), popup_shell_surface.get(), gfx::Point(100, 50))); + sub_popup_shell_surface->Grab(); + sub_popup_surface->Commit(); + ASSERT_EQ(gfx::Rect(100, 50, 256, 256), + sub_popup_shell_surface->GetWidget()->GetWindowBoundsInScreen()); + + // The capture should be on sub_popup_shell_surface. + EXPECT_EQ(wm::CaptureController::Get()->GetCaptureWindow(), + sub_popup_shell_surface->GetWidget()->GetNativeWindow()); + EXPECT_EQ(aura::client::WINDOW_TYPE_POPUP, + sub_popup_shell_surface->GetWidget()->GetNativeWindow()->type()); + + { + // Mouse is on the top most popup. + ui::MouseEvent event(ui::ET_MOUSE_MOVED, gfx::Point(0, 0), + gfx::Point(100, 50), ui::EventTimeForNow(), 0, 0); + EXPECT_EQ(sub_popup_surface.get(), + ShellSurfaceBase::GetTargetSurfaceForLocatedEvent(&event)); + } + { + // Move the mouse to the parent popup. + ui::MouseEvent event(ui::ET_MOUSE_MOVED, gfx::Point(-25, 0), + gfx::Point(75, 50), ui::EventTimeForNow(), 0, 0); + EXPECT_EQ(popup_surface.get(), + ShellSurfaceBase::GetTargetSurfaceForLocatedEvent(&event)); + } + { + // Move the mouse to the main window. + ui::MouseEvent event(ui::ET_MOUSE_MOVED, gfx::Point(-25, -25), + gfx::Point(75, 25), ui::EventTimeForNow(), 0, 0); + EXPECT_EQ(surface.get(), + ShellSurfaceBase::GetTargetSurfaceForLocatedEvent(&event)); + } + + // Removing top most popup moves the grab to parent popup. + sub_popup_shell_surface.reset(); + EXPECT_EQ(wm::CaptureController::Get()->GetCaptureWindow(), + popup_shell_surface->GetWidget()->GetNativeWindow()); + { + // Targetting should still work. + ui::MouseEvent event(ui::ET_MOUSE_MOVED, gfx::Point(0, 0), + gfx::Point(50, 50), ui::EventTimeForNow(), 0, 0); + EXPECT_EQ(popup_surface.get(), + ShellSurfaceBase::GetTargetSurfaceForLocatedEvent(&event)); + } +} + } // namespace } // namespace exo
diff --git a/components/exo/touch.cc b/components/exo/touch.cc index 2ebdbb59..0f73590 100644 --- a/components/exo/touch.cc +++ b/components/exo/touch.cc
@@ -4,12 +4,15 @@ #include "components/exo/touch.h" +#include "components/exo/shell_surface_base.h" #include "components/exo/surface.h" #include "components/exo/touch_delegate.h" #include "components/exo/touch_stylus_delegate.h" #include "components/exo/wm_helper.h" #include "ui/aura/window.h" #include "ui/events/event.h" +#include "ui/wm/core/capture_controller.h" +#include "ui/wm/core/window_util.h" namespace exo { namespace { @@ -190,9 +193,9 @@ //////////////////////////////////////////////////////////////////////////////// // Touch, private: -Surface* Touch::GetEffectiveTargetForEvent(ui::Event* event) const { - Surface* target = - Surface::AsSurface(static_cast<aura::Window*>(event->target())); +Surface* Touch::GetEffectiveTargetForEvent(ui::LocatedEvent* event) const { + Surface* target = ShellSurfaceBase::GetTargetSurfaceForLocatedEvent(event); + if (!target) return nullptr;
diff --git a/components/exo/touch.h b/components/exo/touch.h index 88d1048..bfe7878 100644 --- a/components/exo/touch.h +++ b/components/exo/touch.h
@@ -13,6 +13,7 @@ #include "ui/gfx/geometry/point_f.h" namespace ui { +class LocatedEvent; class TouchEvent; } @@ -41,7 +42,7 @@ private: // Returns the effective target for |event|. - Surface* GetEffectiveTargetForEvent(ui::Event* event) const; + Surface* GetEffectiveTargetForEvent(ui::LocatedEvent* event) const; // The delegate instance that all events are dispatched to. TouchDelegate* const delegate_;
diff --git a/components/exo/wayland/server.cc b/components/exo/wayland/server.cc index cc89928..073deda 100644 --- a/components/exo/wayland/server.cc +++ b/components/exo/wayland/server.cc
@@ -1792,18 +1792,43 @@ // Wrapper around shell surface that allows us to handle the case where the // xdg surface resource is destroyed before the popup resource. -class WaylandPopup { +class WaylandPopup : aura::WindowObserver { public: WaylandPopup(wl_resource* resource, wl_resource* surface_resource) - : resource_(resource), weak_ptr_factory_(this) { - ShellSurface* shell_surface = GetUserDataAs<ShellSurface>(surface_resource); - shell_surface->set_close_callback( + : resource_(resource), + shell_surface_(GetUserDataAs<ShellSurface>(surface_resource)), + weak_ptr_factory_(this) { + shell_surface_->host_window()->AddObserver(this); + shell_surface_->set_close_callback( base::Bind(&WaylandPopup::OnClose, weak_ptr_factory_.GetWeakPtr())); - shell_surface->set_configure_callback( + shell_surface_->set_configure_callback( base::Bind(&HandleXdgSurfaceV6ConfigureCallback, surface_resource, base::Bind(&WaylandPopup::OnConfigure, weak_ptr_factory_.GetWeakPtr()))); } + ~WaylandPopup() override { + if (shell_surface_) + shell_surface_->host_window()->RemoveObserver(this); + } + + void Grab() { + if (!shell_surface_) { + wl_resource_post_error(resource_, ZXDG_POPUP_V6_ERROR_INVALID_GRAB, + "the surface has already been destroyed"); + return; + } + if (shell_surface_->GetWidget()) { + wl_resource_post_error(resource_, ZXDG_POPUP_V6_ERROR_INVALID_GRAB, + "grab must be called before construction"); + return; + } + shell_surface_->Grab(); + } + + // Overridden from aura::WindowObserver: + void OnWindowDestroying(aura::Window* window) override { + shell_surface_ = nullptr; + } private: void OnClose() { @@ -1819,6 +1844,7 @@ } wl_resource* const resource_; + ShellSurface* shell_surface_; base::WeakPtrFactory<WaylandPopup> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(WaylandPopup); @@ -1832,7 +1858,7 @@ wl_resource* resource, wl_resource* seat, uint32_t serial) { - NOTIMPLEMENTED(); + GetUserDataAs<WaylandPopup>(resource)->Grab(); } const struct zxdg_popup_v6_interface xdg_popup_v6_implementation = { @@ -1885,6 +1911,12 @@ return; } + if (shell_surface->GetWidget()) { + wl_resource_post_error(resource, ZXDG_SURFACE_V6_ERROR_ALREADY_CONSTRUCTED, + "get_popup is called after constructed"); + return; + } + gfx::Point position = GetUserDataAs<WaylandPositioner>(positioner_resource) ->CalculatePosition(); // |position| is relative to the parent's contents view origin, and |origin| @@ -1897,6 +1929,8 @@ shell_surface->DisableMovement(); shell_surface->SetActivatable(false); shell_surface->SetCanMinimize(false); + shell_surface->SetParent(parent); + shell_surface->SetPopup(); shell_surface->SetEnabled(true); wl_resource* xdg_popup_resource =
diff --git a/components/flags_ui/resources/flags.html b/components/flags_ui/resources/flags.html index a91d6d6..6331741 100644 --- a/components/flags_ui/resources/flags.html +++ b/components/flags_ui/resources/flags.html
@@ -205,10 +205,10 @@ <div class="flex"> <if expr="not is_ios"> <button class="experiment-restart-button" type="button" tabindex="9"> -<if expr="not is_chromeos"> +<if expr="not chromeos"> Relaunch Now </if> -<if expr="is_chromeos"> +<if expr="chromeos"> Restart Now </if> </button>
diff --git a/components/infobars/core/infobar_delegate.h b/components/infobars/core/infobar_delegate.h index 7bd1083..dc9debd 100644 --- a/components/infobars/core/infobar_delegate.h +++ b/components/infobars/core/infobar_delegate.h
@@ -152,6 +152,7 @@ PAGE_LOAD_CAPPING_INFOBAR_DELEGATE = 81, DOWNLOAD_PROGRESS_INFOBAR_ANDROID = 82, AR_CORE_UPGRADE_ANDROID = 83, + BLOATED_RENDERER_INFOBAR_DELEGATE = 84, }; // Describes navigation events, used to decide whether infobars should be
diff --git a/components/password_manager/core/browser/form_parsing/BUILD.gn b/components/password_manager/core/browser/form_parsing/BUILD.gn index 910fbd1..9fdd67c2 100644 --- a/components/password_manager/core/browser/form_parsing/BUILD.gn +++ b/components/password_manager/core/browser/form_parsing/BUILD.gn
@@ -33,6 +33,7 @@ "//components/autofill/core/browser", "//components/autofill/core/browser/proto", "//components/autofill/core/common", + "//components/password_manager/core/common", ] }
diff --git a/components/password_manager/core/browser/form_parsing/form_parser.cc b/components/password_manager/core/browser/form_parsing/form_parser.cc index dfd4a06..e765dd7 100644 --- a/components/password_manager/core/browser/form_parsing/form_parser.cc +++ b/components/password_manager/core/browser/form_parsing/form_parser.cc
@@ -4,6 +4,8 @@ #include "components/password_manager/core/browser/form_parsing/form_parser.h" +#include <stdint.h> + #include <algorithm> #include <iterator> #include <set> @@ -14,6 +16,7 @@ #include "base/strings/string_split.h" #include "components/autofill/core/common/form_data.h" #include "components/autofill/core/common/password_form.h" +#include "components/password_manager/core/common/password_manager_features.h" using autofill::FieldPropertiesFlags; using autofill::FormFieldData; @@ -376,9 +379,14 @@ return focusable_username ? focusable_username : username; } +// Tries to find the username and password fields in |processed_fields| based on +// the structure (how the fields are ordered). If |mode| is SAVING, only +// consideres non-empty fields. If |username_hint| is not null, it is returned +// as the username. std::unique_ptr<ParseResult> ParseUsingBaseHeuristics( const std::vector<ProcessedField>& processed_fields, - FormParsingMode mode) { + FormParsingMode mode, + const FormFieldData* username_hint) { // What is the best interactability among passwords? Interactability password_max = Interactability::kUnlikely; for (const ProcessedField& processed_field : processed_fields) { @@ -402,6 +410,12 @@ if (result->IsEmpty()) return nullptr; + if (username_hint && + !(mode == FormParsingMode::SAVING && username_hint->value.empty())) { + result->username_field = username_hint; + return result; + } + // What is the best interactability among text fields preceding the passwords? Interactability username_max = Interactability::kUnlikely; for (auto it = processed_fields.begin(); it != first_relevant_password; @@ -504,6 +518,24 @@ return result; } +// Find the first element in |username_predictions| (i.e. the most reliable +// prediction) that occurs in |processed_fields|. +const FormFieldData* FindUsernameInPredictions( + const std::vector<uint32_t>& username_predictions, + const std::vector<ProcessedField>& processed_fields) { + for (uint32_t predicted_id : username_predictions) { + auto iter = std::find_if( + processed_fields.begin(), processed_fields.end(), + [predicted_id](const ProcessedField& processed_field) { + return processed_field.field->unique_renderer_id == predicted_id; + }); + if (iter != processed_fields.end()) { + return iter->field; + } + } + return nullptr; +} + } // namespace std::unique_ptr<PasswordForm> ParseFormData( @@ -546,9 +578,17 @@ return result; } + // Try to find the username based on the context of the fields. + const FormFieldData* username_field_by_context = nullptr; + if (base::FeatureList::IsEnabled( + password_manager::features::kHtmlBasedUsernameDetector)) { + username_field_by_context = FindUsernameInPredictions( + form_data.username_predictions, processed_fields); + } + // Try to parse with base heuristic. - auto base_heuristics_parse_result = - ParseUsingBaseHeuristics(processed_fields, mode); + auto base_heuristics_parse_result = ParseUsingBaseHeuristics( + processed_fields, mode, username_field_by_context); if (base_heuristics_parse_result) { SetFields(*base_heuristics_parse_result, result.get()); return result;
diff --git a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc index 0ae7bb1..8a21bc2 100644 --- a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc +++ b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
@@ -66,6 +66,9 @@ const char* name = kNonimportantValue; const char* form_control_type = "text"; PasswordFieldPrediction prediction = {.type = autofill::MAX_VALID_FIELD_TYPE}; + // If not -1, indicates on which rank among predicted usernames this should + // be. Unused ranks will be padded with unique IDs (not found in any fields). + int predicted_username = -1; }; // Describes a test case for the parser. @@ -81,7 +84,7 @@ // Returns numbers which are distinct from each other within the scope of one // test. uint32_t GetUniqueId() { - static uint32_t counter = 0; + static uint32_t counter = 10; return counter++; } @@ -191,6 +194,19 @@ if (field_description.prediction.type != autofill::MAX_VALID_FIELD_TYPE) { (*predictions)[unique_id] = field_description.prediction; } + if (field_description.predicted_username >= 0) { + size_t index = static_cast<size_t>(field_description.predicted_username); + if (form_data.username_predictions.size() <= index) + form_data.username_predictions.resize(index + 1); + form_data.username_predictions[index] = field.unique_renderer_id; + } + } + // Fill unused ranks in predictions with fresh IDs to check that those are + // correctly ignored. In real situation, this might correspond, e.g., to + // fields which were not fillable and hence dropped from the selection. + for (uint32_t& id : form_data.username_predictions) { + if (id == 0) + id = GetUniqueId(); } return form_data; } @@ -1117,6 +1133,71 @@ }); } +TEST(FormParserTest, UsernamePredictions) { + CheckTestData({ + { + "Username prediction overrides structure", + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .predicted_username = 0}, + {.form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + }, + }, + { + "Username prediction does not override structure if empty and mode " + "is SAVING", + { + {.role = ElementRole::USERNAME_FILLING, + .form_control_type = "text", + .predicted_username = 2, + .value = ""}, + {.role = ElementRole::USERNAME_SAVING, + .form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + }, + }, + { + "Username prediction does not override autocomplete analysis", + { + {.form_control_type = "text", .predicted_username = 0}, + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .autocomplete_attribute = "username"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .autocomplete_attribute = "current-password"}, + }, + }, + { + "Username prediction does not override server hints", + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .prediction = {.type = autofill::USERNAME_AND_EMAIL_ADDRESS}}, + {.form_control_type = "text", .predicted_username = 0}, + {.role = ElementRole::CURRENT_PASSWORD, + .prediction = {.type = autofill::PASSWORD}, + .form_control_type = "password"}, + }, + }, + { + "Username prediction order matters", + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .predicted_username = 1}, + {.form_control_type = "text", .predicted_username = 4}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + }, + }, + }); +} + } // namespace } // namespace password_manager
diff --git a/components/policy/tools/template_writers/writers/reg_writer.py b/components/policy/tools/template_writers/writers/reg_writer.py index 218cd69..aeea2f0 100755 --- a/components/policy/tools/template_writers/writers/reg_writer.py +++ b/components/policy/tools/template_writers/writers/reg_writer.py
@@ -26,8 +26,9 @@ NEWLINE = '\r\n' - def _EscapeRegString(self, string): - return string.replace('\\', '\\\\').replace('\"', '\\\"') + def _QuoteAndEscapeString(self, string): + assert isinstance(string, str) + return json.dumps(string) def _StartBlock(self, key, suffix, list): key = 'HKEY_LOCAL_MACHINE\\' + key @@ -58,22 +59,17 @@ self._StartBlock(key, policy['name'], list) i = 1 for item in example_value: - escaped_str = self._EscapeRegString(item) - list.append('"%d"="%s"' % (i, escaped_str)) + list.append('"%d"=%s' % (i, self._QuoteAndEscapeString(item))) i = i + 1 else: self._StartBlock(key, None, list) - if policy['type'] in ('string', 'string-enum', 'dict', 'external'): - example_value_str = json.dumps(example_value, sort_keys=True) - if policy['type'] in ('dict', 'external'): - example_value_str = '"%s"' % example_value_str - elif policy['type'] == 'main': - if example_value == True: - example_value_str = 'dword:00000001' - else: - example_value_str = 'dword:00000000' - elif policy['type'] in ('int', 'int-enum'): - example_value_str = 'dword:%08x' % example_value + if policy['type'] in ('string', 'string-enum'): + example_value_str = self._QuoteAndEscapeString(example_value) + elif policy['type'] in ('dict', 'external'): + example_value_str = self._QuoteAndEscapeString( + json.dumps(example_value, sort_keys=True)) + elif policy['type'] in ('main', 'int', 'int-enum'): + example_value_str = 'dword:%08x' % int(example_value) else: raise Exception('unknown policy type %s:' % policy['type'])
diff --git a/components/policy/tools/template_writers/writers/reg_writer_unittest.py b/components/policy/tools/template_writers/writers/reg_writer_unittest.py index d2b548f..449e154 100755 --- a/components/policy/tools/template_writers/writers/reg_writer_unittest.py +++ b/components/policy/tools/template_writers/writers/reg_writer_unittest.py
@@ -314,8 +314,9 @@ 'Windows Registry Editor Version 5.00', '', '[HKEY_LOCAL_MACHINE\\Software\\Policies\\Chromium]', - '"DictionaryPolicy"="{"bool": true, "dict": {"a": 1, ' - '"b": 2}, "int": 10, "list": [1, 2, 3], "string": "abc"}"']) + '"DictionaryPolicy"="{\\"bool\\": true, ' + '\\"dict\\": {\\"a\\": 1, \\"b\\": 2}, \\"int\\": 10, ' + '\\"list\\": [1, 2, 3], \\"string\\": \\"abc\\"}"']) self.CompareOutputs(output, expected_output) def testExternalPolicy(self): @@ -344,7 +345,8 @@ 'Windows Registry Editor Version 5.00', '', '[HKEY_LOCAL_MACHINE\\Software\\Policies\\Chromium]', - '"ExternalPolicy"="{"hash": "deadbeef", "url": "https://example.com/avatar.jpg"}"']) + '"ExternalPolicy"="{\\"hash\\": \\"deadbeef\\", ' + '\\"url\\": \\"https://example.com/avatar.jpg\\"}"']) self.CompareOutputs(output, expected_output) def testNonSupportedPolicy(self):
diff --git a/components/sync/BUILD.gn b/components/sync/BUILD.gn index e63df99..632ad1c 100644 --- a/components/sync/BUILD.gn +++ b/components/sync/BUILD.gn
@@ -63,6 +63,7 @@ "base/stop_source.h", "base/sync_prefs.cc", "base/sync_prefs.h", + "base/sync_stop_metadata_fate.h", "base/syncer_error.cc", "base/syncer_error.h", "base/system_encryptor.cc",
diff --git a/components/sync/device_info/device_info_sync_bridge.cc b/components/sync/device_info/device_info_sync_bridge.cc index 6a6579a1..93958cf 100644 --- a/components/sync/device_info/device_info_sync_bridge.cc +++ b/components/sync/device_info/device_info_sync_bridge.cc
@@ -236,20 +236,22 @@ return entity_data.specifics.device_info().cache_guid(); } -ModelTypeSyncBridge::DisableSyncResponse -DeviceInfoSyncBridge::ApplyDisableSyncChanges( +ModelTypeSyncBridge::StopSyncResponse +DeviceInfoSyncBridge::ApplyStopSyncChanges( std::unique_ptr<MetadataChangeList> delete_metadata_change_list) { // TODO(skym, crbug.com/659263): Would it be reasonable to pulse_timer_.Stop() // or subscription_.reset() here? // Remove all local data, if sync is being disabled, the user has expressed // their desire to not have knowledge about other devices. - store_->DeleteAllDataAndMetadata(base::DoNothing()); - if (!all_data_.empty()) { - all_data_.clear(); - NotifyObservers(); + if (delete_metadata_change_list) { + store_->DeleteAllDataAndMetadata(base::DoNothing()); + if (!all_data_.empty()) { + all_data_.clear(); + NotifyObservers(); + } } - return DisableSyncResponse::kModelStillReadyToSync; + return StopSyncResponse::kModelStillReadyToSync; } bool DeviceInfoSyncBridge::IsSyncing() const {
diff --git a/components/sync/device_info/device_info_sync_bridge.h b/components/sync/device_info/device_info_sync_bridge.h index 6d64d83..4ac6cd4 100644 --- a/components/sync/device_info/device_info_sync_bridge.h +++ b/components/sync/device_info/device_info_sync_bridge.h
@@ -52,7 +52,7 @@ void GetAllDataForDebugging(DataCallback callback) override; std::string GetClientTag(const EntityData& entity_data) override; std::string GetStorageKey(const EntityData& entity_data) override; - DisableSyncResponse ApplyDisableSyncChanges( + StopSyncResponse ApplyStopSyncChanges( std::unique_ptr<MetadataChangeList> delete_metadata_change_list) override; // DeviceInfoTracker implementation.
diff --git a/components/sync/device_info/device_info_sync_bridge_unittest.cc b/components/sync/device_info/device_info_sync_bridge_unittest.cc index 776642cb..0d3c20f 100644 --- a/components/sync/device_info/device_info_sync_bridge_unittest.cc +++ b/components/sync/device_info/device_info_sync_bridge_unittest.cc
@@ -787,7 +787,7 @@ EXPECT_EQ(2, change_count()); } -TEST_F(DeviceInfoSyncBridgeTest, ApplyDisableSyncChanges) { +TEST_F(DeviceInfoSyncBridgeTest, ApplyStopSyncChanges) { InitializeAndPump(); EXPECT_EQ(1u, bridge()->GetAllDeviceInfo().size()); EXPECT_EQ(1, change_count()); @@ -801,7 +801,7 @@ EXPECT_EQ(2, change_count()); // Should clear out all local data and notify observers. - bridge()->ApplyDisableSyncChanges({}); + bridge()->ApplyStopSyncChanges(bridge()->CreateMetadataChangeList()); EXPECT_EQ(0u, bridge()->GetAllDeviceInfo().size()); EXPECT_EQ(3, change_count());
diff --git a/components/sync/driver/model_type_controller.cc b/components/sync/driver/model_type_controller.cc index 67c1f056..b7a0325 100644 --- a/components/sync/driver/model_type_controller.cc +++ b/components/sync/driver/model_type_controller.cc
@@ -54,9 +54,10 @@ delegate->RecordMemoryUsageHistogram(); } -void DisableSyncHelperOnModelThread( +void StopSyncHelperOnModelThread( + SyncStopMetadataFate metadata_fate, base::WeakPtr<ModelTypeControllerDelegate> delegate) { - delegate->DisableSync(); + delegate->OnSyncStopping(metadata_fate); } void ReportError(ModelType model_type, @@ -238,13 +239,21 @@ return; // Check preferences if datatype is not in preferred datatypes. Only call - // DisableSync if the delegate is ready to handle it (controller is in loaded + // StopSync() if the delegate is ready to handle it (controller is in loaded // state). ModelTypeSet preferred_types = sync_prefs_.GetPreferredDataTypes(ModelTypeSet(type())); - if ((state() == MODEL_LOADED || state() == RUNNING) && - (!sync_prefs_.IsFirstSetupComplete() || !preferred_types.Has(type()))) { - PostModelTask(FROM_HERE, base::BindOnce(&DisableSyncHelperOnModelThread)); + + if (state() == MODEL_LOADED || state() == RUNNING) { + // TODO(lixan@yandex-team.ru): Migrate away from preference-based inferring + // of |reason| and instead consume |metadata_fate|. + if (sync_prefs_.IsFirstSetupComplete() && preferred_types.Has(type())) { + PostModelTask(FROM_HERE, base::BindOnce(&StopSyncHelperOnModelThread, + KEEP_METADATA)); + } else { + PostModelTask(FROM_HERE, base::BindOnce(&StopSyncHelperOnModelThread, + CLEAR_METADATA)); + } } state_ = NOT_RUNNING;
diff --git a/components/sync/driver/model_type_controller_unittest.cc b/components/sync/driver/model_type_controller_unittest.cc index 71b68ff..236fd6b 100644 --- a/components/sync/driver/model_type_controller_unittest.cc +++ b/components/sync/driver/model_type_controller_unittest.cc
@@ -53,10 +53,10 @@ public FakeModelTypeChangeProcessor, public FakeModelTypeProcessor { public: - explicit TestModelTypeProcessor(int* disable_sync_call_count) + explicit TestModelTypeProcessor(int* cleared_metadata_count) : FakeModelTypeControllerDelegate(kTestModelType), FakeModelTypeChangeProcessor(GetWeakPtr()), - disable_sync_call_count_(disable_sync_call_count), + cleared_metadata_count_(cleared_metadata_count), weak_factory_(this) {} // ModelTypeChangeProcessor implementation. @@ -71,7 +71,11 @@ weak_factory_.GetWeakPtr(), base::ThreadTaskRunnerHandle::Get()); std::move(callback).Run(std::move(activation_response)); } - void DisableSync() override { (*disable_sync_call_count_)++; } + void OnSyncStopping(SyncStopMetadataFate metadata_fate) override { + if (metadata_fate == CLEAR_METADATA) { + (*cleared_metadata_count_)++; + } + } // ModelTypeProcessor implementation. void ConnectSync(std::unique_ptr<CommitQueue> commit_queue) override { @@ -88,7 +92,7 @@ private: bool initial_sync_done_ = false; bool is_connected_ = false; - int* disable_sync_call_count_; + int* cleared_metadata_count_; base::WeakPtrFactory<TestModelTypeProcessor> weak_factory_; DISALLOW_COPY_AND_ASSIGN(TestModelTypeProcessor); }; @@ -254,7 +258,7 @@ SyncPrefs* sync_prefs() { return sync_prefs_.get(); } DataTypeController* controller() { return controller_.get(); } int load_models_done_count() { return load_models_done_count_; } - int disable_sync_call_count() { return disable_sync_call_count_; } + int cleared_metadata_count() { return cleared_metadata_count_; } SyncError load_models_last_error() { return load_models_last_error_; } private: @@ -276,7 +280,7 @@ std::unique_ptr<ModelTypeChangeProcessor> CreateProcessor() { std::unique_ptr<TestModelTypeProcessor> processor = - std::make_unique<TestModelTypeProcessor>(&disable_sync_call_count_); + std::make_unique<TestModelTypeProcessor>(&cleared_metadata_count_); processor_ = processor.get(); return std::move(processor); } @@ -306,7 +310,7 @@ } int load_models_done_count_ = 0; - int disable_sync_call_count_ = 0; + int cleared_metadata_count_ = 0; bool association_callback_called_ = false; SyncError load_models_last_error_; @@ -396,7 +400,7 @@ RunAllTasks(); EXPECT_EQ(DataTypeController::NOT_RUNNING, controller()->state()); // Ensure that DisableSync is not called. - EXPECT_EQ(0, disable_sync_call_count()); + EXPECT_EQ(0, cleared_metadata_count()); ExpectProcessorConnected(false); } @@ -419,7 +423,7 @@ EXPECT_EQ(DataTypeController::NOT_RUNNING, controller()->state()); // Ensure that DisableSync is called. PumpModelThread(); - EXPECT_EQ(1, disable_sync_call_count()); + EXPECT_EQ(1, cleared_metadata_count()); } // Test emulates disabling sync by signing out. DisableSync should be called. @@ -437,7 +441,7 @@ EXPECT_EQ(DataTypeController::NOT_RUNNING, controller()->state()); // Ensure that DisableSync is called. PumpModelThread(); - EXPECT_EQ(1, disable_sync_call_count()); + EXPECT_EQ(1, cleared_metadata_count()); } // Test emulates disabling sync when datatype is not loaded yet. DisableSync @@ -453,7 +457,7 @@ controller()->Stop(KEEP_METADATA); EXPECT_EQ(DataTypeController::NOT_RUNNING, controller()->state()); // Ensure that DisableSync is not called. - EXPECT_EQ(0, disable_sync_call_count()); + EXPECT_EQ(0, cleared_metadata_count()); } } // namespace syncer
diff --git a/components/sync/driver/sync_service_utils.cc b/components/sync/driver/sync_service_utils.cc index dc98882..471bdff 100644 --- a/components/sync/driver/sync_service_utils.cc +++ b/components/sync/driver/sync_service_utils.cc
@@ -42,6 +42,11 @@ !sync_service->GetLastCycleSnapshot().is_initialized()) { return UploadState::INITIALIZING; } + // If configuration is done and sync is active, but the data type in question + // still isn't, then something must have gone wrong with that data type. + if (!sync_service->GetActiveDataTypes().Has(type)) { + return UploadState::NOT_ACTIVE; + } return UploadState::ACTIVE; }
diff --git a/components/sync/driver/sync_service_utils_unittest.cc b/components/sync/driver/sync_service_utils_unittest.cc index 070bfaf..76f4d874 100644 --- a/components/sync/driver/sync_service_utils_unittest.cc +++ b/components/sync/driver/sync_service_utils_unittest.cc
@@ -23,6 +23,9 @@ void SetPreferredDataTypes(const ModelTypeSet& types) { preferred_data_types_ = types; } + void SetActiveDataTypes(const ModelTypeSet& types) { + active_data_types_ = types; + } void SetConfigurationDone(bool done) { configuration_done_ = done; } void SetCustomPassphraseEnabled(bool enabled) { custom_passphrase_enabled_ = enabled; @@ -40,7 +43,7 @@ ModelTypeSet GetActiveDataTypes() const override { if (!sync_active_) return ModelTypeSet(); - return preferred_data_types_; + return active_data_types_; } ModelTypeSet GetEncryptedDataTypes() const override { if (!custom_passphrase_enabled_) { @@ -77,6 +80,7 @@ bool sync_cycle_complete_ = false; bool local_sync_enabled_ = false; ModelTypeSet preferred_data_types_; + ModelTypeSet active_data_types_; bool configuration_done_ = false; bool custom_passphrase_enabled_ = false; }; @@ -90,6 +94,7 @@ service.SetConfigurationDone(true); service.SetPreferredDataTypes(ProtocolTypes()); + service.SetActiveDataTypes(ProtocolTypes()); EXPECT_EQ(UploadState::NOT_ACTIVE, GetUploadToGoogleState(&service, syncer::BOOKMARKS)); @@ -107,6 +112,7 @@ TestSyncService service; service.SetSyncAllowed(true); service.SetPreferredDataTypes(ProtocolTypes()); + service.SetActiveDataTypes(ProtocolTypes()); // By default, if sync isn't disabled, we should be INITIALIZING. EXPECT_EQ(UploadState::INITIALIZING, @@ -136,6 +142,7 @@ // Sync is enabled only for a specific model type. service.SetPreferredDataTypes(ModelTypeSet(syncer::BOOKMARKS)); + service.SetActiveDataTypes(ModelTypeSet(syncer::BOOKMARKS)); // Sanity check: Upload is ACTIVE for this model type. ASSERT_EQ(UploadState::ACTIVE, @@ -149,10 +156,34 @@ GetUploadToGoogleState(&service, syncer::PREFERENCES)); } +TEST(SyncServiceUtilsTest, + UploadToGoogleDisabledForModelTypeThatFailedToStart) { + TestSyncService service; + service.SetSyncAllowed(true); + service.SetConfigurationDone(true); + service.SetSyncActive(true); + service.SetSyncCycleComplete(true); + + // Sync is enabled for some model types. + service.SetPreferredDataTypes( + ModelTypeSet(syncer::BOOKMARKS, syncer::PREFERENCES)); + // But one of them fails to actually start up! + service.SetActiveDataTypes(ModelTypeSet(syncer::BOOKMARKS)); + + // Sanity check: Upload is ACTIVE for the model type that did start up. + ASSERT_EQ(UploadState::ACTIVE, + GetUploadToGoogleState(&service, syncer::BOOKMARKS)); + + // ...but not for the type that failed. + EXPECT_EQ(UploadState::NOT_ACTIVE, + GetUploadToGoogleState(&service, syncer::PREFERENCES)); +} + TEST(SyncServiceUtilsTest, UploadToGoogleDisabledIfLocalSyncEnabled) { TestSyncService service; service.SetSyncAllowed(true); service.SetPreferredDataTypes(ProtocolTypes()); + service.SetActiveDataTypes(ProtocolTypes()); service.SetSyncActive(true); service.SetConfigurationDone(true); service.SetSyncCycleComplete(true); @@ -173,6 +204,7 @@ TestSyncService service; service.SetSyncAllowed(true); service.SetPreferredDataTypes(ProtocolTypes()); + service.SetActiveDataTypes(ProtocolTypes()); service.SetSyncActive(true); service.SetConfigurationDone(true); service.SetSyncCycleComplete(true); @@ -212,6 +244,7 @@ TestSyncService service; service.SetSyncAllowed(true); service.SetPreferredDataTypes(ProtocolTypes()); + service.SetActiveDataTypes(ProtocolTypes()); service.SetSyncActive(true); service.SetConfigurationDone(true); service.SetSyncCycleComplete(true);
diff --git a/components/sync/engine_impl/directory_commit_contribution_unittest.cc b/components/sync/engine_impl/directory_commit_contribution_unittest.cc index 821074c..406ee2b 100644 --- a/components/sync/engine_impl/directory_commit_contribution_unittest.cc +++ b/components/sync/engine_impl/directory_commit_contribution_unittest.cc
@@ -8,6 +8,7 @@ #include <string> #include "base/message_loop/message_loop.h" +#include "base/stl_util.h" #include "components/sync/engine_impl/cycle/directory_type_debug_info_emitter.h" #include "components/sync/syncable/entry.h" #include "components/sync/syncable/mutable_entry.h" @@ -100,10 +101,11 @@ // specified type. TEST_F(DirectoryCommitContributionTest, GatherByTypes) { int64_t pref1; + int64_t pref2; { syncable::WriteTransaction trans(FROM_HERE, syncable::UNITTEST, dir()); pref1 = CreateUnsyncedItem(&trans, PREFERENCES, "pref1"); - CreateUnsyncedItem(&trans, PREFERENCES, "pref2"); + pref2 = CreateUnsyncedItem(&trans, PREFERENCES, "pref2"); CreateUnsyncedItem(&trans, EXTENSIONS, "extension1"); } @@ -112,11 +114,8 @@ DirectoryCommitContribution::Build(dir(), PREFERENCES, 5, &emitter)); ASSERT_EQ(2U, cc->GetNumEntries()); - const std::vector<int64_t>& metahandles = cc->metahandles_; - EXPECT_TRUE(std::find(metahandles.begin(), metahandles.end(), pref1) != - metahandles.end()); - EXPECT_TRUE(std::find(metahandles.begin(), metahandles.end(), pref1) != - metahandles.end()); + EXPECT_TRUE(base::ContainsValue(cc->metahandles_, pref1)); + EXPECT_TRUE(base::ContainsValue(cc->metahandles_, pref2)); cc->CleanUp(); }
diff --git a/components/sync/engine_impl/get_commit_ids.cc b/components/sync/engine_impl/get_commit_ids.cc index f8a9557..5442929 100644 --- a/components/sync/engine_impl/get_commit_ids.cc +++ b/components/sync/engine_impl/get_commit_ids.cc
@@ -7,6 +7,7 @@ #include <set> #include "base/macros.h" +#include "base/stl_util.h" #include "components/sync/base/cryptographer.h" #include "components/sync/engine_impl/syncer_util.h" #include "components/sync/syncable/entry.h" @@ -276,8 +277,7 @@ // We're not interested in non-deleted parents. break; } - if (std::find(traversed.begin(), traversed.end(), handle) != - traversed.end()) { + if (base::ContainsValue(traversed, handle)) { // We've already added this parent (and therefore all of its parents). // We can return early. break; @@ -365,8 +365,7 @@ if (HaveItem(handle)) continue; - if (std::find(deletion_list.begin(), deletion_list.end(), handle) != - deletion_list.end()) { + if (base::ContainsValue(deletion_list, handle)) { continue; }
diff --git a/components/sync/model/fake_model_type_controller_delegate.cc b/components/sync/model/fake_model_type_controller_delegate.cc index 6102d528b..57eeb29d 100644 --- a/components/sync/model/fake_model_type_controller_delegate.cc +++ b/components/sync/model/fake_model_type_controller_delegate.cc
@@ -24,7 +24,8 @@ } } -void FakeModelTypeControllerDelegate::DisableSync() {} +void FakeModelTypeControllerDelegate::OnSyncStopping( + SyncStopMetadataFate metadata_fate) {} void FakeModelTypeControllerDelegate::GetAllNodesForDebugging( ModelTypeControllerDelegate::AllNodesCallback callback) {
diff --git a/components/sync/model/fake_model_type_controller_delegate.h b/components/sync/model/fake_model_type_controller_delegate.h index 8a83db6..c4589cf 100644 --- a/components/sync/model/fake_model_type_controller_delegate.h +++ b/components/sync/model/fake_model_type_controller_delegate.h
@@ -24,7 +24,7 @@ // ModelTypeControllerDelegate overrides void OnSyncStarting(const DataTypeActivationRequest& request, StartCallback callback) override; - void DisableSync() override; + void OnSyncStopping(SyncStopMetadataFate metadata_fate) override; void GetAllNodesForDebugging(AllNodesCallback callback) override; void GetStatusCountersForDebugging(StatusCountersCallback callback) override; void RecordMemoryUsageHistogram() override;
diff --git a/components/sync/model/model_type_controller_delegate.h b/components/sync/model/model_type_controller_delegate.h index 08f1d60d..bd4799d 100644 --- a/components/sync/model/model_type_controller_delegate.h +++ b/components/sync/model/model_type_controller_delegate.h
@@ -11,6 +11,7 @@ #include "base/memory/weak_ptr.h" #include "base/values.h" #include "components/sync/base/model_type.h" +#include "components/sync/base/sync_stop_metadata_fate.h" #include "components/sync/engine/cycle/status_counters.h" #include "components/sync/engine/data_type_activation_response.h" #include "components/sync/model/model_error.h" @@ -40,9 +41,9 @@ StartCallback callback) = 0; // Indicates that we no longer want to do any sync-related things for this - // data type. Severs all ties to the sync thread, deletes all local sync - // metadata, and then destroys the change processor. - virtual void DisableSync() = 0; + // data type. Severs all ties to the sync thread, and depending on + // |metadata_fate|, might delete all local sync metadata. + virtual void OnSyncStopping(SyncStopMetadataFate metadata_fate) = 0; // Returns a ListValue representing all nodes for the type to |callback|. // Used for populating nodes in Sync Node Browser of chrome://sync-internals.
diff --git a/components/sync/model/model_type_sync_bridge.cc b/components/sync/model/model_type_sync_bridge.cc index ea6bf689..8e3b425 100644 --- a/components/sync/model/model_type_sync_bridge.cc +++ b/components/sync/model/model_type_sync_bridge.cc
@@ -37,12 +37,14 @@ return ConflictResolution::UseRemote(); } -ModelTypeSyncBridge::DisableSyncResponse -ModelTypeSyncBridge::ApplyDisableSyncChanges( +ModelTypeSyncBridge::StopSyncResponse ModelTypeSyncBridge::ApplyStopSyncChanges( std::unique_ptr<MetadataChangeList> delete_metadata_change_list) { - // Nothing to do if this fails, so just ignore the error it might return. - ApplySyncChanges(std::move(delete_metadata_change_list), EntityChangeList()); - return DisableSyncResponse::kModelStillReadyToSync; + if (delete_metadata_change_list) { + // Nothing to do if this fails, so just ignore the error it might return. + ApplySyncChanges(std::move(delete_metadata_change_list), + EntityChangeList()); + } + return StopSyncResponse::kModelStillReadyToSync; } ModelTypeChangeProcessor* ModelTypeSyncBridge::change_processor() {
diff --git a/components/sync/model/model_type_sync_bridge.h b/components/sync/model/model_type_sync_bridge.h index 3576f74..a3b87c7 100644 --- a/components/sync/model/model_type_sync_bridge.h +++ b/components/sync/model/model_type_sync_bridge.h
@@ -37,7 +37,7 @@ using DataCallback = base::OnceCallback<void(std::unique_ptr<DataBatch>)>; using StorageKeyList = std::vector<std::string>; - enum class DisableSyncResponse { + enum class StopSyncResponse { kModelStillReadyToSync, kModelNoLongerReadyToSync }; @@ -135,10 +135,12 @@ const EntityData& remote_data) const; // Similar to ApplySyncChanges() but called by the processor when sync - // is in the process of being disabled. |delete_metadata_change_list| contains - // a change list to remove all metadata that the processor knows about, but - // the bridge may decide to implement deletion by other means. - virtual DisableSyncResponse ApplyDisableSyncChanges( + // is in the process of being stopped. If |delete_metadata_change_list| is not + // null, it indicates that sync metadata must be deleted (i.e. the datatype + // was disabled), and |*delete_metadata_change_list| contains a change list to + // remove all metadata that the processor knows about (the bridge may decide + // to implement deletion by other means). + virtual StopSyncResponse ApplyStopSyncChanges( std::unique_ptr<MetadataChangeList> delete_metadata_change_list); // Needs to be informed about any model change occurring via Delete() and
diff --git a/components/sync/model_impl/client_tag_based_model_type_processor.cc b/components/sync/model_impl/client_tag_based_model_type_processor.cc index 9acdd35..766b85da 100644 --- a/components/sync/model_impl/client_tag_based_model_type_processor.cc +++ b/components/sync/model_impl/client_tag_based_model_type_processor.cc
@@ -62,8 +62,9 @@ bridge_(nullptr), dump_stack_(dump_stack), commit_only_(commit_only), - weak_ptr_factory_(this) { - ResetState(); + weak_ptr_factory_for_controller_(this), + weak_ptr_factory_for_worker_(this) { + ResetState(CLEAR_METADATA); } ClientTagBasedModelTypeProcessor::~ClientTagBasedModelTypeProcessor() { @@ -151,7 +152,7 @@ activation_response->model_type_state = model_type_state_; activation_response->type_processor = std::make_unique<ModelTypeProcessorProxy>( - weak_ptr_factory_.GetWeakPtr(), + weak_ptr_factory_for_worker_.GetWeakPtr(), base::ThreadTaskRunnerHandle::Get()); std::move(start_callback_).Run(std::move(activation_response)); } @@ -164,35 +165,58 @@ return !!worker_; } -void ClientTagBasedModelTypeProcessor::DisableSync() { +void ClientTagBasedModelTypeProcessor::OnSyncStopping( + SyncStopMetadataFate metadata_fate) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Disabling sync for a type never happens before the model is ready to sync. DCHECK(model_ready_to_sync_); - std::unique_ptr<MetadataChangeList> change_list = - bridge_->CreateMetadataChangeList(); - for (const auto& kv : entities_) { - change_list->ClearMetadata(kv.second->storage_key()); - } - change_list->ClearModelTypeState(); - - const ModelTypeSyncBridge::DisableSyncResponse response = - bridge_->ApplyDisableSyncChanges(std::move(change_list)); - - // Reset all the internal state of the processor. - ResetState(); - - switch (response) { - case ModelTypeSyncBridge::DisableSyncResponse::kModelStillReadyToSync: - // The model is still ready to sync (with the same |bridge_|) - replay the - // initialization. - ModelReadyToSync(std::make_unique<MetadataBatch>()); + switch (metadata_fate) { + case KEEP_METADATA: { + switch (bridge_->ApplyStopSyncChanges( + /*delete_metadata_change_list=*/nullptr)) { + case ModelTypeSyncBridge::StopSyncResponse::kModelStillReadyToSync: + // The model is still ready to sync (with the same |bridge_|) and same + // sync metadata. + ResetState(KEEP_METADATA); + break; + case ModelTypeSyncBridge::StopSyncResponse::kModelNoLongerReadyToSync: + // Model not ready to sync, so wait until the bridge calls + // ModelReadyToSync(), and meanwhile throw away all metadata. + ResetState(CLEAR_METADATA); + break; + } break; - case ModelTypeSyncBridge::DisableSyncResponse::kModelNoLongerReadyToSync: - // Model not ready to sync, so wait until the bridge calls - // ModelReadyToSync(). - model_ready_to_sync_ = false; + } + + case CLEAR_METADATA: { + // Clear persisted metadata. + std::unique_ptr<MetadataChangeList> change_list = + bridge_->CreateMetadataChangeList(); + for (const auto& kv : entities_) { + change_list->ClearMetadata(kv.second->storage_key()); + } + change_list->ClearModelTypeState(); + + const ModelTypeSyncBridge::StopSyncResponse response = + bridge_->ApplyStopSyncChanges(std::move(change_list)); + + // Reset all the internal state of the processor. + ResetState(CLEAR_METADATA); + + switch (response) { + case ModelTypeSyncBridge::StopSyncResponse::kModelStillReadyToSync: + // The model is still ready to sync (with the same |bridge_|) - replay + // the initialization. + ModelReadyToSync(std::make_unique<MetadataBatch>()); + break; + case ModelTypeSyncBridge::StopSyncResponse::kModelNoLongerReadyToSync: + // Model not ready to sync, so wait until the bridge calls + // ModelReadyToSync(). + break; + } break; + } } } @@ -226,7 +250,7 @@ base::WeakPtr<ModelTypeControllerDelegate> ClientTagBasedModelTypeProcessor::GetControllerDelegateOnUIThread() { - return weak_ptr_factory_.GetWeakPtr(); + return weak_ptr_factory_for_controller_.GetWeakPtr(); } void ClientTagBasedModelTypeProcessor::ConnectSync( @@ -244,7 +268,7 @@ DCHECK(IsConnected()); DVLOG(1) << "Disconnecting sync for " << ModelTypeToString(type_); - weak_ptr_factory_.InvalidateWeakPtrs(); + weak_ptr_factory_for_worker_.InvalidateWeakPtrs(); worker_.reset(); for (const auto& kv : entities_) { @@ -402,7 +426,7 @@ std::move(entities_requiring_data), base::BindRepeating( &ClientTagBasedModelTypeProcessor::OnPendingDataLoaded, - weak_ptr_factory_.GetWeakPtr(), max_entries, callback)); + weak_ptr_factory_for_worker_.GetWeakPtr(), max_entries, callback)); } else { // All commit data can be availbale in memory for those entries passed in // the .put() method. @@ -1024,21 +1048,29 @@ entities_.erase(entity->metadata().client_tag_hash()); } -void ClientTagBasedModelTypeProcessor::ResetState() { +void ClientTagBasedModelTypeProcessor::ResetState( + SyncStopMetadataFate metadata_fate) { // This should reset all mutable fields (except for |bridge_|). worker_.reset(); model_error_.reset(); - model_ready_to_sync_ = false; - entities_.clear(); - storage_key_to_tag_hash_.clear(); - model_type_state_ = sync_pb::ModelTypeState(); start_callback_ = StartCallback(); error_handler_ = ModelErrorHandler(); cached_gc_directive_version_ = 0; cached_gc_directive_aged_out_day_ = base::Time::FromDoubleT(0); + switch (metadata_fate) { + case KEEP_METADATA: + break; + case CLEAR_METADATA: + model_ready_to_sync_ = false; + entities_.clear(); + storage_key_to_tag_hash_.clear(); + model_type_state_ = sync_pb::ModelTypeState(); + break; + } + // Do not let any delayed callbacks to be called. - weak_ptr_factory_.InvalidateWeakPtrs(); + weak_ptr_factory_for_worker_.InvalidateWeakPtrs(); } void ClientTagBasedModelTypeProcessor::GetAllNodesForDebugging( @@ -1047,7 +1079,7 @@ return; bridge_->GetAllDataForDebugging(base::BindOnce( &ClientTagBasedModelTypeProcessor::MergeDataWithMetadataForDebugging, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + weak_ptr_factory_for_worker_.GetWeakPtr(), std::move(callback))); } void ClientTagBasedModelTypeProcessor::MergeDataWithMetadataForDebugging(
diff --git a/components/sync/model_impl/client_tag_based_model_type_processor.h b/components/sync/model_impl/client_tag_based_model_type_processor.h index b57d5709..68c18b4 100644 --- a/components/sync/model_impl/client_tag_based_model_type_processor.h +++ b/components/sync/model_impl/client_tag_based_model_type_processor.h
@@ -15,6 +15,7 @@ #include "base/optional.h" #include "base/sequence_checker.h" #include "components/sync/base/model_type.h" +#include "components/sync/base/sync_stop_metadata_fate.h" #include "components/sync/engine/cycle/status_counters.h" #include "components/sync/engine/model_type_processor.h" #include "components/sync/engine/non_blocking_sync_common.h" @@ -84,7 +85,7 @@ // ModelTypeControllerDelegate implementation. void OnSyncStarting(const DataTypeActivationRequest& request, StartCallback callback) override; - void DisableSync() override; + void OnSyncStopping(SyncStopMetadataFate metadata_fate) override; void GetAllNodesForDebugging(AllNodesCallback callback) override; void GetStatusCountersForDebugging(StatusCountersCallback callback) override; void RecordMemoryUsageHistogram() override; @@ -208,7 +209,7 @@ // TODO(jkrcal): Replace the helper function by grouping the state naturally // into a few structs / nested classes so that the state can be reset by // resetting these structs. - void ResetState(); + void ResetState(SyncStopMetadataFate metadata_fate); // Adds metadata to all data returned by the bridge. // TODO(jkrcal): Mark as const (together with functions it depends on such as @@ -302,8 +303,14 @@ SEQUENCE_CHECKER(sequence_checker_); + // WeakPtrFactory for this processor for ModelTypeController (only gets + // invalidated during destruction). + base::WeakPtrFactory<ModelTypeControllerDelegate> + weak_ptr_factory_for_controller_; + // WeakPtrFactory for this processor which will be sent to sync thread. - base::WeakPtrFactory<ClientTagBasedModelTypeProcessor> weak_ptr_factory_; + base::WeakPtrFactory<ClientTagBasedModelTypeProcessor> + weak_ptr_factory_for_worker_; DISALLOW_COPY_AND_ASSIGN(ClientTagBasedModelTypeProcessor); };
diff --git a/components/sync/model_impl/client_tag_based_model_type_processor_unittest.cc b/components/sync/model_impl/client_tag_based_model_type_processor_unittest.cc index 489bddc..c4ed03c 100644 --- a/components/sync/model_impl/client_tag_based_model_type_processor_unittest.cc +++ b/components/sync/model_impl/client_tag_based_model_type_processor_unittest.cc
@@ -1208,11 +1208,11 @@ EXPECT_TRUE(worker()->HasPendingCommitForHash(kHash3)); } -// Test proper handling of disable and re-enable. +// Test proper handling of stop (without disabling sync) and re-enable. // -// Creates items in various states of commit and verifies they re-attempt to +// Creates items in various states of commit and verifies they do NOT attempt to // commit on re-enable. -TEST_F(ClientTagBasedModelTypeProcessorTest, Disable) { +TEST_F(ClientTagBasedModelTypeProcessorTest, Stop) { InitializeToReadyState(); // The first item is fully committed. @@ -1222,7 +1222,35 @@ bridge()->WriteItem(kKey2, kValue2); EXPECT_TRUE(worker()->HasPendingCommitForHash(kHash2)); - type_processor()->DisableSync(); + type_processor()->OnSyncStopping(KEEP_METADATA); + EXPECT_TRUE(type_processor()->IsTrackingMetadata()); + + // The third item is added after disable. + bridge()->WriteItem(kKey3, kValue3); + + // Now we re-enable. + OnSyncStarting(); + worker()->UpdateFromServer(); + + // Once we're ready to commit, only the newest items should be committed. + worker()->VerifyPendingCommits({{kHash3}}); +} + +// Test proper handling of disable and re-enable. +// +// Creates items in various states of commit and verifies they re-attempt to +// commit on re-enable. +TEST_F(ClientTagBasedModelTypeProcessorTest, StopAndClearMetadata) { + InitializeToReadyState(); + + // The first item is fully committed. + WriteItemAndAck(kKey1, kValue1); + + // The second item has a commit request in progress. + bridge()->WriteItem(kKey2, kValue2); + EXPECT_TRUE(worker()->HasPendingCommitForHash(kHash2)); + + type_processor()->OnSyncStopping(CLEAR_METADATA); EXPECT_FALSE(type_processor()->IsTrackingMetadata()); // The third item is added after disable.
diff --git a/components/sync/user_events/user_event_sync_bridge.cc b/components/sync/user_events/user_event_sync_bridge.cc index 564f807..398a1a62 100644 --- a/components/sync/user_events/user_event_sync_bridge.cc +++ b/components/sync/user_events/user_event_sync_bridge.cc
@@ -158,28 +158,31 @@ #if !defined(OS_IOS) // https://crbug.com/834042 DCHECK(!GetAuthenticatedAccountId().empty()); #endif // !defined(OS_IOS) - bool was_sync_started = is_sync_starting_or_started_; + DCHECK(!is_sync_starting_or_started_); + is_sync_starting_or_started_ = true; - if (store_ && change_processor()->IsTrackingMetadata() && !was_sync_started) { + if (store_ && change_processor()->IsTrackingMetadata()) { ReadAllDataAndResubmit(); } } -ModelTypeSyncBridge::DisableSyncResponse -UserEventSyncBridge::ApplyDisableSyncChanges( +ModelTypeSyncBridge::StopSyncResponse UserEventSyncBridge::ApplyStopSyncChanges( std::unique_ptr<MetadataChangeList> delete_metadata_change_list) { - // Sync can only be disabled after initialization. + // Sync can only be stopped after initialization. DCHECK(deferred_user_events_while_initializing_.empty()); is_sync_starting_or_started_ = false; - // Delete everything except user consents. With DICE the signout may happen - // frequently. It is important to report all user consents, thus, they are - // persisted for some time even after signout. - store_->ReadAllData(base::BindOnce( - &UserEventSyncBridge::OnReadAllDataToDelete, base::AsWeakPtr(this), - std::move(delete_metadata_change_list))); - return DisableSyncResponse::kModelStillReadyToSync; + if (delete_metadata_change_list) { + // Delete everything except user consents. With DICE the signout may happen + // frequently. It is important to report all user consents, thus, they are + // persisted for some time even after signout. + store_->ReadAllData(base::BindOnce( + &UserEventSyncBridge::OnReadAllDataToDelete, base::AsWeakPtr(this), + std::move(delete_metadata_change_list))); + } + + return StopSyncResponse::kModelStillReadyToSync; } void UserEventSyncBridge::OnReadAllDataToDelete(
diff --git a/components/sync/user_events/user_event_sync_bridge.h b/components/sync/user_events/user_event_sync_bridge.h index c70490c..8d0d204 100644 --- a/components/sync/user_events/user_event_sync_bridge.h +++ b/components/sync/user_events/user_event_sync_bridge.h
@@ -44,7 +44,7 @@ void GetAllDataForDebugging(DataCallback callback) override; std::string GetClientTag(const EntityData& entity_data) override; std::string GetStorageKey(const EntityData& entity_data) override; - DisableSyncResponse ApplyDisableSyncChanges( + StopSyncResponse ApplyStopSyncChanges( std::unique_ptr<MetadataChangeList> delete_metadata_change_list) override; void RecordUserEvent(std::unique_ptr<sync_pb::UserEventSpecifics> specifics);
diff --git a/components/sync/user_events/user_event_sync_bridge_unittest.cc b/components/sync/user_events/user_event_sync_bridge_unittest.cc index 49a0588..ecd2d5e 100644 --- a/components/sync/user_events/user_event_sync_bridge_unittest.cc +++ b/components/sync/user_events/user_event_sync_bridge_unittest.cc
@@ -193,21 +193,21 @@ ElementsAre(Pair(storage_key, MatchesUserEvent(specifics)))); } -TEST_F(UserEventSyncBridgeTest, ApplyDisableSyncChanges) { +TEST_F(UserEventSyncBridgeTest, ApplyStopSyncChanges) { const UserEventSpecifics specifics(CreateSpecifics(1u, 2u, 3u)); bridge()->RecordUserEvent(std::make_unique<UserEventSpecifics>(specifics)); ASSERT_THAT(GetAllData(), SizeIs(1)); EXPECT_THAT( - bridge()->ApplyDisableSyncChanges(WriteBatch::CreateMetadataChangeList()), - Eq(ModelTypeSyncBridge::DisableSyncResponse::kModelStillReadyToSync)); + bridge()->ApplyStopSyncChanges(WriteBatch::CreateMetadataChangeList()), + Eq(ModelTypeSyncBridge::StopSyncResponse::kModelStillReadyToSync)); // The bridge may asynchronously query the store to choose what to delete. base::RunLoop().RunUntilIdle(); EXPECT_THAT(GetAllData(), IsEmpty()); } -TEST_F(UserEventSyncBridgeTest, ApplyDisableSyncChangesShouldKeepConsents) { +TEST_F(UserEventSyncBridgeTest, ApplyStopSyncChangesShouldKeepConsents) { UserEventSpecifics user_event_specifics(CreateSpecifics(2u, 2u, 2u)); auto* consent = user_event_specifics.mutable_user_consent(); consent->set_feature(UserEventSpecifics::UserConsent::CHROME_SYNC); @@ -217,8 +217,8 @@ ASSERT_THAT(GetAllData(), SizeIs(1)); EXPECT_THAT( - bridge()->ApplyDisableSyncChanges(WriteBatch::CreateMetadataChangeList()), - Eq(ModelTypeSyncBridge::DisableSyncResponse::kModelStillReadyToSync)); + bridge()->ApplyStopSyncChanges(WriteBatch::CreateMetadataChangeList()), + Eq(ModelTypeSyncBridge::StopSyncResponse::kModelStillReadyToSync)); // The bridge may asynchronously query the store to choose what to delete. base::RunLoop().RunUntilIdle(); @@ -418,7 +418,7 @@ bridge()->RecordUserEvent(std::make_unique<UserEventSpecifics>(consent)); - bridge()->ApplyDisableSyncChanges(WriteBatch::CreateMetadataChangeList()); + bridge()->ApplyStopSyncChanges(WriteBatch::CreateMetadataChangeList()); // The bridge may asynchronously query the store to choose what to delete. base::RunLoop().RunUntilIdle(); @@ -563,7 +563,7 @@ std::make_unique<UserEventSpecifics>(user_event_specifics)); ASSERT_THAT(GetAllData(), SizeIs(1)); - bridge()->ApplyDisableSyncChanges(WriteBatch::CreateMetadataChangeList()); + bridge()->ApplyStopSyncChanges(WriteBatch::CreateMetadataChangeList()); // The bridge may asynchronously query the store to choose what to delete. base::RunLoop().RunUntilIdle(); @@ -581,7 +581,7 @@ bridge()->OnSyncStarting(); base::RunLoop().RunUntilIdle(); - bridge()->ApplyDisableSyncChanges(WriteBatch::CreateMetadataChangeList()); + bridge()->ApplyStopSyncChanges(WriteBatch::CreateMetadataChangeList()); base::RunLoop().RunUntilIdle(); // The previous user signs in again and enables sync.
diff --git a/components/sync_bookmarks/BUILD.gn b/components/sync_bookmarks/BUILD.gn index d7f637f..ff03f1d9 100644 --- a/components/sync_bookmarks/BUILD.gn +++ b/components/sync_bookmarks/BUILD.gn
@@ -14,6 +14,8 @@ "bookmark_model_associator.h", "bookmark_model_type_processor.cc", "bookmark_model_type_processor.h", + "bookmark_sync_service.cc", + "bookmark_sync_service.h", "synced_bookmark_tracker.cc", "synced_bookmark_tracker.h", ] @@ -23,6 +25,7 @@ "//components/bookmarks/browser", "//components/favicon/core", "//components/history/core/browser", + "//components/keyed_service/core:core", "//components/sync", "//components/undo", "//ui/gfx",
diff --git a/components/sync_bookmarks/DEPS b/components/sync_bookmarks/DEPS index 0d5798c..eb67095 100644 --- a/components/sync_bookmarks/DEPS +++ b/components/sync_bookmarks/DEPS
@@ -3,6 +3,7 @@ "+components/bookmarks/test", "+components/favicon/core", "+components/history/core/browser", + "+components/keyed_service", "+components/prefs", "+components/sync", "+components/undo",
diff --git a/components/sync_bookmarks/bookmark_model_type_processor.cc b/components/sync_bookmarks/bookmark_model_type_processor.cc index b07032c87..2162e5f 100644 --- a/components/sync_bookmarks/bookmark_model_type_processor.cc +++ b/components/sync_bookmarks/bookmark_model_type_processor.cc
@@ -541,7 +541,8 @@ std::move(start_callback_).Run(std::move(activation_context)); } -void BookmarkModelTypeProcessor::DisableSync() { +void BookmarkModelTypeProcessor::OnSyncStopping( + syncer::SyncStopMetadataFate metadata_fate) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); NOTIMPLEMENTED(); }
diff --git a/components/sync_bookmarks/bookmark_model_type_processor.h b/components/sync_bookmarks/bookmark_model_type_processor.h index 7ba225a..81039d7 100644 --- a/components/sync_bookmarks/bookmark_model_type_processor.h +++ b/components/sync_bookmarks/bookmark_model_type_processor.h
@@ -48,7 +48,7 @@ // ModelTypeControllerDelegate implementation. void OnSyncStarting(const syncer::DataTypeActivationRequest& request, StartCallback start_callback) override; - void DisableSync() override; + void OnSyncStopping(syncer::SyncStopMetadataFate metadata_fate) override; void GetAllNodesForDebugging(AllNodesCallback callback) override; void GetStatusCountersForDebugging(StatusCountersCallback callback) override; void RecordMemoryUsageHistogram() override;
diff --git a/components/sync_bookmarks/bookmark_sync_service.cc b/components/sync_bookmarks/bookmark_sync_service.cc new file mode 100644 index 0000000..e34166ca --- /dev/null +++ b/components/sync_bookmarks/bookmark_sync_service.cc
@@ -0,0 +1,52 @@ +// Copyright 2018 The Chromium 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/sync_bookmarks/bookmark_sync_service.h" + +#include "base/feature_list.h" +#include "components/sync/driver/sync_driver_switches.h" +#include "components/sync_bookmarks/bookmark_model_type_processor.h" +#include "components/undo/bookmark_undo_service.h" + +namespace sync_bookmarks { + +BookmarkSyncService::BookmarkSyncService( + BookmarkUndoService* bookmark_undo_service) { + if (base::FeatureList::IsEnabled(switches::kSyncUSSBookmarks)) { + bookmark_model_type_processor_ = + std::make_unique<sync_bookmarks::BookmarkModelTypeProcessor>( + bookmark_undo_service); + } +} + +BookmarkSyncService::~BookmarkSyncService() {} + +void BookmarkSyncService::Shutdown() {} + +std::string BookmarkSyncService::EncodeBookmarkSyncMetadata() { + if (!bookmark_model_type_processor_) { + return std::string(); + } + return bookmark_model_type_processor_->EncodeSyncMetadata(); +} + +void BookmarkSyncService::DecodeBookmarkSyncMetadata( + const std::string& metadata_str, + const base::RepeatingClosure& schedule_save_closure, + bookmarks::BookmarkModel* model) { + if (bookmark_model_type_processor_) { + bookmark_model_type_processor_->DecodeSyncMetadata( + metadata_str, schedule_save_closure, model); + } +} + +base::WeakPtr<syncer::ModelTypeControllerDelegate> +BookmarkSyncService::GetBookmarkSyncControllerDelegateOnUIThread() { + if (!bookmark_model_type_processor_) { + return nullptr; + } + return bookmark_model_type_processor_->GetWeakPtr(); +} + +} // namespace sync_bookmarks
diff --git a/components/sync_bookmarks/bookmark_sync_service.h b/components/sync_bookmarks/bookmark_sync_service.h new file mode 100644 index 0000000..92a4a66 --- /dev/null +++ b/components/sync_bookmarks/bookmark_sync_service.h
@@ -0,0 +1,60 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SYNC_BOOKMARKS_BOOKMARK_SYNC_SERVICE_H_ +#define COMPONENTS_SYNC_BOOKMARKS_BOOKMARK_SYNC_SERVICE_H_ + +#include <memory> +#include <string> + +#include "base/memory/weak_ptr.h" +#include "base/sequence_checker.h" +#include "components/keyed_service/core/keyed_service.h" + +class BookmarkUndoService; + +namespace syncer { +class ModelTypeControllerDelegate; +} + +namespace bookmarks { +class BookmarkModel; +} + +namespace sync_bookmarks { +class BookmarkModelTypeProcessor; + +// This service owns the BookmarkModelTypeProcessor. +class BookmarkSyncService : public KeyedService { + public: + // |bookmark_undo_service| must not be null and must outlive this object. + explicit BookmarkSyncService(BookmarkUndoService* bookmark_undo_service); + + // KeyedService implemenation. + ~BookmarkSyncService() override; + void Shutdown() override; + + // Analgous to Encode/Decode methods in BookmarkClient. + std::string EncodeBookmarkSyncMetadata(); + void DecodeBookmarkSyncMetadata( + const std::string& metadata_str, + const base::RepeatingClosure& schedule_save_closure, + bookmarks::BookmarkModel* model); + + // Returns the ModelTypeControllerDelegate for syncer::BOOKMARKS. + virtual base::WeakPtr<syncer::ModelTypeControllerDelegate> + GetBookmarkSyncControllerDelegateOnUIThread(); + + private: + // BookmarkModelTypeProcessor handles communications between sync engine and + // BookmarkModel/HistoryService. + std::unique_ptr<sync_bookmarks::BookmarkModelTypeProcessor> + bookmark_model_type_processor_; + + DISALLOW_COPY_AND_ASSIGN(BookmarkSyncService); +}; + +} // namespace sync_bookmarks + +#endif // COMPONENTS_SYNC_BOOKMARKS_BOOKMARK_SYNC_SERVICE_H_
diff --git a/components/sync_preferences/pref_model_associator.cc b/components/sync_preferences/pref_model_associator.cc index f31df00..0fe8746 100644 --- a/components/sync_preferences/pref_model_associator.cc +++ b/components/sync_preferences/pref_model_associator.cc
@@ -16,6 +16,7 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" +#include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "components/prefs/persistent_pref_store.h" @@ -292,7 +293,7 @@ base::Value result = to_value.Clone(); base::Value::ListStorage& list = result.GetList(); for (const auto& value : from_value.GetList()) { - if (std::find(list.begin(), list.end(), value) == list.end()) + if (!base::ContainsValue(list, value)) list.emplace_back(value.Clone()); }
diff --git a/components/sync_sessions/session_sync_bridge.cc b/components/sync_sessions/session_sync_bridge.cc index 243f1fa..88a4787 100644 --- a/components/sync_sessions/session_sync_bridge.cc +++ b/components/sync_sessions/session_sync_bridge.cc
@@ -291,15 +291,14 @@ return SessionStore::GetStorageKey(entity_data.specifics.session()); } -ModelTypeSyncBridge::DisableSyncResponse -SessionSyncBridge::ApplyDisableSyncChanges( +ModelTypeSyncBridge::StopSyncResponse SessionSyncBridge::ApplyStopSyncChanges( std::unique_ptr<MetadataChangeList> delete_metadata_change_list) { local_session_event_router_->Stop(); - if (syncing_) { + if (syncing_ && delete_metadata_change_list) { syncing_->store->DeleteAllDataAndMetadata(); } syncing_.reset(); - return DisableSyncResponse::kModelNoLongerReadyToSync; + return StopSyncResponse::kModelNoLongerReadyToSync; } std::unique_ptr<LocalSessionEventHandlerImpl::WriteBatch> @@ -338,17 +337,6 @@ } void SessionSyncBridge::OnSyncStarting() { - // |syncing_| can be non-null during testing, if ProfileSyncService is - // restarted without having disabled sync, because USS bridges currently do - // not receive a notification when sync is stopped (without actually - // disabling sync, e.g. browser shutdown). - // TODO(mastiz): Remove the workaround below once a proper signal is plumbed. - if (syncing_) { - local_session_event_router_->Stop(); - syncing_.reset(); // Prevents metadata from being deleted. - change_processor()->GetControllerDelegateOnUIThread()->DisableSync(); - } - DCHECK(!syncing_); session_store_factory_.Run(base::BindOnce(
diff --git a/components/sync_sessions/session_sync_bridge.h b/components/sync_sessions/session_sync_bridge.h index 1a9be71..4dce7dd 100644 --- a/components/sync_sessions/session_sync_bridge.h +++ b/components/sync_sessions/session_sync_bridge.h
@@ -73,7 +73,7 @@ void GetAllDataForDebugging(DataCallback callback) override; std::string GetClientTag(const syncer::EntityData& entity_data) override; std::string GetStorageKey(const syncer::EntityData& entity_data) override; - DisableSyncResponse ApplyDisableSyncChanges( + StopSyncResponse ApplyStopSyncChanges( std::unique_ptr<syncer::MetadataChangeList> delete_metadata_change_list) override;
diff --git a/components/sync_sessions/session_sync_bridge_unittest.cc b/components/sync_sessions/session_sync_bridge_unittest.cc index e9b4b87c..337a0899 100644 --- a/components/sync_sessions/session_sync_bridge_unittest.cc +++ b/components/sync_sessions/session_sync_bridge_unittest.cc
@@ -1002,7 +1002,7 @@ ASSERT_THAT(GetAllData(), Not(IsEmpty())); EXPECT_CALL(mock_processor(), ModelReadyToSync(_)).Times(0); - real_processor()->DisableSync(); + real_processor()->OnSyncStopping(syncer::CLEAR_METADATA); EXPECT_CALL(mock_processor(), ModelReadyToSync(IsEmptyMetadataBatch())); StartSyncing();
diff --git a/components/timers/alarm_timer_chromeos.cc b/components/timers/alarm_timer_chromeos.cc index da5c9b64..4ace852 100644 --- a/components/timers/alarm_timer_chromeos.cc +++ b/components/timers/alarm_timer_chromeos.cc
@@ -33,7 +33,7 @@ void SimpleAlarmTimer::Stop() { DCHECK(origin_task_runner_->RunsTasksInCurrentSequence()); - if (!base::Timer::is_running()) + if (!IsRunning()) return; if (!CanWakeFromSuspend()) {
diff --git a/components/update_client/command_line_config_policy.cc b/components/update_client/command_line_config_policy.cc index a645601..899d8ace2 100644 --- a/components/update_client/command_line_config_policy.cc +++ b/components/update_client/command_line_config_policy.cc
@@ -37,4 +37,8 @@ return GURL(); } +int CommandLineConfigPolicy::InitialDelay() const { + return 0; +} + } // namespace update_client
diff --git a/components/update_client/command_line_config_policy.h b/components/update_client/command_line_config_policy.h index d515c99..2d201a5 100644 --- a/components/update_client/command_line_config_policy.h +++ b/components/update_client/command_line_config_policy.h
@@ -32,6 +32,10 @@ // The override URL for updates. Can be empty. virtual GURL UrlSourceOverride() const; + // If non-zero, time interval in seconds until the first component + // update check. + virtual int InitialDelay() const; + virtual ~CommandLineConfigPolicy() {} };
diff --git a/components/visitedlink/test/BUILD.gn b/components/visitedlink/test/BUILD.gn index e74caca..8bac75b 100644 --- a/components/visitedlink/test/BUILD.gn +++ b/components/visitedlink/test/BUILD.gn
@@ -12,6 +12,7 @@ deps = [ "//base", + "//base/test:test_support", "//components/visitedlink/browser", "//components/visitedlink/common", "//components/visitedlink/renderer",
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc index f2da3544..0fa562a 100644 --- a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc +++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc
@@ -7,6 +7,8 @@ #include <memory> #include "base/bind.h" +#include "base/compiler_specific.h" +#include "build/build_config.h" #include "cc/trees/layer_tree_frame_sink_client.h" #include "components/viz/common/hit_test/hit_test_region_list.h" #include "components/viz/common/quads/compositor_frame.h" @@ -197,11 +199,16 @@ void DirectLayerTreeFrameSink::DisplayDidReceiveCALayerParams( const gfx::CALayerParams& ca_layer_params) { +#if defined(OS_MACOSX) // If |ca_layer_params| should have content only when there exists a client // to send it to. DCHECK(ca_layer_params.is_empty || display_client_); if (display_client_) display_client_->OnDisplayReceivedCALayerParams(ca_layer_params); +#else + NOTREACHED(); + ALLOW_UNUSED_LOCAL(display_client_); +#endif } void DirectLayerTreeFrameSink::DisplayDidCompleteSwapWithSize(
diff --git a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc index ac407f7c..0748bcc 100644 --- a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc +++ b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
@@ -6,6 +6,8 @@ #include <utility> +#include "base/compiler_specific.h" +#include "build/build_config.h" #include "components/viz/common/frame_sinks/begin_frame_source.h" #include "components/viz/service/display/display.h" #include "components/viz/service/display_embedder/external_begin_frame_controller_impl.h" @@ -177,17 +179,27 @@ void RootCompositorFrameSinkImpl::DisplayDidReceiveCALayerParams( const gfx::CALayerParams& ca_layer_params) { +#if defined(OS_MACOSX) // If |ca_layer_params| should have content only when there exists a client // to send it to. DCHECK(ca_layer_params.is_empty || display_client_); if (display_client_) display_client_->OnDisplayReceivedCALayerParams(ca_layer_params); +#else + NOTREACHED(); + ALLOW_UNUSED_LOCAL(display_client_); +#endif } void RootCompositorFrameSinkImpl::DisplayDidCompleteSwapWithSize( const gfx::Size& pixel_size) { +#if defined(OS_ANDROID) if (display_client_) display_client_->DidCompleteSwapWithSize(pixel_size); +#else + NOTREACHED(); + ALLOW_UNUSED_LOCAL(display_client_); +#endif } void RootCompositorFrameSinkImpl::DidSwapAfterSnapshotRequestReceived(
diff --git a/components/viz/test/mock_display_client.h b/components/viz/test/mock_display_client.h index 967fd14..96bb156 100644 --- a/components/viz/test/mock_display_client.h +++ b/components/viz/test/mock_display_client.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_VIZ_TEST_MOCK_DISPLAY_CLIENT_H_ #define COMPONENTS_VIZ_TEST_MOCK_DISPLAY_CLIENT_H_ +#include "build/build_config.h" #include "mojo/public/cpp/bindings/binding.h" #include "services/viz/privileged/interfaces/compositing/frame_sink_manager.mojom.h" #include "testing/gmock/include/gmock/gmock.h" @@ -19,12 +20,18 @@ mojom::DisplayClientPtr BindInterfacePtr(); // mojom::DisplayClient implementation. - MOCK_METHOD1(OnDisplayReceivedCALayerParams, void(const gfx::CALayerParams&)); MOCK_METHOD1(DidSwapAfterSnapshotRequestReceived, void(const std::vector<ui::LatencyInfo>&)); +#if defined(OS_MACOSX) + MOCK_METHOD1(OnDisplayReceivedCALayerParams, void(const gfx::CALayerParams&)); +#endif +#if defined(OS_WIN) MOCK_METHOD1(CreateLayeredWindowUpdater, void(mojom::LayeredWindowUpdaterRequest)); +#endif +#if defined(OS_ANDROID) MOCK_METHOD1(DidCompleteSwapWithSize, void(const gfx::Size&)); +#endif private: mojo::Binding<mojom::DisplayClient> binding_;
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index d7ae77e..e541f3a8 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -125,6 +125,7 @@ #include "net/ssl/ssl_config_service.h" #include "ppapi/buildflags/buildflags.h" #include "services/audio/public/cpp/audio_system_factory.h" +#include "services/audio/public/mojom/constants.mojom.h" #include "services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.h" #include "services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom.h" #include "services/resource_coordinator/public/mojom/service_constants.mojom.h" @@ -1298,7 +1299,7 @@ { TRACE_EVENT0("startup", "BrowserThreadsStarted::Subsystem:AudioMan"); - CreateAudioManager(); + InitializeAudio(); } { @@ -1629,7 +1630,7 @@ base::Bind(OnStoppedStartupTracing, startup_trace_file_))); } -void BrowserMainLoop::CreateAudioManager() { +void BrowserMainLoop::InitializeAudio() { DCHECK(!audio_manager_); audio_manager_ = GetContentClient()->browser()->CreateAudioManager( @@ -1660,6 +1661,12 @@ audio_service_runner_->StartWithTaskRunner(audio_manager_->GetTaskRunner()); } + if (base::FeatureList::IsEnabled(features::kAudioServiceLaunchOnStartup)) { + content::ServiceManagerConnection::GetForProcess() + ->GetConnector() + ->StartService(audio::mojom::kServiceName); + } + audio_system_ = audio::CreateAudioSystem( content::ServiceManagerConnection::GetForProcess() ->GetConnector()
diff --git a/content/browser/browser_main_loop.h b/content/browser/browser_main_loop.h index 542bedf..79d7479 100644 --- a/content/browser/browser_main_loop.h +++ b/content/browser/browser_main_loop.h
@@ -254,7 +254,7 @@ void InitStartupTracingForDuration(); void EndStartupTracing(); - void CreateAudioManager(); + void InitializeAudio(); bool UsingInProcessGpu() const;
diff --git a/content/browser/compositor/in_process_display_client.cc b/content/browser/compositor/in_process_display_client.cc index fdea3fe0..8f5e7a1b 100644 --- a/content/browser/compositor/in_process_display_client.cc +++ b/content/browser/compositor/in_process_display_client.cc
@@ -27,7 +27,7 @@ #endif } -InProcessDisplayClient::~InProcessDisplayClient() {} +InProcessDisplayClient::~InProcessDisplayClient() = default; viz::mojom::DisplayClientPtr InProcessDisplayClient::GetBoundPtr( scoped_refptr<base::SingleThreadTaskRunner> task_runner) { @@ -36,27 +36,24 @@ return ptr; } +void InProcessDisplayClient::DidSwapAfterSnapshotRequestReceived( + const std::vector<ui::LatencyInfo>& latency_info) {} + +#if defined(OS_MACOSX) void InProcessDisplayClient::OnDisplayReceivedCALayerParams( const gfx::CALayerParams& ca_layer_params) { -#if defined(OS_MACOSX) ui::CALayerFrameSink* ca_layer_frame_sink = ui::CALayerFrameSink::FromAcceleratedWidget(widget_); if (ca_layer_frame_sink) ca_layer_frame_sink->UpdateCALayerTree(ca_layer_params); else DLOG(WARNING) << "Received frame for non-existent widget."; -#else - DLOG(ERROR) << "Should not receive CALayer params on non-macOS platforms."; +} #endif -} -void InProcessDisplayClient::DidSwapAfterSnapshotRequestReceived( - const std::vector<ui::LatencyInfo>& latency_info) { -} - +#if defined(OS_WIN) void InProcessDisplayClient::CreateLayeredWindowUpdater( viz::mojom::LayeredWindowUpdaterRequest request) { -#if defined(OS_WIN) if (!viz::NeedsToUseLayerWindow(widget_)) { DLOG(ERROR) << "HWND shouldn't be using a layered window"; return; @@ -64,15 +61,7 @@ layered_window_updater_ = std::make_unique<viz::LayeredWindowUpdaterImpl>( widget_, std::move(request)); -#else -// This should never happen on non-Windows platforms. +} #endif -} - -void InProcessDisplayClient::DidCompleteSwapWithSize( - const gfx::Size& pixel_size) { - // Only used by Viz on Android, which overrides this. - NOTREACHED(); -} } // namespace content
diff --git a/content/browser/compositor/in_process_display_client.h b/content/browser/compositor/in_process_display_client.h index 2495144..f273104 100644 --- a/content/browser/compositor/in_process_display_client.h +++ b/content/browser/compositor/in_process_display_client.h
@@ -32,13 +32,18 @@ private: // viz::mojom::DisplayClient implementation: - void OnDisplayReceivedCALayerParams( - const gfx::CALayerParams& ca_layer_params) override; void DidSwapAfterSnapshotRequestReceived( const std::vector<ui::LatencyInfo>& latency_info) override; + +#if defined(OS_MACOSX) + void OnDisplayReceivedCALayerParams( + const gfx::CALayerParams& ca_layer_params) override; +#endif + +#if defined(OS_WIN) void CreateLayeredWindowUpdater( viz::mojom::LayeredWindowUpdaterRequest request) override; - void DidCompleteSwapWithSize(const gfx::Size& pixel_size) override; +#endif mojo::Binding<viz::mojom::DisplayClient> binding_; #if defined(OS_MACOSX) || defined(OS_WIN)
diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc index 6bf27bb..905fe91 100644 --- a/content/browser/devtools/protocol/network_handler.cc +++ b/content/browser/devtools/protocol/network_handler.cc
@@ -88,9 +88,6 @@ using ClearBrowserCookiesCallback = Network::Backend::ClearBrowserCookiesCallback; -const char kDevToolsEmulateNetworkConditionsClientId[] = - "X-DevTools-Emulate-Network-Conditions-Client-Id"; - Network::CertificateTransparencyCompliance SerializeCTPolicyCompliance( net::ct::CTPolicyCompliance ct_compliance) { switch (ct_compliance) { @@ -820,12 +817,6 @@ DISALLOW_COPY_AND_ASSIGN(NetworkNavigationThrottle); }; -void ConfigureServiceWorkerContextOnIO() { - std::set<std::string> headers; - headers.insert(kDevToolsEmulateNetworkConditionsClientId); - content::ServiceWorkerContext::AddExcludedHeadersForFetchEvent(headers); -} - bool GetPostData(const net::URLRequest* request, std::string* post_data) { if (!request->has_upload()) return false; @@ -967,9 +958,11 @@ }; NetworkHandler::NetworkHandler(const std::string& host_id, + const base::UnguessableToken& devtools_token, DevToolsIOContext* io_context) : DevToolsDomainHandler(Network::Metainfo::domainName), host_id_(host_id), + devtools_token_(devtools_token), io_context_(io_context), browser_context_(nullptr), storage_partition_(nullptr), @@ -983,8 +976,6 @@ if (have_configured_service_worker_context) return; have_configured_service_worker_context = true; - BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::BindOnce(&ConfigureServiceWorkerContextOnIO)); } NetworkHandler::~NetworkHandler() { @@ -2038,7 +2029,6 @@ void NetworkHandler::ApplyOverrides(net::HttpRequestHeaders* headers, bool* skip_service_worker, bool* disable_cache) { - headers->SetHeader(kDevToolsEmulateNetworkConditionsClientId, host_id_); for (auto& entry : extra_headers_) headers->SetHeader(entry.first, entry.second); *skip_service_worker |= bypass_service_worker_; @@ -2113,7 +2103,9 @@ network::mojom::NetworkContext* context = storage_partition_->GetNetworkContext(); bool offline = conditions ? conditions->offline : false; - context->SetNetworkConditions(host_id_, std::move(conditions)); + + if (!devtools_token_.is_empty()) + context->SetNetworkConditions(devtools_token_, std::move(conditions)); if (offline == !!background_sync_restorer_) return;
diff --git a/content/browser/devtools/protocol/network_handler.h b/content/browser/devtools/protocol/network_handler.h index ae4a2fc..e83b50c 100644 --- a/content/browser/devtools/protocol/network_handler.h +++ b/content/browser/devtools/protocol/network_handler.h
@@ -13,6 +13,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/optional.h" +#include "base/unguessable_token.h" #include "content/browser/devtools/devtools_url_loader_interceptor.h" #include "content/browser/devtools/protocol/devtools_domain_handler.h" #include "content/browser/devtools/protocol/network.h" @@ -21,10 +22,6 @@ #include "net/cookies/canonical_cookie.h" #include "services/network/public/mojom/network_service.mojom.h" -namespace base { -class UnguessableToken; -}; - namespace net { class HttpRequestHeaders; class URLRequest; @@ -59,7 +56,9 @@ class NetworkHandler : public DevToolsDomainHandler, public Network::Backend { public: - NetworkHandler(const std::string& host_id, DevToolsIOContext* io_context); + NetworkHandler(const std::string& host_id, + const base::UnguessableToken& devtools_token, + DevToolsIOContext* io_context); ~NetworkHandler() override; static std::vector<NetworkHandler*> ForAgentHost(DevToolsAgentHostImpl* host); @@ -200,7 +199,10 @@ mojo::ScopedDataPipeConsumerHandle pipe, const std::string& mime_type); + // TODO(dgozman): Remove this. const std::string host_id_; + + const base::UnguessableToken devtools_token_; DevToolsIOContext* const io_context_; std::unique_ptr<Network::Frontend> frontend_;
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc index 3ac86b2..7c17e2e 100644 --- a/content/browser/devtools/render_frame_devtools_agent_host.cc +++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -443,8 +443,11 @@ session->AddHandler(base::WrapUnique(new protocol::IOHandler( GetIOContext()))); session->AddHandler(base::WrapUnique(new protocol::MemoryHandler())); - session->AddHandler( - base::WrapUnique(new protocol::NetworkHandler(GetId(), GetIOContext()))); + session->AddHandler(base::WrapUnique(new protocol::NetworkHandler( + GetId(), + frame_tree_node_ ? frame_tree_node_->devtools_frame_token() + : base::UnguessableToken(), + GetIOContext()))); session->AddHandler(base::WrapUnique(new protocol::SchemaHandler())); session->AddHandler(base::WrapUnique(new protocol::ServiceWorkerHandler())); session->AddHandler(base::WrapUnique(new protocol::StorageHandler()));
diff --git a/content/browser/devtools/service_worker_devtools_agent_host.cc b/content/browser/devtools/service_worker_devtools_agent_host.cc index 64801cf7..c78e468c 100644 --- a/content/browser/devtools/service_worker_devtools_agent_host.cc +++ b/content/browser/devtools/service_worker_devtools_agent_host.cc
@@ -126,8 +126,8 @@ session->AttachToAgent(agent_ptr_); } session->AddHandler(base::WrapUnique(new protocol::InspectorHandler())); - session->AddHandler( - base::WrapUnique(new protocol::NetworkHandler(GetId(), GetIOContext()))); + session->AddHandler(base::WrapUnique(new protocol::NetworkHandler( + GetId(), devtools_worker_token_, GetIOContext()))); session->AddHandler(base::WrapUnique(new protocol::SchemaHandler())); return true; }
diff --git a/content/browser/devtools/shared_worker_devtools_agent_host.cc b/content/browser/devtools/shared_worker_devtools_agent_host.cc index fd40420ee..12c913b 100644 --- a/content/browser/devtools/shared_worker_devtools_agent_host.cc +++ b/content/browser/devtools/shared_worker_devtools_agent_host.cc
@@ -68,8 +68,8 @@ bool SharedWorkerDevToolsAgentHost::AttachSession(DevToolsSession* session) { session->AddHandler(std::make_unique<protocol::InspectorHandler>()); - session->AddHandler( - std::make_unique<protocol::NetworkHandler>(GetId(), GetIOContext())); + session->AddHandler(std::make_unique<protocol::NetworkHandler>( + GetId(), devtools_worker_token_, GetIOContext())); session->AddHandler(std::make_unique<protocol::SchemaHandler>()); session->SetRenderer(worker_host_ ? worker_host_->process_id() : -1, nullptr); if (state_ == WORKER_READY)
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index 4aad393..84789761 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -1344,7 +1344,8 @@ upgrade_if_insecure_, blob_url_loader_factory_ ? blob_url_loader_factory_->Clone() : nullptr, - devtools_navigation_token()), + devtools_navigation_token(), + frame_tree_node_->devtools_frame_token()), std::move(navigation_ui_data), navigation_handle_->service_worker_handle(), navigation_handle_->appcache_handle(), this);
diff --git a/content/browser/frame_host/navigation_request_info.cc b/content/browser/frame_host/navigation_request_info.cc index 2dc9038..f02f9a18 100644 --- a/content/browser/frame_host/navigation_request_info.cc +++ b/content/browser/frame_host/navigation_request_info.cc
@@ -21,7 +21,8 @@ bool upgrade_if_insecure, std::unique_ptr<network::SharedURLLoaderFactoryInfo> blob_url_loader_factory, - const base::UnguessableToken& devtools_navigation_token) + const base::UnguessableToken& devtools_navigation_token, + const base::UnguessableToken& devtools_frame_token) : common_params(common_params), begin_params(std::move(begin_params)), site_for_cookies(site_for_cookies), @@ -34,7 +35,8 @@ is_prerendering(is_prerendering), upgrade_if_insecure(upgrade_if_insecure), blob_url_loader_factory(std::move(blob_url_loader_factory)), - devtools_navigation_token(devtools_navigation_token) {} + devtools_navigation_token(devtools_navigation_token), + devtools_frame_token(devtools_frame_token) {} NavigationRequestInfo::NavigationRequestInfo(const NavigationRequestInfo& other) : common_params(other.common_params), @@ -48,7 +50,7 @@ report_raw_headers(other.report_raw_headers), is_prerendering(other.is_prerendering), upgrade_if_insecure(other.upgrade_if_insecure), - devtools_navigation_token(other.devtools_navigation_token) {} + devtools_frame_token(other.devtools_frame_token) {} NavigationRequestInfo::~NavigationRequestInfo() {}
diff --git a/content/browser/frame_host/navigation_request_info.h b/content/browser/frame_host/navigation_request_info.h index 4178a39..8b6a81c9 100644 --- a/content/browser/frame_host/navigation_request_info.h +++ b/content/browser/frame_host/navigation_request_info.h
@@ -23,21 +23,21 @@ // ResourceDispatcherHost. It is initialized on the UI thread, and then passed // to the IO thread by a NavigationRequest object. struct CONTENT_EXPORT NavigationRequestInfo { - NavigationRequestInfo( - const CommonNavigationParams& common_params, - mojom::BeginNavigationParamsPtr begin_params, - const GURL& site_for_cookies, - bool is_main_frame, - bool parent_is_main_frame, - bool are_ancestors_secure, - int frame_tree_node_id, - bool is_for_guests_only, - bool report_raw_headers, - bool is_prerendering, - bool upgrade_if_insecure, - std::unique_ptr<network::SharedURLLoaderFactoryInfo> - blob_url_loader_factory, - const base::UnguessableToken& devtools_navigation_token); + NavigationRequestInfo(const CommonNavigationParams& common_params, + mojom::BeginNavigationParamsPtr begin_params, + const GURL& site_for_cookies, + bool is_main_frame, + bool parent_is_main_frame, + bool are_ancestors_secure, + int frame_tree_node_id, + bool is_for_guests_only, + bool report_raw_headers, + bool is_prerendering, + bool upgrade_if_insecure, + std::unique_ptr<network::SharedURLLoaderFactoryInfo> + blob_url_loader_factory, + const base::UnguessableToken& devtools_navigation_token, + const base::UnguessableToken& devtools_frame_token); NavigationRequestInfo(const NavigationRequestInfo& other); ~NavigationRequestInfo(); @@ -71,6 +71,8 @@ std::unique_ptr<network::SharedURLLoaderFactoryInfo> blob_url_loader_factory; const base::UnguessableToken devtools_navigation_token; + + const base::UnguessableToken devtools_frame_token; }; } // namespace content
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc index db60507..e0c9367 100644 --- a/content/browser/loader/navigation_url_loader_impl.cc +++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -245,6 +245,7 @@ new_request->fetch_request_context_type = request_info->begin_params->request_context_type; new_request->upgrade_if_insecure = request_info->upgrade_if_insecure; + new_request->throttling_profile_id = request_info->devtools_frame_token; return new_request; } @@ -283,7 +284,8 @@ previous_request_info.is_prerendering, previous_request_info.upgrade_if_insecure, nullptr /* blob_url_loader_factory */, - previous_request_info.devtools_navigation_token); + previous_request_info.devtools_navigation_token, + previous_request_info.devtools_frame_token); } // Called for requests that we don't have a URLLoaderFactory for. @@ -400,7 +402,7 @@ GetURLLoaderOptions(request_info->is_main_frame), request_info->frame_tree_node_id, request_info->devtools_navigation_token, - request_info->report_raw_headers, + request_info->devtools_frame_token, request_info->report_raw_headers, request_info->begin_params->load_flags, base::MakeRefCounted< SignedExchangeURLLoaderFactoryForNonNetworkService>( @@ -429,7 +431,7 @@ upload_file_system_context, *request_info, std::move(navigation_ui_data_), std::move(url_loader_client), std::move(url_loader), service_worker_navigation_handle_core, - appcache_handle_core, options, &global_request_id_); + appcache_handle_core, options, global_request_id_); } // TODO(arthursonzogni): Detect when the ResourceDispatcherHost didn't @@ -457,6 +459,11 @@ web_contents_getter_ = base::BindRepeating( &GetWebContentsFromFrameTreeNodeID, frame_tree_node_id_); navigation_ui_data_ = std::move(navigation_ui_data); + // The ResourceDispatcherHostImpl can be null in unit tests. + ResourceDispatcherHostImpl* rph = ResourceDispatcherHostImpl::Get(); + if (rph) + global_request_id_ = rph->MakeGlobalRequestID(); + default_request_handler_factory_ = base::BindRepeating( &URLLoaderRequestController:: CreateDefaultRequestHandlerForNonNetworkService, @@ -521,9 +528,6 @@ interceptors_.push_back(std::move(service_worker_interceptor)); - // TODO(shimazu): Make sure we have a consistent global id for the - // navigation request. - global_request_id_ = MakeGlobalRequestID(); Restart(); } @@ -611,7 +615,7 @@ GetURLLoaderOptions(request_info->is_main_frame), request_info->frame_tree_node_id, request_info->devtools_navigation_token, - request_info->report_raw_headers, + request_info->devtools_frame_token, request_info->report_raw_headers, request_info->begin_params->load_flags, default_url_loader_factory_getter_->GetNetworkFactory(), base::BindRepeating(
diff --git a/content/browser/loader/navigation_url_loader_impl_unittest.cc b/content/browser/loader/navigation_url_loader_impl_unittest.cc index 59ef014..6e41331 100644 --- a/content/browser/loader/navigation_url_loader_impl_unittest.cc +++ b/content/browser/loader/navigation_url_loader_impl_unittest.cc
@@ -179,7 +179,8 @@ false /* report_raw_headers */, false /* is_prerenering */, upgrade_if_insecure /* upgrade_if_insecure */, nullptr /* blob_url_loader_factory */, - base::UnguessableToken::Create() /* devtools_navigation_token */)); + base::UnguessableToken::Create() /* devtools_navigation_token */, + base::UnguessableToken::Create() /* devtools_frame_token */)); std::vector<std::unique_ptr<NavigationLoaderInterceptor>> interceptors; most_recent_resource_request_ = base::nullopt; interceptors.push_back(std::make_unique<TestNavigationLoaderInterceptor>(
diff --git a/content/browser/loader/navigation_url_loader_unittest.cc b/content/browser/loader/navigation_url_loader_unittest.cc index a00adcf..75f70ba 100644 --- a/content/browser/loader/navigation_url_loader_unittest.cc +++ b/content/browser/loader/navigation_url_loader_unittest.cc
@@ -96,6 +96,7 @@ new NavigationRequestInfo(common_params, std::move(begin_params), url, true, false, false, -1, false, false, false, false, nullptr, + base::UnguessableToken::Create(), base::UnguessableToken::Create())); return NavigationURLLoader::Create( browser_context_->GetResourceContext(),
diff --git a/content/browser/loader/prefetch_url_loader.cc b/content/browser/loader/prefetch_url_loader.cc index 02d9ddb..bbfd85f 100644 --- a/content/browser/loader/prefetch_url_loader.cc +++ b/content/browser/loader/prefetch_url_loader.cc
@@ -30,6 +30,7 @@ url_(resource_request.url), report_raw_headers_(resource_request.report_raw_headers), load_flags_(resource_request.load_flags), + throttling_profile_id_(resource_request.throttling_profile_id), network_loader_factory_(std::move(network_loader_factory)), client_binding_(this), forwarding_client_(std::move(client)), @@ -96,10 +97,10 @@ signed_exchange_prefetch_handler_ = std::make_unique<SignedExchangePrefetchHandler>( frame_tree_node_id_getter_, report_raw_headers_, load_flags_, - response, std::move(loader_), client_binding_.Unbind(), - network_loader_factory_, request_initiator_, url_, - url_loader_throttles_getter_, resource_context_, - request_context_getter_, this); + throttling_profile_id_, response, std::move(loader_), + client_binding_.Unbind(), network_loader_factory_, + request_initiator_, url_, url_loader_throttles_getter_, + resource_context_, request_context_getter_, this); return; } forwarding_client_->OnReceiveResponse(response);
diff --git a/content/browser/loader/prefetch_url_loader.h b/content/browser/loader/prefetch_url_loader.h index 1fd8986..ef4ff33 100644 --- a/content/browser/loader/prefetch_url_loader.h +++ b/content/browser/loader/prefetch_url_loader.h
@@ -9,6 +9,8 @@ #include "base/callback.h" #include "base/macros.h" +#include "base/optional.h" +#include "base/unguessable_token.h" #include "content/common/content_export.h" #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/system/data_pipe_drainer.h" @@ -94,6 +96,7 @@ const GURL url_; const bool report_raw_headers_; const int load_flags_; + const base::Optional<base::UnguessableToken> throttling_profile_id_; scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory_;
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc index 61bcb6cb..faeae257 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -111,6 +111,7 @@ #include "services/network/public/cpp/url_loader_completion_status.h" #include "services/network/public/mojom/request_context_frame_type.mojom.h" #include "services/network/resource_scheduler.h" +#include "services/network/throttling/scoped_throttling_token.h" #include "services/network/url_loader_factory.h" #include "storage/browser/blob/blob_data_handle.h" #include "storage/browser/blob/blob_storage_context.h" @@ -965,6 +966,11 @@ new_request->SetExtraRequestHeaders(headers); + std::unique_ptr<network::ScopedThrottlingToken> throttling_token = + network::ScopedThrottlingToken::MaybeCreate( + new_request->net_log().source().id, + request_data.throttling_profile_id); + blob_context = GetBlobStorageContext(requester_info->blob_storage_context()); // Resolve elements from request_body and prepare upload data. if (request_data.request_body.get()) { @@ -1103,7 +1109,8 @@ const bool is_initiated_by_fetch_api = request_data.fetch_request_context_type == REQUEST_CONTEXT_TYPE_FETCH; BeginRequestInternal(std::move(new_request), std::move(handler), - is_initiated_by_fetch_api); + is_initiated_by_fetch_api, + std::move(throttling_token)); } } @@ -1531,7 +1538,7 @@ ServiceWorkerNavigationHandleCore* service_worker_handle_core, AppCacheNavigationHandleCore* appcache_handle_core, uint32_t url_loader_options, - GlobalRequestID* global_request_id) { + const GlobalRequestID& global_request_id) { // PlzNavigate: BeginNavigationRequest currently should only be used for the // browser-side navigations project. CHECK(IsBrowserSideNavigationEnabled()); @@ -1589,6 +1596,10 @@ net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT); } + std::unique_ptr<network::ScopedThrottlingToken> throttling_token = + network::ScopedThrottlingToken::MaybeCreate( + new_request->net_log().source().id, info.devtools_frame_token); + Referrer::SetReferrerForRequest(new_request.get(), info.common_params.referrer); @@ -1645,7 +1656,7 @@ -1, // route_id info.frame_tree_node_id, ChildProcessHost::kInvalidUniqueID, // plugin_child_id - MakeRequestID(), + global_request_id.request_id, -1, // request_data.render_frame_id, info.is_main_frame, resource_type, info.common_params.transition, false, // is download @@ -1674,8 +1685,6 @@ // Request takes ownership. extra_info->AssociateWithRequest(new_request.get()); - *global_request_id = extra_info->GetGlobalRequestID(); - if (new_request->url().SchemeIs(url::kBlobScheme)) { // Hang on to a reference to ensure the blob is not released prior // to the job being started. @@ -1721,7 +1730,8 @@ RecordFetchRequestMode(new_request->url(), new_request->method(), network::mojom::FetchRequestMode::kNavigate); BeginRequestInternal(std::move(new_request), std::move(handler), - false /* is_initiated_by_fetch_api */); + false /* is_initiated_by_fetch_api */, + std::move(throttling_token)); } void ResourceDispatcherHostImpl::SetLoaderDelegate( @@ -1779,7 +1789,8 @@ void ResourceDispatcherHostImpl::BeginRequestInternal( std::unique_ptr<net::URLRequest> request, std::unique_ptr<ResourceHandler> handler, - bool is_initiated_by_fetch_api) { + bool is_initiated_by_fetch_api, + std::unique_ptr<network::ScopedThrottlingToken> throttling_token) { DCHECK(!request->is_pending()); ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request.get()); @@ -1855,8 +1866,9 @@ } ResourceContext* resource_context = info->GetContext(); - std::unique_ptr<ResourceLoader> loader(new ResourceLoader( - std::move(request), std::move(handler), this, resource_context)); + std::unique_ptr<ResourceLoader> loader( + new ResourceLoader(std::move(request), std::move(handler), this, + resource_context, std::move(throttling_token))); GlobalFrameRoutingId id(info->GetChildID(), info->GetRenderFrameID()); BlockedLoadersMap::const_iterator iter = blocked_loaders_map_.find(id); @@ -1926,7 +1938,8 @@ true /* force_download */, true /* is_new_request */); } BeginRequestInternal(std::move(request), std::move(handler), - false /* is_initiated_by_fetch_api */); + false /* is_initiated_by_fetch_api */, + nullptr /* throttling_token */); } int ResourceDispatcherHostImpl::MakeRequestID() { @@ -1934,6 +1947,10 @@ return --request_id_; } +GlobalRequestID ResourceDispatcherHostImpl::MakeGlobalRequestID() { + return GlobalRequestID(ChildProcessHost::kInvalidUniqueID, MakeRequestID()); +} + void ResourceDispatcherHostImpl::CancelRequestFromRenderer( GlobalRequestID request_id) { ResourceLoader* loader = GetLoader(request_id);
diff --git a/content/browser/loader/resource_dispatcher_host_impl.h b/content/browser/loader/resource_dispatcher_host_impl.h index 97d5cae..afc6eb7 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.h +++ b/content/browser/loader/resource_dispatcher_host_impl.h
@@ -58,6 +58,7 @@ namespace network { class ResourceScheduler; +class ScopedThrottlingToken; } // namespace network namespace storage { @@ -229,9 +230,8 @@ void FinishedWithResourcesForRequest(net::URLRequest* request); // PlzNavigate: Begins a request for NavigationURLLoader. |loader| is the - // loader to attach to the leaf resource handler. - // After calling this function, |global_request_id| will contains the - // request's global id. + // loader to attach to the leaf resource handler. |global_request_id| needs to + // be created by MakeGlobalRequestID() before calling this method. void BeginNavigationRequest( ResourceContext* resource_context, net::URLRequestContext* request_context, @@ -243,7 +243,7 @@ ServiceWorkerNavigationHandleCore* service_worker_handle_core, AppCacheNavigationHandleCore* appcache_handle_core, uint32_t url_loader_options, - GlobalRequestID* global_request_id); + const GlobalRequestID& global_request_id); int num_in_flight_requests_for_testing() const { return num_in_flight_requests_; @@ -300,6 +300,11 @@ // of |request_id_| for the details. Must be called on the IO thread. int MakeRequestID(); + // Creates a new global request ID for browser initiated requests. The ID + // is consistent with the request id created by MakeRequestID(). Must be + // called on the IO thread. + GlobalRequestID MakeGlobalRequestID(); + // Cancels a request as requested by a renderer. This function is called when // a mojo connection is lost. // Note that this cancel is subtly different from the other CancelRequest @@ -409,9 +414,11 @@ void OnShutdown(); // Helper function for URL requests. - void BeginRequestInternal(std::unique_ptr<net::URLRequest> request, - std::unique_ptr<ResourceHandler> handler, - bool is_initiated_by_fetch_api); + void BeginRequestInternal( + std::unique_ptr<net::URLRequest> request, + std::unique_ptr<ResourceHandler> handler, + bool is_initiated_by_fetch_api, + std::unique_ptr<network::ScopedThrottlingToken> throttling_token); void StartLoading(ResourceRequestInfoImpl* info, std::unique_ptr<ResourceLoader> loader);
diff --git a/content/browser/loader/resource_dispatcher_host_unittest.cc b/content/browser/loader/resource_dispatcher_host_unittest.cc index 46322f6..d8d744e 100644 --- a/content/browser/loader/resource_dispatcher_host_unittest.cc +++ b/content/browser/loader/resource_dispatcher_host_unittest.cc
@@ -819,6 +819,7 @@ new NavigationRequestInfo(common_params, std::move(begin_params), url, true, false, false, -1, false, false, false, false, nullptr, + base::UnguessableToken::Create(), base::UnguessableToken::Create())); std::unique_ptr<NavigationURLLoader> test_loader = NavigationURLLoader::Create(
diff --git a/content/browser/loader/resource_loader.cc b/content/browser/loader/resource_loader.cc index 4f6ba78..41150370 100644 --- a/content/browser/loader/resource_loader.cc +++ b/content/browser/loader/resource_loader.cc
@@ -43,6 +43,7 @@ #include "net/url_request/url_request_status.h" #include "services/network/loader_util.h" #include "services/network/public/cpp/resource_response.h" +#include "services/network/throttling/scoped_throttling_token.h" #include "url/url_constants.h" using base::TimeDelta; @@ -221,10 +222,12 @@ DISALLOW_COPY_AND_ASSIGN(ScopedDeferral); }; -ResourceLoader::ResourceLoader(std::unique_ptr<net::URLRequest> request, - std::unique_ptr<ResourceHandler> handler, - ResourceLoaderDelegate* delegate, - ResourceContext* resource_context) +ResourceLoader::ResourceLoader( + std::unique_ptr<net::URLRequest> request, + std::unique_ptr<ResourceHandler> handler, + ResourceLoaderDelegate* delegate, + ResourceContext* resource_context, + std::unique_ptr<network::ScopedThrottlingToken> throttling_token) : deferred_stage_(DEFERRED_NONE), request_(std::move(request)), handler_(std::move(handler)), @@ -233,6 +236,7 @@ started_request_(false), times_cancelled_after_request_start_(0), resource_context_(resource_context), + throttling_token_(std::move(throttling_token)), weak_ptr_factory_(this) { request_->set_delegate(this); handler_->SetDelegate(this);
diff --git a/content/browser/loader/resource_loader.h b/content/browser/loader/resource_loader.h index 93ea0021..3830cd4 100644 --- a/content/browser/loader/resource_loader.h +++ b/content/browser/loader/resource_loader.h
@@ -25,6 +25,10 @@ class X509Certificate; } +namespace network { +class ScopedThrottlingToken; +} + namespace content { class LoginDelegate; class ResourceHandler; @@ -39,10 +43,12 @@ public SSLClientAuthHandler::Delegate, public ResourceHandler::Delegate { public: - ResourceLoader(std::unique_ptr<net::URLRequest> request, - std::unique_ptr<ResourceHandler> handler, - ResourceLoaderDelegate* delegate, - ResourceContext* resource_context); + ResourceLoader( + std::unique_ptr<net::URLRequest> request, + std::unique_ptr<ResourceHandler> handler, + ResourceLoaderDelegate* delegate, + ResourceContext* resource_context, + std::unique_ptr<network::ScopedThrottlingToken> throttling_token); ~ResourceLoader() override; void StartRequest(); @@ -177,6 +183,8 @@ ResourceContext* resource_context_; + std::unique_ptr<network::ScopedThrottlingToken> throttling_token_; + bool should_pause_reading_body_ = false; // The request is not deferred (i.e., DEFERRED_NONE) and is ready to read more // response body data. However, reading is paused because of
diff --git a/content/browser/loader/resource_loader_unittest.cc b/content/browser/loader/resource_loader_unittest.cc index 469e35d2..aeae17a 100644 --- a/content/browser/loader/resource_loader_unittest.cc +++ b/content/browser/loader/resource_loader_unittest.cc
@@ -59,6 +59,7 @@ #include "net/url_request/url_request_test_job.h" #include "net/url_request/url_request_test_util.h" #include "services/network/public/cpp/resource_response.h" +#include "services/network/throttling/scoped_throttling_token.h" #include "testing/gtest/include/gtest/gtest.h" namespace content { @@ -453,7 +454,7 @@ loader_.reset(new ResourceLoader( std::move(request), WrapResourceHandler(std::move(resource_handler), raw_ptr_to_request_), - this, &resource_context_)); + this, &resource_context_, nullptr /* throttling_token */)); } void SetUpResourceLoaderForUrl(const GURL& test_url) {
diff --git a/content/browser/picture_in_picture/overlay_surface_embedder.cc b/content/browser/picture_in_picture/overlay_surface_embedder.cc index 08c18f1..a10fe651 100644 --- a/content/browser/picture_in_picture/overlay_surface_embedder.cc +++ b/content/browser/picture_in_picture/overlay_surface_embedder.cc
@@ -30,6 +30,7 @@ void OverlaySurfaceEmbedder::SetPrimarySurfaceId( const viz::SurfaceId& surface_id) { + video_layer_ = window_->GetVideoLayer(); // SurfaceInfo has information about the embedded surface. video_layer_->SetShowPrimarySurface( surface_id, window_->GetBounds().size(), SK_ColorBLACK, @@ -39,13 +40,17 @@ void OverlaySurfaceEmbedder::UpdateLayerBounds() { // Update the size and position of the video to stretch on the entire window. + video_layer_ = window_->GetVideoLayer(); video_layer_->SetBounds(window_->GetVideoBounds()); video_layer_->SetSurfaceSize(window_->GetVideoBounds().size()); // Update the size and position of controls. + controls_background_layer_ = window_->GetControlsBackgroundLayer(); controls_background_layer_->SetBounds( gfx::Rect(gfx::Point(0, 0), window_->GetBounds().size())); + close_controls_layer_ = window_->GetCloseControlsLayer(); close_controls_layer_->SetBounds(window_->GetCloseControlsBounds()); + play_pause_controls_layer_ = window_->GetPlayPauseControlsLayer(); play_pause_controls_layer_->SetBounds(window_->GetPlayPauseControlsBounds()); }
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.cc b/content/browser/service_worker/service_worker_fetch_dispatcher.cc index f6fe9fec..83b88a0 100644 --- a/content/browser/service_worker/service_worker_fetch_dispatcher.cc +++ b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
@@ -40,6 +40,7 @@ #include "net/log/net_log_event_type.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_request.h" +#include "services/network/throttling/throttling_controller.h" namespace content { @@ -720,6 +721,9 @@ request.is_main_frame = original_info->IsMainFrame(); request.enable_load_timing = original_info->is_load_timing_enabled(); request.report_raw_headers = original_info->ShouldReportRawHeaders(); + request.throttling_profile_id = + network::ThrottlingController::GetProfileIDForNetLogSource( + original_request->net_log().source().id); DCHECK(net::HttpUtil::IsValidHeaderValue( version_->navigation_preload_state().header));
diff --git a/content/browser/web_package/signed_exchange_cert_fetcher.cc b/content/browser/web_package/signed_exchange_cert_fetcher.cc index 20e9c54..90dd7610 100644 --- a/content/browser/web_package/signed_exchange_cert_fetcher.cc +++ b/content/browser/web_package/signed_exchange_cert_fetcher.cc
@@ -72,14 +72,15 @@ bool force_fetch, SignedExchangeVersion version, CertificateCallback callback, - SignedExchangeDevToolsProxy* devtools_proxy) { + SignedExchangeDevToolsProxy* devtools_proxy, + const base::Optional<base::UnguessableToken>& throttling_profile_id) { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"), "SignedExchangeCertFetcher::CreateAndStart"); std::unique_ptr<SignedExchangeCertFetcher> cert_fetcher( new SignedExchangeCertFetcher( std::move(shared_url_loader_factory), std::move(throttles), cert_url, std::move(request_initiator), force_fetch, version, - std::move(callback), devtools_proxy)); + std::move(callback), devtools_proxy, throttling_profile_id)); cert_fetcher->Start(); return cert_fetcher; } @@ -92,7 +93,8 @@ bool force_fetch, SignedExchangeVersion version, CertificateCallback callback, - SignedExchangeDevToolsProxy* devtools_proxy) + SignedExchangeDevToolsProxy* devtools_proxy, + const base::Optional<base::UnguessableToken>& throttling_profile_id) : shared_url_loader_factory_(std::move(shared_url_loader_factory)), throttles_(std::move(throttles)), resource_request_(std::make_unique<network::ResourceRequest>()), @@ -117,6 +119,7 @@ cert_request_id_ = base::UnguessableToken::Create(); resource_request_->enable_load_timing = true; } + resource_request_->throttling_profile_id = throttling_profile_id; } SignedExchangeCertFetcher::~SignedExchangeCertFetcher() = default;
diff --git a/content/browser/web_package/signed_exchange_cert_fetcher.h b/content/browser/web_package/signed_exchange_cert_fetcher.h index c3f6835..679ed5f 100644 --- a/content/browser/web_package/signed_exchange_cert_fetcher.h +++ b/content/browser/web_package/signed_exchange_cert_fetcher.h
@@ -54,7 +54,8 @@ bool force_fetch, SignedExchangeVersion version, CertificateCallback callback, - SignedExchangeDevToolsProxy* devtools_proxy); + SignedExchangeDevToolsProxy* devtools_proxy, + const base::Optional<base::UnguessableToken>& throttling_profile_id); ~SignedExchangeCertFetcher() override; @@ -76,7 +77,8 @@ bool force_fetch, SignedExchangeVersion version, CertificateCallback callback, - SignedExchangeDevToolsProxy* devtools_proxy); + SignedExchangeDevToolsProxy* devtools_proxy, + const base::Optional<base::UnguessableToken>& throttling_profile_id); void Start(); void Abort(); void OnHandleReady(MojoResult result);
diff --git a/content/browser/web_package/signed_exchange_cert_fetcher_factory.cc b/content/browser/web_package/signed_exchange_cert_fetcher_factory.cc index 2023480..7cff4e9 100644 --- a/content/browser/web_package/signed_exchange_cert_fetcher_factory.cc +++ b/content/browser/web_package/signed_exchange_cert_fetcher_factory.cc
@@ -4,6 +4,7 @@ #include "content/browser/web_package/signed_exchange_cert_fetcher_factory.h" +#include "base/unguessable_token.h" #include "content/public/common/url_loader_throttle.h" #include "services/network/public/cpp/shared_url_loader_factory.h" @@ -17,10 +18,12 @@ SignedExchangeCertFetcherFactoryImpl( url::Origin request_initiator, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - URLLoaderThrottlesGetter url_loader_throttles_getter) + URLLoaderThrottlesGetter url_loader_throttles_getter, + const base::Optional<base::UnguessableToken>& throttling_profile_id) : request_initiator_(std::move(request_initiator)), url_loader_factory_(std::move(url_loader_factory)), - url_loader_throttles_getter_(std::move(url_loader_throttles_getter)) {} + url_loader_throttles_getter_(std::move(url_loader_throttles_getter)), + throttling_profile_id_(throttling_profile_id) {} std::unique_ptr<SignedExchangeCertFetcher> CreateFetcherAndStart( const GURL& cert_url, @@ -33,6 +36,7 @@ url::Origin request_initiator_; scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; URLLoaderThrottlesGetter url_loader_throttles_getter_; + const base::Optional<base::UnguessableToken> throttling_profile_id_; }; std::unique_ptr<SignedExchangeCertFetcher> @@ -49,7 +53,7 @@ return SignedExchangeCertFetcher::CreateAndStart( std::move(url_loader_factory_), std::move(throttles), cert_url, std::move(request_initiator_), force_fetch, version, std::move(callback), - devtools_proxy); + devtools_proxy, throttling_profile_id_); } // static @@ -57,10 +61,11 @@ SignedExchangeCertFetcherFactory::Create( url::Origin request_initiator, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - URLLoaderThrottlesGetter url_loader_throttles_getter) { + URLLoaderThrottlesGetter url_loader_throttles_getter, + const base::Optional<base::UnguessableToken>& throttling_profile_id) { return std::make_unique<SignedExchangeCertFetcherFactoryImpl>( std::move(request_initiator), std::move(url_loader_factory), - std::move(url_loader_throttles_getter)); + std::move(url_loader_throttles_getter), throttling_profile_id); } } // namespace content
diff --git a/content/browser/web_package/signed_exchange_cert_fetcher_factory.h b/content/browser/web_package/signed_exchange_cert_fetcher_factory.h index dc01c1c..94133457 100644 --- a/content/browser/web_package/signed_exchange_cert_fetcher_factory.h +++ b/content/browser/web_package/signed_exchange_cert_fetcher_factory.h
@@ -9,6 +9,8 @@ #include <vector> #include "base/callback_forward.h" +#include "base/optional.h" +#include "base/unguessable_token.h" #include "content/browser/web_package/signed_exchange_cert_fetcher.h" #include "content/common/content_export.h" #include "url/origin.h" @@ -41,7 +43,8 @@ static std::unique_ptr<SignedExchangeCertFetcherFactory> Create( url::Origin request_initiator, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - URLLoaderThrottlesGetter url_loader_throttles_getter); + URLLoaderThrottlesGetter url_loader_throttles_getter, + const base::Optional<base::UnguessableToken>& throttling_profile_id); }; } // namespace content
diff --git a/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc b/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc index e27b26b..8be2dd02 100644 --- a/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc +++ b/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc
@@ -212,7 +212,8 @@ &mock_loader_factory_), std::move(throttles_), url, request_initiator_, force_fetch, SignedExchangeVersion::kB1, std::move(callback), - nullptr /* devtools_proxy */); + nullptr /* devtools_proxy */, + base::nullopt /* throttling_profile_id */); } void CallOnReceiveResponse() {
diff --git a/content/browser/web_package/signed_exchange_loader.cc b/content/browser/web_package/signed_exchange_loader.cc index af85f82..9ede996 100644 --- a/content/browser/web_package/signed_exchange_loader.cc +++ b/content/browser/web_package/signed_exchange_loader.cc
@@ -87,6 +87,7 @@ url::Origin request_initiator, uint32_t url_loader_options, int load_flags, + const base::Optional<base::UnguessableToken>& throttling_profile_id, std::unique_ptr<SignedExchangeDevToolsProxy> devtools_proxy, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, URLLoaderThrottlesGetter url_loader_throttles_getter, @@ -99,6 +100,7 @@ request_initiator_(request_initiator), url_loader_options_(url_loader_options), load_flags_(load_flags), + throttling_profile_id_(throttling_profile_id), devtools_proxy_(std::move(devtools_proxy)), url_loader_factory_(std::move(url_loader_factory)), url_loader_throttles_getter_(std::move(url_loader_throttles_getter)), @@ -211,7 +213,7 @@ mojo::ScopedDataPipeConsumerHandle body) { auto cert_fetcher_factory = SignedExchangeCertFetcherFactory::Create( std::move(request_initiator_), std::move(url_loader_factory_), - std::move(url_loader_throttles_getter_)); + std::move(url_loader_throttles_getter_), throttling_profile_id_); if (g_signed_exchange_factory_for_testing_) { signed_exchange_handler_ = g_signed_exchange_factory_for_testing_->Create(
diff --git a/content/browser/web_package/signed_exchange_loader.h b/content/browser/web_package/signed_exchange_loader.h index 10394cf..2ab0d3a 100644 --- a/content/browser/web_package/signed_exchange_loader.h +++ b/content/browser/web_package/signed_exchange_loader.h
@@ -53,6 +53,7 @@ url::Origin request_initiator, uint32_t url_loader_options, int load_flags, + const base::Optional<base::UnguessableToken>& throttling_profile_id, std::unique_ptr<SignedExchangeDevToolsProxy> devtools_proxy, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, URLLoaderThrottlesGetter url_loader_throttles_getter, @@ -136,6 +137,7 @@ url::Origin request_initiator_; const uint32_t url_loader_options_; const int load_flags_; + const base::Optional<base::UnguessableToken> throttling_profile_id_; std::unique_ptr<SignedExchangeDevToolsProxy> devtools_proxy_; scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; URLLoaderThrottlesGetter url_loader_throttles_getter_;
diff --git a/content/browser/web_package/signed_exchange_prefetch_handler.cc b/content/browser/web_package/signed_exchange_prefetch_handler.cc index 2eb57ee..c28252b 100644 --- a/content/browser/web_package/signed_exchange_prefetch_handler.cc +++ b/content/browser/web_package/signed_exchange_prefetch_handler.cc
@@ -22,6 +22,7 @@ base::RepeatingCallback<int(void)> frame_tree_node_id_getter, bool report_raw_headers, int load_flags, + const base::Optional<base::UnguessableToken>& throttling_profile_id, const network::ResourceResponseHead& response, network::mojom::URLLoaderPtr network_loader, network::mojom::URLLoaderClientRequest network_client_request, @@ -50,7 +51,7 @@ signed_exchange_loader_ = std::make_unique<SignedExchangeLoader>( outer_request_url, response, std::move(client), std::move(endpoints), std::move(request_initiator), network::mojom::kURLLoadOptionNone, - load_flags, + load_flags, throttling_profile_id, std::make_unique<SignedExchangeDevToolsProxy>( outer_request_url, response, std::move(frame_tree_node_id_getter), base::nullopt /* devtools_navigation_token */, report_raw_headers),
diff --git a/content/browser/web_package/signed_exchange_prefetch_handler.h b/content/browser/web_package/signed_exchange_prefetch_handler.h index 976f481..0c3551f 100644 --- a/content/browser/web_package/signed_exchange_prefetch_handler.h +++ b/content/browser/web_package/signed_exchange_prefetch_handler.h
@@ -7,6 +7,8 @@ #include "base/callback_forward.h" #include "base/macros.h" +#include "base/optional.h" +#include "base/unguessable_token.h" #include "mojo/public/cpp/bindings/binding.h" #include "services/network/public/mojom/url_loader.mojom.h" @@ -39,6 +41,7 @@ base::RepeatingCallback<int(void)> frame_tree_node_id_getter, bool report_raw_headers, int load_flags, + const base::Optional<base::UnguessableToken>& throttling_profile_id, const network::ResourceResponseHead& response, network::mojom::URLLoaderPtr network_loader, network::mojom::URLLoaderClientRequest network_client_request,
diff --git a/content/browser/web_package/signed_exchange_request_handler.cc b/content/browser/web_package/signed_exchange_request_handler.cc index 8ef25782..e5d33126 100644 --- a/content/browser/web_package/signed_exchange_request_handler.cc +++ b/content/browser/web_package/signed_exchange_request_handler.cc
@@ -35,6 +35,7 @@ uint32_t url_loader_options, int frame_tree_node_id, const base::UnguessableToken& devtools_navigation_token, + const base::Optional<base::UnguessableToken>& throttling_profile_id, bool report_raw_headers, int load_flags, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, @@ -45,6 +46,7 @@ url_loader_options_(url_loader_options), frame_tree_node_id_(frame_tree_node_id), devtools_navigation_token_(devtools_navigation_token), + throttling_profile_id_(throttling_profile_id), report_raw_headers_(report_raw_headers), load_flags_(load_flags), url_loader_factory_(url_loader_factory), @@ -93,6 +95,7 @@ signed_exchange_loader_ = std::make_unique<SignedExchangeLoader>( url_, response, std::move(client), url_loader->Unbind(), std::move(request_initiator_), url_loader_options_, load_flags_, + throttling_profile_id_, std::make_unique<SignedExchangeDevToolsProxy>( url_, response, base::BindRepeating([](int id) { return id; }, frame_tree_node_id_),
diff --git a/content/browser/web_package/signed_exchange_request_handler.h b/content/browser/web_package/signed_exchange_request_handler.h index a9cf1a3..02fbd7a 100644 --- a/content/browser/web_package/signed_exchange_request_handler.h +++ b/content/browser/web_package/signed_exchange_request_handler.h
@@ -6,6 +6,7 @@ #define CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_REQUEST_HANDLER_H_ #include "base/memory/weak_ptr.h" +#include "base/optional.h" #include "base/unguessable_token.h" #include "content/browser/loader/navigation_loader_interceptor.h" #include "content/public/common/resource_type.h" @@ -37,6 +38,7 @@ uint32_t url_loader_options, int frame_tree_node_id, const base::UnguessableToken& devtools_navigation_token, + const base::Optional<base::UnguessableToken>& throttling_profile_id, bool report_raw_headers, int load_flags, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, @@ -68,6 +70,7 @@ const uint32_t url_loader_options_; const int frame_tree_node_id_; base::Optional<const base::UnguessableToken> devtools_navigation_token_; + const base::Optional<base::UnguessableToken> throttling_profile_id_; const bool report_raw_headers_; const int load_flags_; scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index c474bf28..35a3f90 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -36,6 +36,10 @@ const base::Feature kAudioServiceAudioStreams{ "AudioServiceAudioStreams", base::FEATURE_DISABLED_BY_DEFAULT}; +// Launches the audio service on the browser startup. +const base::Feature kAudioServiceLaunchOnStartup{ + "AudioServiceLaunchOnStartup", base::FEATURE_DISABLED_BY_DEFAULT}; + // Runs the audio service in a separate process. const base::Feature kAudioServiceOutOfProcess{ "AudioServiceOutOfProcess", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index 0412fd3..f4a38dd4 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -22,6 +22,7 @@ CONTENT_EXPORT extern const base::Feature kAsmJsToWebAssembly; CONTENT_EXPORT extern const base::Feature kAsyncWheelEvents; CONTENT_EXPORT extern const base::Feature kAudioServiceAudioStreams; +CONTENT_EXPORT extern const base::Feature kAudioServiceLaunchOnStartup; CONTENT_EXPORT extern const base::Feature kAudioServiceOutOfProcess; CONTENT_EXPORT extern const base::Feature kBlinkHeapIncrementalMarking; CONTENT_EXPORT extern const base::Feature kBlockCredentialedSubresources;
diff --git a/content/public/renderer/render_frame_observer.h b/content/public/renderer/render_frame_observer.h index 74a031a..d52332f 100644 --- a/content/public/renderer/render_frame_observer.h +++ b/content/public/renderer/render_frame_observer.h
@@ -30,6 +30,11 @@ class WebWorkerFetchContext; } +namespace network { +struct ResourceResponseHead; +struct URLLoaderCompletionStatus; +} // namespace network + namespace content { class RendererPpapiHost; @@ -123,6 +128,24 @@ virtual void DidObserveNewCssPropertyUsage(int css_property, bool is_animated) {} + // Notification when the renderer a response started, completed or canceled. + // Complete or Cancel is guaranteed to be called for a response that started. + // |request_id| uniquely identifies the request within this render frame. + virtual void DidStartResponse( + int request_id, + const network::ResourceResponseHead& response_head) {} + virtual void DidCompleteResponse( + int request_id, + const network::URLLoaderCompletionStatus& status) {} + virtual void DidCancelResponse(int request_id) {} + + // Notification when the renderer observes data used during the page load. + // This is used for page load metrics. |received_data_length| is the received + // network bytes. |resource_id| uniquely identifies the resource within this + // render frame. + virtual void DidReceiveTransferSizeUpdate(int resource_id, + int received_data_length) {} + // Called when the focused node has changed to |node|. virtual void FocusedNodeChanged(const blink::WebNode& node) {}
diff --git a/content/renderer/loader/resource_dispatcher.cc b/content/renderer/loader/resource_dispatcher.cc index c698849..846cb4c5 100644 --- a/content/renderer/loader/resource_dispatcher.cc +++ b/content/renderer/loader/resource_dispatcher.cc
@@ -96,18 +96,18 @@ render_frame->GetFrameHost()->SubresourceResponseStarted(url, cert_status); } -void NotifyResourceLoadComplete( +void NotifyResourceLoadStarted( scoped_refptr<base::SingleThreadTaskRunner> thread_task_runner, int render_frame_id, - mojom::ResourceLoadInfoPtr resource_load_info) { + int request_id, + const network::ResourceResponseHead& response_head) { if (!thread_task_runner) return; if (!thread_task_runner->BelongsToCurrentThread()) { thread_task_runner->PostTask( - FROM_HERE, - base::BindOnce(NotifyResourceLoadComplete, thread_task_runner, - render_frame_id, std::move(resource_load_info))); + FROM_HERE, base::BindOnce(NotifyResourceLoadStarted, thread_task_runner, + render_frame_id, request_id, response_head)); return; } @@ -116,10 +116,81 @@ if (!render_frame) return; + render_frame->DidStartResponse(request_id, response_head); +} + +void NotifyResourceLoadComplete( + scoped_refptr<base::SingleThreadTaskRunner> thread_task_runner, + int render_frame_id, + mojom::ResourceLoadInfoPtr resource_load_info, + const network::URLLoaderCompletionStatus& status) { + if (!thread_task_runner) + return; + + if (!thread_task_runner->BelongsToCurrentThread()) { + thread_task_runner->PostTask( + FROM_HERE, + base::BindOnce(NotifyResourceLoadComplete, thread_task_runner, + render_frame_id, std::move(resource_load_info), status)); + return; + } + + RenderFrameImpl* render_frame = + RenderFrameImpl::FromRoutingID(render_frame_id); + if (!render_frame) + return; + + render_frame->DidCompleteResponse(resource_load_info->request_id, status); render_frame->GetFrameHost()->ResourceLoadComplete( std::move(resource_load_info)); } +void NotifyResourceLoadCancel( + scoped_refptr<base::SingleThreadTaskRunner> thread_task_runner, + int render_frame_id, + int request_id) { + if (!thread_task_runner) + return; + + if (!thread_task_runner->BelongsToCurrentThread()) { + thread_task_runner->PostTask( + FROM_HERE, base::BindOnce(NotifyResourceLoadCancel, thread_task_runner, + render_frame_id, request_id)); + return; + } + + RenderFrameImpl* render_frame = + RenderFrameImpl::FromRoutingID(render_frame_id); + if (!render_frame) + return; + + render_frame->DidCancelResponse(request_id); +} + +void NotifyResourceTransferSizeUpdate( + scoped_refptr<base::SingleThreadTaskRunner> thread_task_runner, + int render_frame_id, + int request_id, + int transfer_size_diff) { + if (!thread_task_runner) + return; + + if (!thread_task_runner->BelongsToCurrentThread()) { + thread_task_runner->PostTask( + FROM_HERE, + base::BindOnce(NotifyResourceTransferSizeUpdate, thread_task_runner, + render_frame_id, request_id, transfer_size_diff)); + return; + } + + RenderFrameImpl* render_frame = + RenderFrameImpl::FromRoutingID(render_frame_id); + if (!render_frame) + return; + + render_frame->DidReceiveTransferSizeUpdate(request_id, transfer_size_diff); +} + // Returns true if the headers indicate that this resource should always be // revalidated or not cached. bool AlwaysAccessNetwork( @@ -232,6 +303,14 @@ } request_info->peer->OnReceivedResponse(renderer_response_info); + + // Make a deep copy of ResourceResponseHead before passing it cross-thread. + auto resource_response = base::MakeRefCounted<network::ResourceResponse>(); + resource_response->head = response_head; + auto deep_copied_response = resource_response->DeepCopy(); + NotifyResourceLoadStarted(RenderThreadImpl::DeprecatedGetMainTaskRunner(), + request_info->render_frame_id, request_id, + deep_copied_response->head); } void ResourceDispatcher::OnReceivedCachedMetadata( @@ -322,6 +401,7 @@ return; request_info->buffer.reset(); request_info->buffer_size = 0; + request_info->did_request_complete = true; auto resource_load_info = mojom::ResourceLoadInfo::New(); resource_load_info->url = request_info->response_url; @@ -347,7 +427,7 @@ NotifyResourceLoadComplete(RenderThreadImpl::DeprecatedGetMainTaskRunner(), request_info->render_frame_id, - std::move(resource_load_info)); + std::move(resource_load_info), status); RequestPeer* peer = request_info->peer.get(); @@ -397,6 +477,11 @@ if (it == pending_requests_.end()) return false; + if (!it->second->did_request_complete) { + NotifyResourceLoadCancel(RenderThreadImpl::DeprecatedGetMainTaskRunner(), + it->second->render_frame_id, request_id); + } + // Cancel loading. it->second->url_loader = nullptr; // Clear URLLoaderClient to stop receiving further Mojo IPC from the browser @@ -465,6 +550,10 @@ // TODO(yhirano): Consider using int64_t in // RequestPeer::OnTransferSizeUpdated. request_info->peer->OnTransferSizeUpdated(transfer_size_diff); + + NotifyResourceTransferSizeUpdate( + RenderThreadImpl::DeprecatedGetMainTaskRunner(), + request_info->render_frame_id, request_id, transfer_size_diff); } ResourceDispatcher::PendingRequestInfo::PendingRequestInfo(
diff --git a/content/renderer/loader/resource_dispatcher.h b/content/renderer/loader/resource_dispatcher.h index 402c913..a5c1ba4 100644 --- a/content/renderer/loader/resource_dispatcher.h +++ b/content/renderer/loader/resource_dispatcher.h
@@ -214,6 +214,7 @@ navigation_response_override; bool should_follow_redirect = true; bool always_access_network = false; + bool did_request_complete = false; std::vector<content::mojom::RedirectInfoPtr> redirect_info_chain;
diff --git a/content/renderer/loader/web_url_loader_impl.cc b/content/renderer/loader/web_url_loader_impl.cc index 22b83b2..2c6ac5b 100644 --- a/content/renderer/loader/web_url_loader_impl.cc +++ b/content/renderer/loader/web_url_loader_impl.cc
@@ -709,6 +709,7 @@ resource_request->report_raw_headers = request.ReportRawHeaders(); resource_request->previews_state = static_cast<int>(request.GetPreviewsState()); + resource_request->throttling_profile_id = request.GetDevToolsToken(); // The network request has already been made by the browser. The renderer // should bind the URLLoaderClientEndpoints stored in |response_override| to
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 9f54a39..bd60a21 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -3984,11 +3984,6 @@ navigation_start)); } -void RenderFrameImpl::DidReceiveServerRedirectForProvisionalLoad() { - // TODO(creis): Determine if this can be removed or if we need to clear any - // local state here to fix https://crbug.com/671276. -} - void RenderFrameImpl::DidFailProvisionalLoad( const WebURLError& error, blink::WebHistoryCommitType commit_type) { @@ -4821,6 +4816,32 @@ response.MimeType().Utf8(), WebURLRequestToResourceType(request))); } +void RenderFrameImpl::DidStartResponse( + int request_id, + const network::ResourceResponseHead& response_head) { + for (auto& observer : observers_) + observer.DidStartResponse(request_id, response_head); +} + +void RenderFrameImpl::DidCompleteResponse( + int request_id, + const network::URLLoaderCompletionStatus& status) { + for (auto& observer : observers_) + observer.DidCompleteResponse(request_id, status); +} + +void RenderFrameImpl::DidCancelResponse(int request_id) { + for (auto& observer : observers_) + observer.DidCancelResponse(request_id); +} + +void RenderFrameImpl::DidReceiveTransferSizeUpdate(int resource_id, + int received_data_length) { + for (auto& observer : observers_) { + observer.DidReceiveTransferSizeUpdate(resource_id, received_data_length); + } +} + void RenderFrameImpl::DidDisplayInsecureContent() { Send(new FrameHostMsg_DidDisplayInsecureContent(routing_id_)); }
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index a0402af1..64606449 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -630,7 +630,6 @@ blink::WebDocumentLoader* document_loader) override; void DidStartProvisionalLoad(blink::WebDocumentLoader* document_loader, blink::WebURLRequest& request) override; - void DidReceiveServerRedirectForProvisionalLoad() override; void DidFailProvisionalLoad(const blink::WebURLError& error, blink::WebHistoryCommitType commit_type) override; void DidCommitProvisionalLoad( @@ -877,6 +876,13 @@ // browser. void OnDroppedNavigation(); + void DidStartResponse(int request_id, + const network::ResourceResponseHead& response_head); + void DidCompleteResponse(int request_id, + const network::URLLoaderCompletionStatus& status); + void DidCancelResponse(int request_id); + void DidReceiveTransferSizeUpdate(int request_id, int received_data_length); + protected: explicit RenderFrameImpl(CreateParams params);
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 896f89a..7160fae 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -1259,12 +1259,6 @@ if (!command_line.HasSwitch(switches::kDisableThreadedCompositing)) InitializeCompositorThread(); - scoped_refptr<base::SingleThreadTaskRunner> compositor_impl_side_task_runner; - if (compositor_task_runner_) - compositor_impl_side_task_runner = compositor_task_runner_; - else - compositor_impl_side_task_runner = base::ThreadTaskRunnerHandle::Get(); - RenderThreadImpl::RegisterSchemes(); RenderMediaClient::Initialize();
diff --git a/content/renderer/web_database_observer_impl.cc b/content/renderer/web_database_observer_impl.cc index 087cf47..76426679 100644 --- a/content/renderer/web_database_observer_impl.cc +++ b/content/renderer/web_database_observer_impl.cc
@@ -99,17 +99,15 @@ int callsite, int websql_error, int sqlite_error, - double call_time) { + base::TimeDelta call_time) { UMA_HISTOGRAM_WEBSQL_RESULT("OpenResult", callsite, websql_error, sqlite_error); HandleSqliteError(origin, database_name, sqlite_error); if (websql_error == kWebSQLSuccess && sqlite_error == SQLITE_OK) { - UMA_HISTOGRAM_TIMES("websql.Async.OpenTime.Success", - base::TimeDelta::FromSecondsD(call_time)); + UMA_HISTOGRAM_TIMES("websql.Async.OpenTime.Success", call_time); } else { - UMA_HISTOGRAM_TIMES("websql.Async.OpenTime.Error", - base::TimeDelta::FromSecondsD(call_time)); + UMA_HISTOGRAM_TIMES("websql.Async.OpenTime.Error", call_time); } }
diff --git a/content/renderer/web_database_observer_impl.h b/content/renderer/web_database_observer_impl.h index df5c4c1..629f126 100644 --- a/content/renderer/web_database_observer_impl.h +++ b/content/renderer/web_database_observer_impl.h
@@ -37,7 +37,7 @@ int callsite, int websql_error, int sqlite_error, - double call_time) override; + base::TimeDelta call_time) override; void ReportChangeVersionResult(const blink::WebSecurityOrigin& origin, const blink::WebString& database_name, int callsite,
diff --git a/content/shell/test_runner/web_frame_test_client.cc b/content/shell/test_runner/web_frame_test_client.cc index 5b96e37..3a3d3f0 100644 --- a/content/shell/test_runner/web_frame_test_client.cc +++ b/content/shell/test_runner/web_frame_test_client.cc
@@ -407,14 +407,6 @@ } } -void WebFrameTestClient::DidReceiveServerRedirectForProvisionalLoad() { - if (test_runner()->shouldDumpFrameLoadCallbacks()) { - PrintFrameDescription(delegate_, web_frame_test_proxy_base_->web_frame()); - delegate_->PrintMessage( - " - didReceiveServerRedirectForProvisionalLoadForFrame\n"); - } -} - void WebFrameTestClient::DidFailProvisionalLoad( const blink::WebURLError& error, blink::WebHistoryCommitType commit_type) {
diff --git a/content/shell/test_runner/web_frame_test_client.h b/content/shell/test_runner/web_frame_test_client.h index 1f25338..9226f0a 100644 --- a/content/shell/test_runner/web_frame_test_client.h +++ b/content/shell/test_runner/web_frame_test_client.h
@@ -56,7 +56,6 @@ void LoadErrorPage(int reason) override; void DidStartProvisionalLoad(blink::WebDocumentLoader* loader, blink::WebURLRequest& request) override; - void DidReceiveServerRedirectForProvisionalLoad() override; void DidFailProvisionalLoad(const blink::WebURLError& error, blink::WebHistoryCommitType commit_type) override; void DidCommitProvisionalLoad(const blink::WebHistoryItem& history_item,
diff --git a/content/shell/test_runner/web_frame_test_proxy.h b/content/shell/test_runner/web_frame_test_proxy.h index c0f83a7..637926a 100644 --- a/content/shell/test_runner/web_frame_test_proxy.h +++ b/content/shell/test_runner/web_frame_test_proxy.h
@@ -91,11 +91,6 @@ Base::DidStartProvisionalLoad(document_loader, request); } - void DidReceiveServerRedirectForProvisionalLoad() override { - test_client()->DidReceiveServerRedirectForProvisionalLoad(); - Base::DidReceiveServerRedirectForProvisionalLoad(); - } - void DidFailProvisionalLoad( const blink::WebURLError& error, blink::WebHistoryCommitType commit_type) override {
diff --git a/device/BUILD.gn b/device/BUILD.gn index 1b20a89..f643626 100644 --- a/device/BUILD.gn +++ b/device/BUILD.gn
@@ -113,6 +113,7 @@ "//device/gamepad/public/cpp:shared_with_blink", "//device/gamepad/public/mojom", "//device/gamepad/public/mojom:gamepad_mojom_traits_test", + "//device/geolocation:unittests", "//mojo/edk", "//mojo/public/cpp/bindings", "//net",
diff --git a/device/geolocation/BUILD.gn b/device/geolocation/BUILD.gn index 2750b89..b321a72 100644 --- a/device/geolocation/BUILD.gn +++ b/device/geolocation/BUILD.gn
@@ -150,3 +150,52 @@ "//testing/gtest", ] } + +source_set("unittests") { + testonly = true + + sources = [ + "geolocation_provider_impl_unittest.cc", + "location_arbitrator_unittest.cc", + "network_location_provider_unittest.cc", + "wifi_data_provider_chromeos_unittest.cc", + "wifi_data_provider_common_unittest.cc", + "wifi_data_provider_linux_unittest.cc", + "wifi_data_provider_win_unittest.cc", + "wifi_polling_policy_unittest.cc", + ] + public_deps = [ + ":geolocation", + ] + deps = [ + ":test_support", + "//base", + "//base/third_party/dynamic_annotations", + "//device/geolocation/public/cpp", + "//net:test_support", + "//services/device/public/mojom", + "//testing/gmock", + "//testing/gtest", + ] + + if (is_linux) { + if (use_dbus) { + deps += [ "//dbus:test_support" ] + } else { + sources -= [ "wifi_data_provider_linux_unittest.cc" ] + } + } + + if (is_chromeos) { + sources -= [ "wifi_data_provider_linux_unittest.cc" ] + deps += [ "//chromeos" ] + } + + if (is_android) { + sources -= [ + "network_location_provider_unittest.cc", + "wifi_data_provider_common_unittest.cc", + ] + deps += [ "//device/geolocation/public/java:geolocation_java_test_support" ] + } +}
diff --git a/services/device/geolocation/geolocation_provider_impl_unittest.cc b/device/geolocation/geolocation_provider_impl_unittest.cc similarity index 100% rename from services/device/geolocation/geolocation_provider_impl_unittest.cc rename to device/geolocation/geolocation_provider_impl_unittest.cc
diff --git a/services/device/geolocation/location_arbitrator_unittest.cc b/device/geolocation/location_arbitrator_unittest.cc similarity index 99% rename from services/device/geolocation/location_arbitrator_unittest.cc rename to device/geolocation/location_arbitrator_unittest.cc index b708234..ff9bcd4 100644 --- a/services/device/geolocation/location_arbitrator_unittest.cc +++ b/device/geolocation/location_arbitrator_unittest.cc
@@ -77,17 +77,6 @@ SetPositionFix(provider, 51.0, -0.1, 400); } -// Simple request context producer that immediately produces a -// TestURLRequestContextGetter. -void TestRequestContextProducer( - const scoped_refptr<base::SingleThreadTaskRunner>& network_task_runner, - base::OnceCallback<void(scoped_refptr<net::URLRequestContextGetter>)> - response_callback) { - std::move(response_callback) - .Run(base::MakeRefCounted<net::TestURLRequestContextGetter>( - network_task_runner)); -} - } // namespace // Simple request context producer that immediately produces a nullptr @@ -100,6 +89,17 @@ .Run(scoped_refptr<net::URLRequestContextGetter>(nullptr)); } +// Simple request context producer that immediately produces a +// TestURLRequestContextGetter. +void TestRequestContextProducer( + const scoped_refptr<base::SingleThreadTaskRunner>& network_task_runner, + base::OnceCallback<void(scoped_refptr<net::URLRequestContextGetter>)> + response_callback) { + std::move(response_callback) + .Run(base::MakeRefCounted<net::TestURLRequestContextGetter>( + network_task_runner)); +} + class TestingLocationArbitrator : public LocationArbitrator { public: TestingLocationArbitrator(
diff --git a/services/device/geolocation/network_location_provider_unittest.cc b/device/geolocation/network_location_provider_unittest.cc similarity index 98% rename from services/device/geolocation/network_location_provider_unittest.cc rename to device/geolocation/network_location_provider_unittest.cc index c9d26dc..8162d02 100644 --- a/services/device/geolocation/network_location_provider_unittest.cc +++ b/device/geolocation/network_location_provider_unittest.cc
@@ -229,13 +229,13 @@ const base::Value* expected_value; const base::Value* actual_value; if (!expected.Get(field, &expected_value)) - return testing::AssertionFailure() - << "Expected dictionary " << PrettyJson(expected) - << " is missing field " << field; + return testing::AssertionFailure() << "Expected dictionary " + << PrettyJson(expected) + << " is missing field " << field; if (!expected.Get(field, &actual_value)) - return testing::AssertionFailure() - << "Actual dictionary " << PrettyJson(actual) - << " is missing field " << field; + return testing::AssertionFailure() << "Actual dictionary " + << PrettyJson(actual) + << " is missing field " << field; if (!expected_value->Equals(actual_value)) return testing::AssertionFailure() << "Field " << field
diff --git a/services/device/geolocation/wifi_data_provider_chromeos_unittest.cc b/device/geolocation/wifi_data_provider_chromeos_unittest.cc similarity index 100% rename from services/device/geolocation/wifi_data_provider_chromeos_unittest.cc rename to device/geolocation/wifi_data_provider_chromeos_unittest.cc
diff --git a/services/device/geolocation/wifi_data_provider_common_unittest.cc b/device/geolocation/wifi_data_provider_common_unittest.cc similarity index 100% rename from services/device/geolocation/wifi_data_provider_common_unittest.cc rename to device/geolocation/wifi_data_provider_common_unittest.cc
diff --git a/services/device/geolocation/wifi_data_provider_linux_unittest.cc b/device/geolocation/wifi_data_provider_linux_unittest.cc similarity index 98% rename from services/device/geolocation/wifi_data_provider_linux_unittest.cc rename to device/geolocation/wifi_data_provider_linux_unittest.cc index 64591629..b4fb94b4 100644 --- a/services/device/geolocation/wifi_data_provider_linux_unittest.cc +++ b/device/geolocation/wifi_data_provider_linux_unittest.cc
@@ -41,7 +41,8 @@ // Set an expectation so mock_network_manager_proxy_'s // CallMethodAndBlock() will use CreateNetworkManagerProxyResponse() // to return responses. - EXPECT_CALL(*mock_network_manager_proxy_.get(), CallMethodAndBlock(_, _)) + EXPECT_CALL(*mock_network_manager_proxy_.get(), + CallMethodAndBlock(_, _)) .WillRepeatedly(Invoke(this, &GeolocationWifiDataProviderLinuxTest:: CreateNetworkManagerProxyResponse));
diff --git a/services/device/geolocation/wifi_data_provider_win_unittest.cc b/device/geolocation/wifi_data_provider_win_unittest.cc similarity index 99% rename from services/device/geolocation/wifi_data_provider_win_unittest.cc rename to device/geolocation/wifi_data_provider_win_unittest.cc index 7f4c83e..102401a 100644 --- a/services/device/geolocation/wifi_data_provider_win_unittest.cc +++ b/device/geolocation/wifi_data_provider_win_unittest.cc
@@ -5,8 +5,8 @@ // Most logic for the platform wifi provider is now factored into // WifiDataProviderCommon and covered by it's unit tests. -#include "device/geolocation/wifi_data_provider_win.h" #include "base/message_loop/message_loop.h" +#include "device/geolocation/wifi_data_provider_win.h" #include "testing/gtest/include/gtest/gtest.h" namespace device {
diff --git a/services/device/geolocation/wifi_polling_policy_unittest.cc b/device/geolocation/wifi_polling_policy_unittest.cc similarity index 100% rename from services/device/geolocation/wifi_polling_policy_unittest.cc rename to device/geolocation/wifi_polling_policy_unittest.cc
diff --git a/docs/speed/benchmark/harnesses/loading.md b/docs/speed/benchmark/harnesses/loading.md new file mode 100644 index 0000000..2c24b04 --- /dev/null +++ b/docs/speed/benchmark/harnesses/loading.md
@@ -0,0 +1,101 @@ +# Loading benchmarks + +[TOC] + +## Overview + +The Telemetry loading benchmarks measure Chrome's loading performance under +different network and caching conditions. + +There are currently three loading benchmarks: + +- **`loading.desktop`**: A desktop-only benchmark in which each test case + measures performance of loading a real world website (e.g: facebook, cnn, + alibaba..). +- **`loading.mobile`**: A mobile-only benchmark that parallels `loading.desktop` +- **`loading.cluster_telemetry`**: A cluster Telemetry benchmark that uses the +corpus of top 10 thousands URLs from Alexa. Unlike the other two loading +benchmarks which are run continuously on the perf waterfall, this benchmark is +triggered on-demand only. + +# Running the tests remotely + +If you're just trying to gauge whether your change has caused a loading +regression, you can either run `loading.desktop` and `loading.mobile` through +[perf try job](https://chromium.googlesource.com/chromium/src/+/master/docs/speed/perf_trybots.md) or you can run `loading.cluster_telemetry` through +[Cluster Telemetry service](https://ct.skia.org/) (Cluster Telemetry is for +Googler only). + +## Running the tests locally + +For more in-depth analysis and shorter cycle times, it can be helpful to run the tests locally. + +First, [prepare your test device for +Telemetry](https://chromium.googlesource.com/chromium/src/+/master/docs/speed/benchmark/telemetry_device_setup.md). + +Once you've done this, you can start the Telemetry benchmark with: + +``` +./tools/perf/run_benchmark <benchmark_name> --browser=<browser> +``` + +where `benchmark_name` can be `loading.desktop` or `loading.mobile`. + +## Understanding the loading test cases + +The loading test cases are divided into groups based on their network traffic +settings and cache conditions. + +All available traffic settings can be found in [traffic_setting.py](https://chromium.googlesource.com/catapult/+/master/telemetry/telemetry/page/traffic_setting.py) + +All available caching conditions can be found in [cache_temperature.py](https://chromium.googlesource.com/catapult/+/master/telemetry/telemetry/page/cache_temperature.py) + +Test cases of `loading.desktop` and `loading.mobile` are named with their +corresponding settings. For example, `DevOpera_cold_3g` test case loads +`https://dev.opera.com/` with cold cache and 3G network setting. + +In additions, the pages are also tagged with labels describing their content. +e.g: 'global', 'pwa',... + +To run only pages of one tags, add `--story-tag-filter=<tag name>` flag to the +run benchmark command. + +## Understanding the loading metrics +The benchmark output several different loading metrics. The keys one are: + * [Time To First Contentful Paint](https://docs.google.com/document/d/1kKGZO3qlBBVOSZTf-T8BOMETzk3bY15SC-jsMJWv4IE/edit#heading=h.27igk2kctj7o) + * [Time To First Meaningful Paint](https://docs.google.com/document/d/1BR94tJdZLsin5poeet0XoTW60M0SjvOJQttKT-JK8HI/edit) + * [Time to First CPU + Idle](https://docs.google.com/document/d/12UHgAW2r7nWo3R6FBerpYuz9EVOdG1OpPm8YmY4yD0c/edit#) + +Besides those key metrics, there are also breakdown metrics that are meant to +to make debugging regressions simpler. These metrics are updated often, for most +up to date information, you can email progressive-web-metrics@chromium.org +or chrome-speed-metrics@google.com (Googlers only). + +## Adding new loading test cases +New test cases can be added by modifying +[loading_desktop.py](https://chromium.googlesource.com/chromium/src/+/master/tools/perf/page_sets/loading_desktop.py) +or [loading_mobile.py](https://chromium.googlesource.com/chromium/src/+/master/tools/perf/page_sets/loading_mobile.py) page sets. + +For example, to add a new case of loading +`https://en.wikipedia.org/wiki/Cats_and_the_Internet` on 2G and 3G networks with +warm cache to `news` group to `loading.desktop` benchmark, you would write: + +``` +self.AddStories( + tags=['news'], + urls=[('https://en.wikipedia.org/wiki/Cats_and_the_Internet', 'wiki_cats')], + cache_temperatures=[cache_temperature_module.WARM], + traffic_settings=[traffic_setting_module.2G, traffic_setting_module.3G]) +``` + +After adding the new page, record it and upload the page archive to cloud +storage with: + +``` +$ ./tools/perf/record_wpr loading_desktop --browser=system \ + --story-filter=wiki_cats --upload +``` + +If the extra story was added to `loading.mobile`, replace `loading_desktop` in +the command above with `loading_mobile`.
diff --git a/headless/lib/browser/headless_network_delegate.cc b/headless/lib/browser/headless_network_delegate.cc index be12174..b19e715 100644 --- a/headless/lib/browser/headless_network_delegate.cc +++ b/headless/lib/browser/headless_network_delegate.cc
@@ -15,13 +15,6 @@ namespace headless { -namespace { -// Keep in sync with X_DevTools_Emulate_Network_Conditions_Client_Id defined in -// HTTPNames.json5. -const char kDevToolsEmulateNetworkConditionsClientId[] = - "X-DevTools-Emulate-Network-Conditions-Client-Id"; -} // namespace - HeadlessNetworkDelegate::HeadlessNetworkDelegate( HeadlessBrowserContextImpl* headless_browser_context) : headless_browser_context_(headless_browser_context) { @@ -40,12 +33,6 @@ net::URLRequest* request, net::CompletionOnceCallback callback, GURL* new_url) { - base::AutoLock lock(lock_); - if (headless_browser_context_ && - headless_browser_context_->ShouldRemoveHeaders()) { - request->RemoveRequestHeaderByName( - kDevToolsEmulateNetworkConditionsClientId); - } return net::OK; }
diff --git a/headless/lib/browser/headless_web_contents_impl.cc b/headless/lib/browser/headless_web_contents_impl.cc index b5e473a..2e1a0b9 100644 --- a/headless/lib/browser/headless_web_contents_impl.cc +++ b/headless/lib/browser/headless_web_contents_impl.cc
@@ -95,7 +95,7 @@ auto* const headless_contents = HeadlessWebContentsImpl::From(browser(), source); DCHECK(headless_contents); - headless_contents->Close(); + headless_contents->DelegateRequestsClose(); } void AddNewContents(content::WebContents* source, @@ -379,9 +379,29 @@ void HeadlessWebContentsImpl::Close() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + if (quit_closure_) + return; + + if (!render_process_exited_) { + web_contents_->ClosePage(); + base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); + quit_closure_ = run_loop.QuitClosure(); + run_loop.Run(); + } + browser_context()->DestroyWebContents(this); } +void HeadlessWebContentsImpl::DelegateRequestsClose() { + if (quit_closure_) { + quit_closure_.Run(); + quit_closure_ = base::Closure(); + } else { + browser_context()->DestroyWebContents(this); + } +} + std::string HeadlessWebContentsImpl::GetDevToolsAgentHostId() { return agent_host_->GetId(); }
diff --git a/headless/lib/browser/headless_web_contents_impl.h b/headless/lib/browser/headless_web_contents_impl.h index 7a0bb87..7a010ee 100644 --- a/headless/lib/browser/headless_web_contents_impl.h +++ b/headless/lib/browser/headless_web_contents_impl.h
@@ -99,6 +99,8 @@ void Close() override; + void DelegateRequestsClose(); + std::string GetDevToolsAgentHostId(); HeadlessBrowserImpl* browser() const; @@ -176,6 +178,8 @@ base::ObserverList<HeadlessWebContents::Observer> observers_; + base::Closure quit_closure_; + base::WeakPtrFactory<HeadlessWebContentsImpl> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(HeadlessWebContentsImpl);
diff --git a/headless/lib/headless_devtools_client_browsertest.cc b/headless/lib/headless_devtools_client_browsertest.cc index 152aa78..a564ab1 100644 --- a/headless/lib/headless_devtools_client_browsertest.cc +++ b/headless/lib/headless_devtools_client_browsertest.cc
@@ -1119,51 +1119,6 @@ HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessDevToolsNetworkBlockedUrlTest); -namespace { -// Keep in sync with X_DevTools_Emulate_Network_Conditions_Client_Id defined in -// HTTPNames.json5. -const char kDevToolsEmulateNetworkConditionsClientId[] = - "X-DevTools-Emulate-Network-Conditions-Client-Id"; -} // namespace - -class DevToolsHeaderStrippingTest : public HeadlessAsyncDevTooledBrowserTest, - public page::Observer, - public network::Observer { - void RunDevTooledTest() override { - EXPECT_TRUE(embedded_test_server()->Start()); - base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); - devtools_client_->GetPage()->AddObserver(this); - devtools_client_->GetPage()->Enable(); - // Enable network domain in order to get DevTools to add the header. - devtools_client_->GetNetwork()->AddObserver(this); - devtools_client_->GetNetwork()->Enable(run_loop.QuitClosure()); - run_loop.Run(); - devtools_client_->GetPage()->Navigate( - "http://not-an-actual-domain.tld/hello.html"); - } - - ProtocolHandlerMap GetProtocolHandlers() override { - const std::string kResponseBody = "<p>HTTP response body</p>"; - ProtocolHandlerMap protocol_handlers; - protocol_handlers[url::kHttpScheme] = - std::make_unique<TestProtocolHandler>(kResponseBody); - test_handler_ = static_cast<TestProtocolHandler*>( - protocol_handlers[url::kHttpScheme].get()); - return protocol_handlers; - } - - void OnLoadEventFired(const page::LoadEventFiredParams&) override { - EXPECT_FALSE(test_handler_->last_http_request_headers().IsEmpty()); - EXPECT_FALSE(test_handler_->last_http_request_headers().HasHeader( - kDevToolsEmulateNetworkConditionsClientId)); - FinishAsynchronousTest(); - } - - TestProtocolHandler* test_handler_; // NOT OWNED -}; - -HEADLESS_ASYNC_DEVTOOLED_TEST_F(DevToolsHeaderStrippingTest); - class DevToolsNetworkOfflineEmulationTest : public HeadlessAsyncDevTooledBrowserTest, public page::Observer,
diff --git a/ios/chrome/browser/DEPS b/ios/chrome/browser/DEPS index 4162955..631c02e 100644 --- a/ios/chrome/browser/DEPS +++ b/ios/chrome/browser/DEPS
@@ -70,6 +70,7 @@ "+components/ssl_errors", "+components/suggestions", "+components/sync", + "+components/sync_bookmarks", "+components/sync_sessions", "+components/sync_preferences", "+components/task_scheduler_util",
diff --git a/ios/chrome/browser/bookmarks/BUILD.gn b/ios/chrome/browser/bookmarks/BUILD.gn index 253908fe..60ec8d9 100644 --- a/ios/chrome/browser/bookmarks/BUILD.gn +++ b/ios/chrome/browser/bookmarks/BUILD.gn
@@ -8,6 +8,8 @@ "bookmark_client_impl.h", "bookmark_model_factory.cc", "bookmark_model_factory.h", + "bookmark_sync_service_factory.cc", + "bookmark_sync_service_factory.h", "startup_task_runner_service_factory.cc", "startup_task_runner_service_factory.h", ] @@ -20,6 +22,7 @@ "//components/keyed_service/core", "//components/keyed_service/ios", "//components/prefs", + "//components/sync_bookmarks", "//components/undo", "//ios/chrome/browser", "//ios/chrome/browser/browser_state",
diff --git a/ios/chrome/browser/bookmarks/bookmark_client_impl.cc b/ios/chrome/browser/bookmarks/bookmark_client_impl.cc index 1f85bb7..e551e0b 100644 --- a/ios/chrome/browser/bookmarks/bookmark_client_impl.cc +++ b/ios/chrome/browser/bookmarks/bookmark_client_impl.cc
@@ -14,14 +14,22 @@ #include "components/history/core/browser/history_service.h" #include "components/history/core/browser/url_database.h" #include "components/keyed_service/core/service_access_type.h" +#include "components/sync_bookmarks/bookmark_sync_service.h" #include "ios/chrome/browser/favicon/favicon_service_factory.h" #include "ios/chrome/browser/history/history_service_factory.h" -BookmarkClientImpl::BookmarkClientImpl(ios::ChromeBrowserState* browser_state) - : browser_state_(browser_state) {} +BookmarkClientImpl::BookmarkClientImpl( + ios::ChromeBrowserState* browser_state, + sync_bookmarks::BookmarkSyncService* bookmark_sync_service) + : browser_state_(browser_state), + bookmark_sync_service_(bookmark_sync_service) {} BookmarkClientImpl::~BookmarkClientImpl() {} +void BookmarkClientImpl::Init(bookmarks::BookmarkModel* model) { + model_ = model; +} + bool BookmarkClientImpl::PreferTouchIcon() { return true; } @@ -89,3 +97,14 @@ const bookmarks::BookmarkNode* node) { return true; } + +std::string BookmarkClientImpl::EncodeBookmarkSyncMetadata() { + return bookmark_sync_service_->EncodeBookmarkSyncMetadata(); +} + +void BookmarkClientImpl::DecodeBookmarkSyncMetadata( + const std::string& metadata_str, + const base::RepeatingClosure& schedule_save_closure) { + bookmark_sync_service_->DecodeBookmarkSyncMetadata( + metadata_str, schedule_save_closure, model_); +}
diff --git a/ios/chrome/browser/bookmarks/bookmark_client_impl.h b/ios/chrome/browser/bookmarks/bookmark_client_impl.h index 44a32d5..170b78d 100644 --- a/ios/chrome/browser/bookmarks/bookmark_client_impl.h +++ b/ios/chrome/browser/bookmarks/bookmark_client_impl.h
@@ -15,20 +15,28 @@ class GURL; namespace bookmarks { +class BookmarkModel; class BookmarkNode; class BookmarkPermanentNode; } +namespace sync_bookmarks { +class BookmarkSyncService; +} + namespace ios { class ChromeBrowserState; } class BookmarkClientImpl : public bookmarks::BookmarkClient { public: - BookmarkClientImpl(ios::ChromeBrowserState* browser_state); + BookmarkClientImpl( + ios::ChromeBrowserState* browser_state, + sync_bookmarks::BookmarkSyncService* bookmark_sync_service); ~BookmarkClientImpl() override; // bookmarks::BookmarkClient: + void Init(bookmarks::BookmarkModel* model) override; bool PreferTouchIcon() override; base::CancelableTaskTracker::TaskId GetFaviconImageForPageURL( const GURL& page_url, @@ -45,12 +53,22 @@ const bookmarks::BookmarkNode* permanent_node) override; bool CanSyncNode(const bookmarks::BookmarkNode* node) override; bool CanBeEditedByUser(const bookmarks::BookmarkNode* node) override; + std::string EncodeBookmarkSyncMetadata() override; + void DecodeBookmarkSyncMetadata( + const std::string& metadata_str, + const base::RepeatingClosure& schedule_save_closure) override; private: // Pointer to the associated ios::ChromeBrowserState. Must outlive // BookmarkClientImpl. ios::ChromeBrowserState* browser_state_; + bookmarks::BookmarkModel* model_; + + // Pointer to the BookmarkSyncService responsible for encoding and decoding + // sync metadata persisted together with the bookmarks model. + sync_bookmarks::BookmarkSyncService* bookmark_sync_service_; + DISALLOW_COPY_AND_ASSIGN(BookmarkClientImpl); };
diff --git a/ios/chrome/browser/bookmarks/bookmark_model_factory.cc b/ios/chrome/browser/bookmarks/bookmark_model_factory.cc index 18af3b5..ad34214 100644 --- a/ios/chrome/browser/bookmarks/bookmark_model_factory.cc +++ b/ios/chrome/browser/bookmarks/bookmark_model_factory.cc
@@ -5,7 +5,6 @@ #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" #include <utility> - #include "base/memory/singleton.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/browser/bookmark_utils.h" @@ -14,6 +13,7 @@ #include "components/prefs/pref_service.h" #include "components/undo/bookmark_undo_service.h" #include "ios/chrome/browser/bookmarks/bookmark_client_impl.h" +#include "ios/chrome/browser/bookmarks/bookmark_sync_service_factory.h" #include "ios/chrome/browser/bookmarks/startup_task_runner_service_factory.h" #include "ios/chrome/browser/browser_state/browser_state_otr_helper.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" @@ -62,8 +62,9 @@ ios::ChromeBrowserState* browser_state = ios::ChromeBrowserState::FromBrowserState(context); std::unique_ptr<bookmarks::BookmarkModel> bookmark_model( - new bookmarks::BookmarkModel( - std::make_unique<BookmarkClientImpl>(browser_state))); + new bookmarks::BookmarkModel(std::make_unique<BookmarkClientImpl>( + browser_state, + ios::BookmarkSyncServiceFactory::GetForBrowserState(browser_state)))); bookmark_model->Load( browser_state->GetPrefs(), browser_state->GetStatePath(),
diff --git a/ios/chrome/browser/bookmarks/bookmark_sync_service_factory.cc b/ios/chrome/browser/bookmarks/bookmark_sync_service_factory.cc new file mode 100644 index 0000000..ed02486 --- /dev/null +++ b/ios/chrome/browser/bookmarks/bookmark_sync_service_factory.cc
@@ -0,0 +1,53 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ios/chrome/browser/bookmarks/bookmark_sync_service_factory.h" + +#include "components/keyed_service/ios/browser_state_dependency_manager.h" +#include "components/sync_bookmarks/bookmark_sync_service.h" +#include "ios/chrome/browser/browser_state/browser_state_otr_helper.h" +#include "ios/chrome/browser/browser_state/chrome_browser_state.h" +#include "ios/chrome/browser/undo/bookmark_undo_service_factory.h" + +namespace ios { + +// static +sync_bookmarks::BookmarkSyncService* +BookmarkSyncServiceFactory::GetForBrowserState( + ios::ChromeBrowserState* browser_state) { + return static_cast<sync_bookmarks::BookmarkSyncService*>( + GetInstance()->GetServiceForBrowserState(browser_state, true)); +} + +// static +BookmarkSyncServiceFactory* BookmarkSyncServiceFactory::GetInstance() { + return base::Singleton<BookmarkSyncServiceFactory>::get(); +} + +BookmarkSyncServiceFactory::BookmarkSyncServiceFactory() + : BrowserStateKeyedServiceFactory( + "BookmarkSyncServiceFactory", + BrowserStateDependencyManager::GetInstance()) { + DependsOn(ios::BookmarkUndoServiceFactory::GetInstance()); +} + +BookmarkSyncServiceFactory::~BookmarkSyncServiceFactory() {} + +std::unique_ptr<KeyedService> +BookmarkSyncServiceFactory::BuildServiceInstanceFor( + web::BrowserState* context) const { + ios::ChromeBrowserState* browser_state = + ios::ChromeBrowserState::FromBrowserState(context); + std::unique_ptr<sync_bookmarks::BookmarkSyncService> bookmark_sync_service( + new sync_bookmarks::BookmarkSyncService( + BookmarkUndoServiceFactory::GetForBrowserState(browser_state))); + return bookmark_sync_service; +} + +web::BrowserState* BookmarkSyncServiceFactory::GetBrowserStateToUse( + web::BrowserState* context) const { + return GetBrowserStateRedirectedInIncognito(context); +} + +} // namespace ios
diff --git a/ios/chrome/browser/bookmarks/bookmark_sync_service_factory.h b/ios/chrome/browser/bookmarks/bookmark_sync_service_factory.h new file mode 100644 index 0000000..984d8f1 --- /dev/null +++ b/ios/chrome/browser/bookmarks/bookmark_sync_service_factory.h
@@ -0,0 +1,52 @@ +// Copyright 2018 The Chromium 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_BOOKMARKS_BOOKMARK_SYNC_SERVICE_FACTORY_H_ +#define IOS_CHROME_BROWSER_BOOKMARKS_BOOKMARK_SYNC_SERVICE_FACTORY_H_ + +#include "base/memory/singleton.h" +#include "components/keyed_service/ios/browser_state_keyed_service_factory.h" + +namespace base { +template <typename T> +struct DefaultSingletonTraits; +} // namespace base + +namespace sync_bookmarks { +class BookmarkSyncService; +} + +namespace ios { + +class ChromeBrowserState; + +// Singleton that owns the bookmark sync service. +class BookmarkSyncServiceFactory : public BrowserStateKeyedServiceFactory { + public: + // Returns the instance of BookmarkSyncService associated with this profile + // (creating one if none exists). + static sync_bookmarks::BookmarkSyncService* GetForBrowserState( + ios::ChromeBrowserState* browser_state); + + // Returns an instance of the BookmarkSyncServiceFactory singleton. + static BookmarkSyncServiceFactory* GetInstance(); + + private: + friend struct base::DefaultSingletonTraits<BookmarkSyncServiceFactory>; + + BookmarkSyncServiceFactory(); + ~BookmarkSyncServiceFactory() override; + + // BrowserStateKeyedServiceFactory implementation. + std::unique_ptr<KeyedService> BuildServiceInstanceFor( + web::BrowserState* context) const override; + web::BrowserState* GetBrowserStateToUse( + web::BrowserState* context) const override; + + DISALLOW_COPY_AND_ASSIGN(BookmarkSyncServiceFactory); +}; + +} // namespace ios + +#endif // IOS_CHROME_BROWSER_BOOKMARKS_BOOKMARK_SYNC_SERVICE_FACTORY_H_
diff --git a/ios/chrome/browser/browser_state/BUILD.gn b/ios/chrome/browser/browser_state/BUILD.gn index a131220..a713dd5 100644 --- a/ios/chrome/browser/browser_state/BUILD.gn +++ b/ios/chrome/browser/browser_state/BUILD.gn
@@ -176,6 +176,7 @@ "//components/keyed_service/ios", "//components/sync_preferences", "//components/sync_preferences:test_support", + "//components/undo", "//components/user_prefs", "//components/webdata_services", "//ios/chrome/browser", @@ -186,6 +187,7 @@ "//ios/chrome/browser/prefs", "//ios/chrome/browser/prefs:browser_prefs", "//ios/chrome/browser/sync/glue", + "//ios/chrome/browser/undo", "//ios/chrome/test:test_support", "//ios/public/provider/chrome/browser", "//ios/public/provider/chrome/browser/ui",
diff --git a/ios/chrome/browser/browser_state/test_chrome_browser_state.mm b/ios/chrome/browser/browser_state/test_chrome_browser_state.mm index 8720238..2d1add7 100644 --- a/ios/chrome/browser/browser_state/test_chrome_browser_state.mm +++ b/ios/chrome/browser/browser_state/test_chrome_browser_state.mm
@@ -27,12 +27,14 @@ #include "components/keyed_service/ios/browser_state_dependency_manager.h" #include "components/sync_preferences/pref_service_syncable.h" #include "components/sync_preferences/testing_pref_service_syncable.h" +#include "components/undo/bookmark_undo_service.h" #include "components/user_prefs/user_prefs.h" #include "components/webdata_services/web_data_service_wrapper.h" #include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/autocomplete/in_memory_url_index_factory.h" #include "ios/chrome/browser/bookmarks/bookmark_client_impl.h" #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" +#include "ios/chrome/browser/bookmarks/bookmark_sync_service_factory.h" #include "ios/chrome/browser/browser_state/browser_state_keyed_service_factories.h" #include "ios/chrome/browser/history/history_client_impl.h" #include "ios/chrome/browser/history/history_service_factory.h" @@ -41,6 +43,7 @@ #include "ios/chrome/browser/prefs/browser_prefs.h" #include "ios/chrome/browser/prefs/ios_chrome_pref_service_factory.h" #include "ios/chrome/browser/sync/glue/sync_start_util.h" +#include "ios/chrome/browser/undo/bookmark_undo_service_factory.h" #include "ios/chrome/browser/web_data_service_factory.h" #include "ios/public/provider/chrome/browser/chrome_browser_provider.h" #include "ios/web/public/web_thread.h" @@ -64,12 +67,15 @@ ios::ChromeBrowserState* browser_state = ios::ChromeBrowserState::FromBrowserState(context); std::unique_ptr<bookmarks::BookmarkModel> bookmark_model( - new bookmarks::BookmarkModel( - std::make_unique<BookmarkClientImpl>(browser_state))); + new bookmarks::BookmarkModel(std::make_unique<BookmarkClientImpl>( + browser_state, + ios::BookmarkSyncServiceFactory::GetForBrowserState(browser_state)))); bookmark_model->Load( browser_state->GetPrefs(), browser_state->GetStatePath(), browser_state->GetIOTaskRunner(), web::WebThread::GetTaskRunnerForThread(web::WebThread::UI)); + ios::BookmarkUndoServiceFactory::GetForBrowserState(browser_state) + ->Start(bookmark_model.get()); return bookmark_model; }
diff --git a/ios/chrome/browser/metrics/ukm_egtest.mm b/ios/chrome/browser/metrics/ukm_egtest.mm index 66c5763..ee92393 100644 --- a/ios/chrome/browser/metrics/ukm_egtest.mm +++ b/ios/chrome/browser/metrics/ukm_egtest.mm
@@ -252,6 +252,13 @@ @implementation UKMTestCase +// Per crbug.com/853992, Entire test suite is failing regularly. ++ (NSArray*)testInvocations { + if (IsIPadIdiom()) + return @[]; + return [super testInvocations]; +} + + (void)setUp { [super setUp]; if (!base::FeatureList::IsEnabled(ukm::kUkmFeature)) {
diff --git a/ios/chrome/browser/ui/list_model/BUILD.gn b/ios/chrome/browser/ui/list_model/BUILD.gn index 47ec373..9b6260b 100644 --- a/ios/chrome/browser/ui/list_model/BUILD.gn +++ b/ios/chrome/browser/ui/list_model/BUILD.gn
@@ -21,6 +21,7 @@ testonly = true sources = [ "list_item_unittest.mm", + "list_model_collapse_unittest.mm", "list_model_unittest.mm", ] deps = [
diff --git a/ios/chrome/browser/ui/list_model/list_model.h b/ios/chrome/browser/ui/list_model/list_model.h index 274635a..93981a23 100644 --- a/ios/chrome/browser/ui/list_model/list_model.h +++ b/ios/chrome/browser/ui/list_model/list_model.h
@@ -9,6 +9,9 @@ @class ListItem; +// Key for saving collapsed state in the NSUserDefaults. +extern NSString* const kListModelCollapsedKey; + // Use these as the starting value for section identifier and item type enums. // These are provided to help not mix between indexPath's section/item and the // model section identifier / item type. @@ -184,6 +187,23 @@ // Returns the number of items in the given section. - (NSInteger)numberOfItemsInSection:(NSInteger)section; +#pragma mark Collapsing methods. + +// Sets an existing |sectionIdentifier| |collapsedKey| to be used when +// collapsing or expanding a section. |collapsedKey| is a unique identifier for +// each section that will be used for persisting information about the collapsed +// state of a section. A |collapsedKey| its only needed when +// collapsing/expanding sections. You can't collapse/expand any sections without +// a |collapsedKey|. +- (void)setSectionIdentifier:(NSInteger)sectionIdentifier + collapsedKey:(NSString*)collapsedKey; +// Sets the state of an existing |sectionIdentifier| to |collapsed|. A +// collapsedKey has to be previously set or this method will DCHECK(). +- (void)setSection:(NSInteger)sectionIdentifier collapsed:(BOOL)collapsed; +// Returns YES if |sectionIdentifier| is collapsed. If not collapsedKey has been +// set it will also return NO. +- (BOOL)sectionIsCollapsed:(NSInteger)sectionIdentifier; + @end #endif // IOS_CHROME_BROWSER_UI_LIST_MODEL_LIST_MODEL_H_
diff --git a/ios/chrome/browser/ui/list_model/list_model.mm b/ios/chrome/browser/ui/list_model/list_model.mm index d7bd8114..87ffbc3 100644 --- a/ios/chrome/browser/ui/list_model/list_model.mm +++ b/ios/chrome/browser/ui/list_model/list_model.mm
@@ -12,7 +12,10 @@ #error "This file requires ARC support." #endif +NSString* const kListModelCollapsedKey = @"ChromeListModelCollapsedSections"; + namespace { + typedef NSMutableArray<ListItem*> SectionItems; } @@ -26,6 +29,9 @@ // Maps from section identifier to header and footer. NSMutableDictionary<NSNumber*, ListItem*>* _headers; NSMutableDictionary<NSNumber*, ListItem*>* _footers; + + // Maps from collapsed keys to section identifier. + NSMutableDictionary<NSNumber*, NSString*>* _collapsedKeys; } - (instancetype)init { @@ -103,6 +109,7 @@ NSInteger section = [self sectionForSectionIdentifier:sectionIdentifier]; [_sectionIdentifiers removeObjectAtIndex:section]; [_sections removeObjectAtIndex:section]; + [_collapsedKeys removeObjectForKey:@(sectionIdentifier)]; } - (void)setHeader:(ListItem*)header @@ -285,10 +292,62 @@ - (NSInteger)numberOfItemsInSection:(NSInteger)section { DCHECK_LT(base::checked_cast<NSUInteger>(section), [_sections count]); + NSInteger sectionIdentifier = [self sectionIdentifierForSection:section]; + if ([self sectionIsCollapsed:sectionIdentifier]) + return 0; SectionItems* items = [_sections objectAtIndex:section]; return items.count; } +#pragma mark Collapsing methods. + +- (void)setSectionIdentifier:(NSInteger)sectionIdentifier + collapsedKey:(NSString*)collapsedKey { + // Check that the sectionIdentifier exists. + DCHECK([self hasSectionForSectionIdentifier:sectionIdentifier]); + // Check that the collapsedKey is not being used already. + DCHECK(![self.collapsedKeys allKeysForObject:collapsedKey].count); + [self.collapsedKeys setObject:collapsedKey forKey:@(sectionIdentifier)]; +} + +- (void)setSection:(NSInteger)sectionIdentifier collapsed:(BOOL)collapsed { + // TODO(crbug.com/419346): Store in the browser state preference instead of + // NSUserDefaults. + DCHECK([self hasSectionForSectionIdentifier:sectionIdentifier]); + NSString* sectionKey = [self.collapsedKeys objectForKey:@(sectionIdentifier)]; + DCHECK(sectionKey); + NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; + NSDictionary* collapsedSections = + [defaults dictionaryForKey:kListModelCollapsedKey]; + NSMutableDictionary* newCollapsedSection = + [NSMutableDictionary dictionaryWithDictionary:collapsedSections]; + NSNumber* value = [NSNumber numberWithBool:collapsed]; + [newCollapsedSection setValue:value forKey:sectionKey]; + [defaults setObject:newCollapsedSection forKey:kListModelCollapsedKey]; +} + +- (BOOL)sectionIsCollapsed:(NSInteger)sectionIdentifier { + // TODO(crbug.com/419346): Store in the profile's preference instead of the + // NSUserDefaults. + DCHECK([self hasSectionForSectionIdentifier:sectionIdentifier]); + NSString* sectionKey = [self.collapsedKeys objectForKey:@(sectionIdentifier)]; + if (!sectionKey) + return NO; + NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; + NSDictionary* collapsedSections = + [defaults dictionaryForKey:kListModelCollapsedKey]; + NSNumber* value = (NSNumber*)[collapsedSections valueForKey:sectionKey]; + return [value boolValue]; +} + +// |_collapsedKeys| lazy instantiation. +- (NSMutableDictionary*)collapsedKeys { + if (!_collapsedKeys) { + _collapsedKeys = [[NSMutableDictionary alloc] init]; + } + return _collapsedKeys; +} + #pragma mark Private methods // Returns the section for the given section identifier. If the section
diff --git a/ios/chrome/browser/ui/table_view/table_view_model_unittest.mm b/ios/chrome/browser/ui/list_model/list_model_collapse_unittest.mm similarity index 73% rename from ios/chrome/browser/ui/table_view/table_view_model_unittest.mm rename to ios/chrome/browser/ui/list_model/list_model_collapse_unittest.mm index c47109f..8196316a 100644 --- a/ios/chrome/browser/ui/table_view/table_view_model_unittest.mm +++ b/ios/chrome/browser/ui/list_model/list_model_collapse_unittest.mm
@@ -2,10 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/ui/table_view/table_view_model.h" +#import "ios/chrome/browser/ui/list_model/list_model.h" -#import "ios/chrome/browser/ui/table_view/cells/table_view_header_footer_item.h" -#import "ios/chrome/browser/ui/table_view/cells/table_view_item.h" +#import "ios/chrome/browser/ui/list_model/list_item.h" #include "testing/platform_test.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -23,62 +22,71 @@ ItemTypeFooBar = kItemTypeEnumZero, }; -class TableViewModelTest : public PlatformTest { +class ListModelCollapseTest : public PlatformTest { protected: - TableViewModelTest() { + ListModelCollapseTest() { // Need to clean up NSUserDefaults before and after each test. NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; - [defaults setObject:nil forKey:kTableViewModelCollapsedKey]; + [defaults setObject:nil forKey:kListModelCollapsedKey]; - model = [[TableViewModel alloc] init]; + model = [[ListModel alloc] init]; [model addSectionWithIdentifier:SectionIdentifierFoo]; [model setSectionIdentifier:SectionIdentifierFoo collapsedKey:@"FooKey"]; - TableViewHeaderFooterItem* header = - [[TableViewHeaderFooterItem alloc] initWithType:ItemTypeFooBar]; - TableViewItem* item = [[TableViewItem alloc] initWithType:ItemTypeFooBar]; + ListItem* header = [[ListItem alloc] initWithType:ItemTypeFooBar]; + ListItem* item = [[ListItem alloc] initWithType:ItemTypeFooBar]; [model setHeader:header forSectionWithIdentifier:SectionIdentifierFoo]; [model addItem:item toSectionWithIdentifier:SectionIdentifierFoo]; [model addSectionWithIdentifier:SectionIdentifierBar]; [model setSectionIdentifier:SectionIdentifierBar collapsedKey:@"BarKey"]; - header = [[TableViewHeaderFooterItem alloc] initWithType:ItemTypeFooBar]; - item = [[TableViewItem alloc] initWithType:ItemTypeFooBar]; + header = [[ListItem alloc] initWithType:ItemTypeFooBar]; [model setHeader:header forSectionWithIdentifier:SectionIdentifierBar]; + item = [[ListItem alloc] initWithType:ItemTypeFooBar]; + [model addItem:item toSectionWithIdentifier:SectionIdentifierBar]; + item = [[ListItem alloc] initWithType:ItemTypeFooBar]; [model addItem:item toSectionWithIdentifier:SectionIdentifierBar]; } - ~TableViewModelTest() override { + ~ListModelCollapseTest() override { NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; - [defaults setObject:nil forKey:kTableViewModelCollapsedKey]; + [defaults setObject:nil forKey:kListModelCollapsedKey]; } - TableViewModel* model; + ListModel* model; }; // Tests the default collapsed value is NO. -TEST_F(TableViewModelTest, DefaultCollapsedSectionValue) { +TEST_F(ListModelCollapseTest, DefaultCollapsedSectionValue) { EXPECT_FALSE([model sectionIsCollapsed:SectionIdentifierFoo]); EXPECT_FALSE([model sectionIsCollapsed:SectionIdentifierBar]); } // Collapses all sections. -TEST_F(TableViewModelTest, SetAllCollapsed) { +TEST_F(ListModelCollapseTest, SetAllCollapsed) { [model setSection:SectionIdentifierFoo collapsed:YES]; [model setSection:SectionIdentifierBar collapsed:YES]; + // SectionIdentifierFoo + EXPECT_EQ(0, [model numberOfItemsInSection:0]); EXPECT_TRUE([model sectionIsCollapsed:SectionIdentifierFoo]); + // SectionIdentifierBar + EXPECT_EQ(0, [model numberOfItemsInSection:1]); EXPECT_TRUE([model sectionIsCollapsed:SectionIdentifierBar]); [model setSection:SectionIdentifierFoo collapsed:NO]; [model setSection:SectionIdentifierBar collapsed:NO]; + // SectionIdentifierFoo + EXPECT_EQ(1, [model numberOfItemsInSection:0]); EXPECT_FALSE([model sectionIsCollapsed:SectionIdentifierFoo]); + // SectionIdentifierBar + EXPECT_EQ(2, [model numberOfItemsInSection:1]); EXPECT_FALSE([model sectionIsCollapsed:SectionIdentifierBar]); } // Collapses just one section at the time. -TEST_F(TableViewModelTest, SetSomeCollapsed) { +TEST_F(ListModelCollapseTest, SetSomeCollapsed) { [model setSection:SectionIdentifierFoo collapsed:NO]; [model setSection:SectionIdentifierBar collapsed:YES]; @@ -93,7 +101,7 @@ } // Removes a collapsed section. -TEST_F(TableViewModelTest, RemoveCollapsedSection) { +TEST_F(ListModelCollapseTest, RemoveCollapsedSection) { [model setSection:SectionIdentifierFoo collapsed:NO]; [model setSection:SectionIdentifierBar collapsed:YES]; @@ -108,7 +116,7 @@ } // Removes a collapsed section, then re-adds it, it should still be collapsed. -TEST_F(TableViewModelTest, RemoveReaddCollapsedSection) { +TEST_F(ListModelCollapseTest, RemoveReaddCollapsedSection) { [model setSection:SectionIdentifierFoo collapsed:NO]; [model setSection:SectionIdentifierBar collapsed:YES]; @@ -124,9 +132,8 @@ [model addSectionWithIdentifier:SectionIdentifierBar]; // Use the same Key as the previously removed section. [model setSectionIdentifier:SectionIdentifierBar collapsedKey:@"BarKey"]; - TableViewHeaderFooterItem* header = - [[TableViewHeaderFooterItem alloc] initWithType:ItemTypeFooBar]; - TableViewItem* item = [[TableViewItem alloc] initWithType:ItemTypeFooBar]; + ListItem* header = [[ListItem alloc] initWithType:ItemTypeFooBar]; + ListItem* item = [[ListItem alloc] initWithType:ItemTypeFooBar]; [model setHeader:header forSectionWithIdentifier:SectionIdentifierBar]; [model addItem:item toSectionWithIdentifier:SectionIdentifierBar]; @@ -136,29 +143,28 @@ } // Test Collapsed persistance. -TEST_F(TableViewModelTest, PersistCollapsedSections) { +TEST_F(ListModelCollapseTest, PersistCollapsedSections) { [model setSection:SectionIdentifierFoo collapsed:NO]; [model setSection:SectionIdentifierBar collapsed:YES]; EXPECT_FALSE([model sectionIsCollapsed:SectionIdentifierFoo]); EXPECT_TRUE([model sectionIsCollapsed:SectionIdentifierBar]); - TableViewModel* anotherModel = [[TableViewModel alloc] init]; + ListModel* anotherModel = [[ListModel alloc] init]; [anotherModel addSectionWithIdentifier:SectionIdentifierFoo]; [anotherModel setSectionIdentifier:SectionIdentifierFoo collapsedKey:@"FooKey"]; - TableViewHeaderFooterItem* header = - [[TableViewHeaderFooterItem alloc] initWithType:ItemTypeFooBar]; - TableViewItem* item = [[TableViewItem alloc] initWithType:ItemTypeFooBar]; + ListItem* header = [[ListItem alloc] initWithType:ItemTypeFooBar]; + ListItem* item = [[ListItem alloc] initWithType:ItemTypeFooBar]; [anotherModel setHeader:header forSectionWithIdentifier:SectionIdentifierFoo]; [anotherModel addItem:item toSectionWithIdentifier:SectionIdentifierFoo]; [anotherModel addSectionWithIdentifier:SectionIdentifierBar]; [anotherModel setSectionIdentifier:SectionIdentifierBar collapsedKey:@"BarKey"]; - header = [[TableViewHeaderFooterItem alloc] initWithType:ItemTypeFooBar]; - item = [[TableViewItem alloc] initWithType:ItemTypeFooBar]; + header = [[ListItem alloc] initWithType:ItemTypeFooBar]; + item = [[ListItem alloc] initWithType:ItemTypeFooBar]; [anotherModel setHeader:header forSectionWithIdentifier:SectionIdentifierBar]; [anotherModel addItem:item toSectionWithIdentifier:SectionIdentifierBar];
diff --git a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_egtest.mm b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_egtest.mm index d921352..82c5e3d 100644 --- a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_egtest.mm +++ b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_egtest.mm
@@ -75,7 +75,7 @@ }}); if (IsUIRefreshPhase1Enabled()) { [NSUserDefaults.standardUserDefaults setObject:@{} - forKey:kTableViewModelCollapsedKey]; + forKey:kListModelCollapsedKey]; } else { [NSUserDefaults.standardUserDefaults setObject:@{} forKey:kCollapsedSectionsKey];
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm index 3b4634fa..86fbee76 100644 --- a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm +++ b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
@@ -162,7 +162,9 @@ // |guideName|. - (void)presentPopupOfType:(PopupMenuType)type fromNamedGuide:(GuideName*)guideName { - DCHECK(!self.presenter); + if (self.presenter) + [self dismissPopupMenuAnimated:YES]; + id<BrowserCommands> callableDispatcher = static_cast<id<BrowserCommands>>(self.dispatcher); [callableDispatcher
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_view_controller.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_view_controller.mm index b544baa..020f6c05 100644 --- a/ios/chrome/browser/ui/popup_menu/popup_menu_view_controller.mm +++ b/ios/chrome/browser/ui/popup_menu/popup_menu_view_controller.mm
@@ -88,13 +88,11 @@ UIImageView* shadow = [[UIImageView alloc] initWithImage:StretchableImageNamed(@"menu_shadow")]; [_contentContainer addSubview:shadow]; - shadow.translatesAutoresizingMaskIntoConstraints = NO; - AddSameConstraintsToSidesWithInsets( - _contentContainer, shadow, - LayoutSides::kTop | LayoutSides::kBottom | LayoutSides::kLeading | - LayoutSides::kTrailing, - ChromeDirectionalEdgeInsetsMake(kImageMargin, kImageMargin, kImageMargin, - kImageMargin)); + shadow.frame = + CGRectInset(_contentContainer.frame, -kImageMargin, -kImageMargin); + shadow.autoresizingMask = + UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + _contentContainer.layer.cornerRadius = kCornerRadius; _contentContainer.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:_contentContainer];
diff --git a/ios/chrome/browser/ui/table_view/BUILD.gn b/ios/chrome/browser/ui/table_view/BUILD.gn index c46fbe2..f9fcf7e 100644 --- a/ios/chrome/browser/ui/table_view/BUILD.gn +++ b/ios/chrome/browser/ui/table_view/BUILD.gn
@@ -80,7 +80,6 @@ testonly = true sources = [ "chrome_table_view_controller_unittest.mm", - "table_view_model_unittest.mm", ] deps = [ ":table_view",
diff --git a/ios/chrome/browser/ui/table_view/table_view_model.h b/ios/chrome/browser/ui/table_view/table_view_model.h index 0f8a0b1..30957af 100644 --- a/ios/chrome/browser/ui/table_view/table_view_model.h +++ b/ios/chrome/browser/ui/table_view/table_view_model.h
@@ -11,28 +11,10 @@ #import "ios/chrome/browser/ui/table_view/cells/table_view_header_footer_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_item.h" -// Key for saving collapsed state in the UserDefaults. -extern NSString* const kTableViewModelCollapsedKey; - // TableViewModel acts as a model class for table view controllers. @interface TableViewModel<__covariant ObjectType : TableViewItem*> : ListModel<ObjectType, TableViewHeaderFooterItem*> -// Sets an existing |sectionIdentifier| |collapsedKey| to be used when -// collapsing or expanding a section. |collapsedKey| is a unique identifier for -// each section that will be used for persisting information about the collapsed -// state of a section. A |collapsedKey| its only needed when -// collapsing/expanding sections. You can't collapse/expand any sections without -// a |collapsedKey|. -- (void)setSectionIdentifier:(NSInteger)sectionIdentifier - collapsedKey:(NSString*)collapsedKey; -// Sets the state of an existing |sectionIdentifier| to |collapsed|. A -// collapsedKey has to be previously set or this method will DCHECK(). -- (void)setSection:(NSInteger)sectionIdentifier collapsed:(BOOL)collapsed; -// Returns YES if |sectionIdentifier| is collapsed. If not collapsedKey has been -// set it will also return NO. -- (BOOL)sectionIsCollapsed:(NSInteger)sectionIdentifier; - @end #endif // IOS_CHROME_BROWSER_UI_TABLE_VIEW_TABLE_VIEW_MODEL_H_
diff --git a/ios/chrome/browser/ui/table_view/table_view_model.mm b/ios/chrome/browser/ui/table_view/table_view_model.mm index a68d2d5..45549a99 100644 --- a/ios/chrome/browser/ui/table_view/table_view_model.mm +++ b/ios/chrome/browser/ui/table_view/table_view_model.mm
@@ -4,84 +4,9 @@ #import "ios/chrome/browser/ui/table_view/table_view_model.h" -#include "base/logging.h" - #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif -NSString* const kTableViewModelCollapsedKey = - @"ChromeTableViewModelCollapsedSections"; - -@interface TableViewModel () -@property(strong, nonatomic) NSMutableDictionary* collapsedKeys; -@end - @implementation TableViewModel -@synthesize collapsedKeys = _collapsedKeys; - -#pragma mark - UITableViewDataSource - -// Override numberOfItemsInSection to return 0 if the section is collapsed. -- (NSInteger)numberOfItemsInSection:(NSInteger)section { - DCHECK_LT(section, [self numberOfSections]); - NSInteger sectionIdentifier = [self sectionIdentifierForSection:section]; - // Check if the sectionType is collapsed. If sectionType is collapsed - // return 0. - if ([self sectionIsCollapsed:sectionIdentifier]) { - return 0; - } else { - return [super numberOfItemsInSection:section]; - } -} - -#pragma mark - Collapsing methods. - -- (void)setSectionIdentifier:(NSInteger)sectionIdentifier - collapsedKey:(NSString*)collapsedKey { - // Check that the sectionIdentifier exists. - DCHECK([self hasSectionForSectionIdentifier:sectionIdentifier]); - // Check that the collapsedKey is not being used already. - DCHECK(![self.collapsedKeys objectForKey:collapsedKey]); - [self.collapsedKeys setObject:collapsedKey forKey:@(sectionIdentifier)]; -} - -- (void)setSection:(NSInteger)sectionIdentifier collapsed:(BOOL)collapsed { - // TODO(crbug.com/419346): Store in the browser state preference instead of - // NSUserDefaults. - DCHECK([self hasSectionForSectionIdentifier:sectionIdentifier]); - NSString* sectionKey = [self.collapsedKeys objectForKey:@(sectionIdentifier)]; - DCHECK(sectionKey); - NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; - NSDictionary* collapsedSections = - [defaults dictionaryForKey:kTableViewModelCollapsedKey]; - NSMutableDictionary* newCollapsedSection = - [NSMutableDictionary dictionaryWithDictionary:collapsedSections]; - NSNumber* value = [NSNumber numberWithBool:collapsed]; - [newCollapsedSection setValue:value forKey:sectionKey]; - [defaults setObject:newCollapsedSection forKey:kTableViewModelCollapsedKey]; -} - -- (BOOL)sectionIsCollapsed:(NSInteger)sectionIdentifier { - // TODO(crbug.com/419346): Store in the profile's preference instead of the - // NSUserDefaults. - DCHECK([self hasSectionForSectionIdentifier:sectionIdentifier]); - NSString* sectionKey = [self.collapsedKeys objectForKey:@(sectionIdentifier)]; - if (!sectionKey) - return NO; - NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; - NSDictionary* collapsedSections = - [defaults dictionaryForKey:kTableViewModelCollapsedKey]; - NSNumber* value = (NSNumber*)[collapsedSections valueForKey:sectionKey]; - return [value boolValue]; -} - -// |self.collapsedKeys| lazy instantiation. -- (NSMutableDictionary*)collapsedKeys { - if (!_collapsedKeys) { - _collapsedKeys = [[NSMutableDictionary alloc] init]; - } - return _collapsedKeys; -} - @end
diff --git a/ios/chrome/browser/ui/toolbar/buttons/toolbar_tools_menu_button.mm b/ios/chrome/browser/ui/toolbar/buttons/toolbar_tools_menu_button.mm index 0b1d1d8..5ee7bd2 100644 --- a/ios/chrome/browser/ui/toolbar/buttons/toolbar_tools_menu_button.mm +++ b/ios/chrome/browser/ui/toolbar/buttons/toolbar_tools_menu_button.mm
@@ -99,6 +99,8 @@ forState:UIControlStateNormal]; [self setTintColor:toolbar::HighlighButtonTint(style_) forState:UIControlStateHighlighted]; + } else { + [self configureSpotlightView]; } } return self;
diff --git a/media/audio/pulse/audio_manager_pulse.cc b/media/audio/pulse/audio_manager_pulse.cc index ee50c611..3cd51959 100644 --- a/media/audio/pulse/audio_manager_pulse.cc +++ b/media/audio/pulse/audio_manager_pulse.cc
@@ -274,13 +274,16 @@ if (info->monitor_of_sink != PA_INVALID_INDEX) return; - // Exclude devices that don't have an available active port (i.e it's - // unplugged). Such devices won't be picked (by pulseaudio) as default device, - // and if we have no available devices we don't want to add a default device - // to enumerations either. - if (!info->active_port || - info->active_port->available == PA_PORT_AVAILABLE_NO) - return; + // If the device has ports, but none of them are available, skip it. + if (info->n_ports > 0) { + uint32_t port = 0; + for (; port != info->n_ports; ++port) { + if (info->ports[port]->available != PA_PORT_AVAILABLE_NO) + break; + } + if (port == info->n_ports) + return; + } manager->devices_->push_back(AudioDeviceName(info->description, info->name)); }
diff --git a/net/cert/cert_verify_proc_blacklist.inc b/net/cert/cert_verify_proc_blacklist.inc index 0778a8cb..249b61db 100644 --- a/net/cert/cert_verify_proc_blacklist.inc +++ b/net/cert/cert_verify_proc_blacklist.inc
@@ -31,7 +31,7 @@ {0x1f, 0x42, 0x24, 0xce, 0xc8, 0x4f, 0xc9, 0x9c, 0xed, 0x88, 0x1f, 0xf6, 0xfc, 0xfd, 0x3e, 0x21, 0xf8, 0xc5, 0x19, 0xc5, 0x47, 0xaa, 0x6a, 0x5d, 0xd3, 0xde, 0x24, 0x73, 0x02, 0xce, 0x50, 0xd1}, - // 2c998e761160c3b06d82faa9fdc7545d9bda9eb60310f992aa510a6280b74245.pem + // 159ca03a88897c8f13817a212629df84ce824709492b8c9adb8e5437d2fc72be.pem {0x2c, 0x99, 0x8e, 0x76, 0x11, 0x60, 0xc3, 0xb0, 0x6d, 0x82, 0xfa, 0xa9, 0xfd, 0xc7, 0x54, 0x5d, 0x9b, 0xda, 0x9e, 0xb6, 0x03, 0x10, 0xf9, 0x92, 0xaa, 0x51, 0x0a, 0x62, 0x80, 0xb7, 0x42, 0x45}, @@ -51,6 +51,10 @@ {0x45, 0x5b, 0x87, 0xe9, 0x6f, 0x1c, 0xea, 0x2f, 0x8b, 0x6d, 0xae, 0x08, 0x08, 0xec, 0x24, 0x73, 0x8f, 0xd9, 0x2b, 0x7f, 0xd3, 0x06, 0x75, 0x71, 0x98, 0xbf, 0x38, 0x9d, 0x75, 0x5c, 0x0b, 0x6c}, + // 3ab0fcc7287454c405863e3aa204fea8eb0c50a524d2a7e15524a830cd4ab0fe.pem + {0x49, 0x0b, 0x6e, 0xc6, 0xbe, 0xb2, 0xd6, 0x03, 0x47, 0x20, 0xb5, + 0x14, 0x9b, 0x6b, 0x29, 0xcd, 0x35, 0x51, 0x59, 0x88, 0xcc, 0x16, + 0xaf, 0x85, 0x41, 0x48, 0xb0, 0x7b, 0x9b, 0x1f, 0x8a, 0x11}, // b6fe9151402bad1c06d7e66db67a26aa7356f2e6c644dbcf9f98968ff632e1b7.pem {0x4b, 0xb8, 0xf3, 0x5b, 0xa1, 0xe1, 0x26, 0xf8, 0xdd, 0xe1, 0xb0, 0xc4, 0x20, 0x62, 0x5e, 0xd8, 0x6d, 0xce, 0x61, 0xa7, 0xbd, 0xda, @@ -69,6 +73,14 @@ {0x5e, 0x53, 0xf2, 0x64, 0x67, 0xf8, 0x94, 0xfd, 0xe5, 0x3b, 0x3f, 0xa4, 0x06, 0xa4, 0x40, 0xcb, 0xb3, 0xb0, 0x76, 0xbb, 0x5b, 0x75, 0x8f, 0xe4, 0x83, 0x4a, 0xd6, 0x65, 0x00, 0x20, 0x89, 0x07}, + // 2d11e736f0427fd6ba4b372755d34a0edd8d83f7e9e7f6c01b388c9b7afa850d.pem + {0x6a, 0xdb, 0x8e, 0x3e, 0x05, 0x54, 0x60, 0x92, 0x2d, 0x15, 0x01, + 0xcb, 0x97, 0xf9, 0x4c, 0x6a, 0x02, 0xe3, 0x9c, 0x8f, 0x27, 0x74, + 0xca, 0x40, 0x88, 0x25, 0xb7, 0xb5, 0x83, 0x79, 0xdc, 0x14}, + // 2a33f5b48176523fd3c0d854f20093417175bfd498ef354cc7f38b54adabaf1a.pem + {0x70, 0x7d, 0x36, 0x4e, 0x72, 0xae, 0x52, 0x14, 0x31, 0xdd, 0x95, + 0x38, 0x97, 0xf9, 0xc4, 0x84, 0x6d, 0x5b, 0x8c, 0x32, 0x42, 0x98, + 0xfe, 0x53, 0xfb, 0xd4, 0xad, 0xa1, 0xf2, 0xd1, 0x15, 0x7f}, // f4a5984324de98bd979ef181a100cf940f2166173319a86a0d9d7c8fac3b0a8f.pem {0x71, 0x65, 0xe9, 0x91, 0xad, 0xe7, 0x91, 0x6d, 0x86, 0xb4, 0x66, 0xab, 0xeb, 0xb6, 0xe4, 0x57, 0xca, 0x93, 0x1c, 0x80, 0x4e, 0x58, @@ -175,6 +187,10 @@ {0xea, 0x08, 0xc8, 0xd4, 0x5d, 0x52, 0xca, 0x59, 0x3d, 0xe5, 0x24, 0xf0, 0x51, 0x3c, 0xa6, 0x41, 0x8d, 0xa9, 0x85, 0x9f, 0x7b, 0x08, 0xef, 0x13, 0xff, 0x9d, 0xd7, 0xbf, 0x61, 0x2d, 0x6a, 0x37}, + // 60911c79835c3739432d08c45df64311e06985c5889dc5420ce3d142c8c7ef58.pem + {0xef, 0x55, 0x12, 0x84, 0x71, 0x52, 0x32, 0xde, 0x92, 0xe2, 0x46, + 0xc3, 0x23, 0x32, 0x93, 0x62, 0xb1, 0x32, 0x49, 0x3b, 0xb1, 0x6b, + 0x58, 0x9e, 0x47, 0x75, 0x52, 0x0b, 0xeb, 0x87, 0x1a, 0x56}, // 31c8fd37db9b56e708b03d1f01848b068c6da66f36fb5d82c008c6040fa3e133.pem {0xf0, 0x34, 0xf6, 0x42, 0xca, 0x1d, 0x9e, 0x88, 0xe9, 0xef, 0xea, 0xfc, 0xb1, 0x5c, 0x7c, 0x93, 0x7a, 0xa1, 0x9e, 0x04, 0xb0, 0x80,
diff --git a/net/data/ssl/blacklist/2a33f5b48176523fd3c0d854f20093417175bfd498ef354cc7f38b54adabaf1a.pem b/net/data/ssl/blacklist/2a33f5b48176523fd3c0d854f20093417175bfd498ef354cc7f38b54adabaf1a.pem new file mode 100644 index 0000000..36df02c0 --- /dev/null +++ b/net/data/ssl/blacklist/2a33f5b48176523fd3c0d854f20093417175bfd498ef354cc7f38b54adabaf1a.pem
@@ -0,0 +1,47 @@ +Certificate: + Data: + Version: 1 (0x0) + Serial Number: 0 (0x0) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=FR, ST=IDF, L=GUY, O=Aastra, OU=Aastra, CN=Aastra + Validity + Not Before: Sep 23 10:01:14 2008 GMT + Not After : Sep 21 10:01:14 2018 GMT + Subject: C=FR, ST=IDF, L=GUY, O=Aastra, OU=Aastra, CN=Aastra + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (1024 bit) + Modulus: + 00:b9:54:78:1e:d7:97:97:08:f4:80:4b:30:84:f9: + ff:20:20:f8:4c:57:fd:9d:e7:01:68:2d:fe:11:33: + 6f:db:6f:af:b6:5a:51:c6:5b:7c:e2:24:0f:f9:4d: + 3c:35:bf:16:78:a5:45:57:c6:8d:d7:80:91:53:0f: + 74:34:36:19:dc:a1:b6:2e:13:15:3a:04:65:7f:fd: + 51:34:1d:62:8c:e8:28:10:25:57:e2:9e:c1:fe:7a: + 82:f3:2d:ce:cc:cb:40:d5:c3:9d:fc:58:19:ba:86: + 64:16:15:30:87:54:82:8b:4f:68:93:ca:80:4b:7c: + a2:3f:5a:70:e7:b7:4a:a6:27 + Exponent: 65537 (0x10001) + Signature Algorithm: md5WithRSAEncryption + 20:66:bf:a8:40:01:8d:4f:4b:e8:07:67:7f:c3:0d:42:87:c8: + a0:b8:60:7a:ac:40:3d:1a:9b:60:59:90:7f:7e:f3:e1:e6:2f: + 8a:2f:30:e5:46:e7:f1:51:82:d1:e6:d2:87:aa:87:d3:a8:c9: + ec:04:f7:9a:bd:e7:b3:47:59:c2:17:0c:6a:aa:50:a7:f2:06: + a6:e2:8d:99:0e:8b:aa:fb:69:d6:95:6a:ec:19:99:29:a1:82: + 02:f7:85:9a:5d:8f:c0:a3:94:56:6f:78:5e:15:59:9e:81:29: + 93:89:3d:0a:b3:07:cb:59:07:d3:b4:70:2b:d7:9c:ba:67:ca: + 10:a7 +-----BEGIN CERTIFICATE----- +MIICJzCCAZACAQAwDQYJKoZIhvcNAQEEBQAwXDELMAkGA1UEBhMCRlIxDDAKBgNV +BAgTA0lERjEMMAoGA1UEBxMDR1VZMQ8wDQYDVQQKEwZBYXN0cmExDzANBgNVBAsT +BkFhc3RyYTEPMA0GA1UEAxMGQWFzdHJhMB4XDTA4MDkyMzEwMDExNFoXDTE4MDky +MTEwMDExNFowXDELMAkGA1UEBhMCRlIxDDAKBgNVBAgTA0lERjEMMAoGA1UEBxMD +R1VZMQ8wDQYDVQQKEwZBYXN0cmExDzANBgNVBAsTBkFhc3RyYTEPMA0GA1UEAxMG +QWFzdHJhMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5VHge15eXCPSASzCE ++f8gIPhMV/2d5wFoLf4RM2/bb6+2WlHGW3ziJA/5TTw1vxZ4pUVXxo3XgJFTD3Q0 +NhncobYuExU6BGV//VE0HWKM6CgQJVfinsH+eoLzLc7My0DVw538WBm6hmQWFTCH +VIKLT2iTyoBLfKI/WnDnt0qmJwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBACBmv6hA +AY1PS+gHZ3/DDUKHyKC4YHqsQD0am2BZkH9+8+HmL4ovMOVG5/FRgtHm0oeqh9Oo +yewE95q957NHWcIXDGqqUKfyBqbijZkOi6r7adaVauwZmSmhggL3hZpdj8CjlFZv +eF4VWZ6BKZOJPQqzB8tZB9O0cCvXnLpnyhCn +-----END CERTIFICATE-----
diff --git a/net/data/ssl/blacklist/2d11e736f0427fd6ba4b372755d34a0edd8d83f7e9e7f6c01b388c9b7afa850d.pem b/net/data/ssl/blacklist/2d11e736f0427fd6ba4b372755d34a0edd8d83f7e9e7f6c01b388c9b7afa850d.pem new file mode 100644 index 0000000..1fdfccd --- /dev/null +++ b/net/data/ssl/blacklist/2d11e736f0427fd6ba4b372755d34a0edd8d83f7e9e7f6c01b388c9b7afa850d.pem
@@ -0,0 +1,84 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 12725199854837502752 (0xb098fdd8d3711320) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=CA, ST=Ontario, L=Ottawa, O=Mitel Networks, OU=VoIP Platforms, CN=Mitel Networks Root CA/emailAddress=sslsecurity@mitel.com + Validity + Not Before: Jul 8 13:40:51 2015 GMT + Not After : Jul 5 13:40:51 2027 GMT + Subject: C=CA, ST=Ontario, L=Ottawa, O=Mitel Networks, OU=VoIP Platforms, CN=Mitel Networks ICP CA/emailAddress=sslsecurity@mitel.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:c3:bb:30:13:8c:87:ce:c0:a9:75:6f:20:15:33: + 6e:df:cc:ae:c3:ae:dc:1a:dc:f7:3d:17:2a:9a:cf: + fe:0b:95:d3:9c:df:fe:e5:2e:b3:2e:e6:ed:e9:21: + e4:59:f2:c3:22:ea:53:a9:4d:6e:ff:2f:0c:3f:c7: + b1:c4:83:85:aa:a3:87:96:b2:49:91:ee:e6:c2:a1: + f0:13:6c:fe:77:6d:a0:b0:35:18:ff:1e:84:f2:f7: + 70:00:24:d4:c8:bd:82:52:ca:c7:4b:82:af:ca:c5: + 0a:56:08:1f:59:b4:c8:77:5c:12:75:28:e4:02:87: + 6e:51:8c:fc:e9:13:4e:62:00:db:59:6f:d8:18:43: + c2:0a:3c:52:9a:fd:80:16:0d:a9:be:93:04:61:8e: + ab:79:e5:c5:74:aa:18:a8:b2:4d:66:14:01:c0:a2: + ff:ef:f2:fa:e3:15:24:46:ac:e8:2b:4f:54:3d:d2: + 58:0e:11:ad:c1:b2:c4:bf:89:29:e8:9f:a8:c1:e2: + 65:82:57:ea:e2:89:6d:56:44:da:cd:bd:b2:dc:90: + 5e:ac:c6:74:b2:fb:83:70:21:ac:1e:f4:48:93:09: + cf:25:17:3d:ef:d3:48:28:b7:d1:8d:3e:aa:01:a4: + 94:22:65:19:9a:ee:61:25:4b:93:fe:97:bc:a2:cd: + d9:71 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + 70:87:52:6E:59:87:43:AD:14:0B:BE:95:64:4C:73:30:11:53:D1:72 + X509v3 Authority Key Identifier: + keyid:7E:AD:DA:3D:2C:6D:90:C3:E1:F2:DE:4D:66:6A:89:41:D1:3E:35:C9 + + X509v3 Basic Constraints: + CA:TRUE + X509v3 Key Usage: + Certificate Sign, CRL Sign + Signature Algorithm: sha256WithRSAEncryption + 57:6e:3a:2d:55:99:ce:29:e2:9f:65:67:43:36:60:d6:5f:92: + aa:94:a4:7c:fd:79:c8:c4:b4:c4:58:a8:8d:92:22:92:25:39: + 6e:11:46:50:65:a9:75:c9:16:07:ca:47:f5:2c:77:47:4f:af: + dc:5a:ef:64:b6:04:96:85:27:82:7b:dc:34:06:c9:48:a9:b7: + 68:52:e9:cb:c0:58:8e:38:d4:e7:bd:8c:8b:0f:ce:ee:47:5c: + 50:ac:79:04:40:1c:18:4a:a7:09:32:8a:ae:6e:35:12:e7:8e: + 41:ae:f9:f7:df:b8:33:67:b5:3a:c2:c0:b3:37:86:ae:41:86: + d6:e9:bb:f9:6f:dc:57:1f:a8:ac:4b:87:ed:d5:74:74:6e:7e: + a0:40:c6:2c:27:f5:39:14:59:fd:30:46:a4:3b:b6:6a:4e:5d: + 1d:16:5c:15:69:35:4b:70:df:96:d4:72:f0:86:1a:6f:59:b4: + 89:67:d8:b7:85:42:aa:bf:e1:03:49:fb:79:3a:e7:44:3f:3f: + e9:f4:d3:06:01:93:1b:b5:7b:3c:f3:ac:34:53:12:fc:6d:1d: + 80:36:c0:46:e4:46:3f:4b:33:a3:d5:b5:e1:4a:7d:e7:20:e5: + 65:a5:ad:2f:ec:f2:a1:62:41:35:aa:0b:1a:9d:d4:90:76:30: + b1:62:e0:75 +-----BEGIN CERTIFICATE----- +MIIEMzCCAxugAwIBAgIJALCY/djTcRMgMA0GCSqGSIb3DQEBCwUAMIGpMQswCQYD +VQQGEwJDQTEQMA4GA1UECAwHT250YXJpbzEPMA0GA1UEBwwGT3R0YXdhMRcwFQYD +VQQKDA5NaXRlbCBOZXR3b3JrczEXMBUGA1UECwwOVm9JUCBQbGF0Zm9ybXMxHzAd +BgNVBAMMFk1pdGVsIE5ldHdvcmtzIFJvb3QgQ0ExJDAiBgkqhkiG9w0BCQEWFXNz +bHNlY3VyaXR5QG1pdGVsLmNvbTAeFw0xNTA3MDgxMzQwNTFaFw0yNzA3MDUxMzQw +NTFaMIGoMQswCQYDVQQGEwJDQTEQMA4GA1UECAwHT250YXJpbzEPMA0GA1UEBwwG +T3R0YXdhMRcwFQYDVQQKDA5NaXRlbCBOZXR3b3JrczEXMBUGA1UECwwOVm9JUCBQ +bGF0Zm9ybXMxHjAcBgNVBAMMFU1pdGVsIE5ldHdvcmtzIElDUCBDQTEkMCIGCSqG +SIb3DQEJARYVc3Nsc2VjdXJpdHlAbWl0ZWwuY29tMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAw7swE4yHzsCpdW8gFTNu38yuw67cGtz3PRcqms/+C5XT +nN/+5S6zLubt6SHkWfLDIupTqU1u/y8MP8exxIOFqqOHlrJJke7mwqHwE2z+d22g +sDUY/x6E8vdwACTUyL2CUsrHS4KvysUKVggfWbTId1wSdSjkAoduUYz86RNOYgDb +WW/YGEPCCjxSmv2AFg2pvpMEYY6reeXFdKoYqLJNZhQBwKL/7/L64xUkRqzoK09U +PdJYDhGtwbLEv4kp6J+oweJlglfq4oltVkTazb2y3JBerMZ0svuDcCGsHvRIkwnP +JRc979NIKLfRjT6qAaSUImUZmu5hJUuT/pe8os3ZcQIDAQABo10wWzAdBgNVHQ4E +FgQUcIdSblmHQ60UC76VZExzMBFT0XIwHwYDVR0jBBgwFoAUfq3aPSxtkMPh8t5N +ZmqJQdE+NckwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEL +BQADggEBAFduOi1Vmc4p4p9lZ0M2YNZfkqqUpHz9ecjEtMRYqI2SIpIlOW4RRlBl +qXXJFgfKR/Usd0dPr9xa72S2BJaFJ4J73DQGyUipt2hS6cvAWI441Oe9jIsPzu5H +XFCseQRAHBhKpwkyiq5uNRLnjkGu+fffuDNntTrCwLM3hq5Bhtbpu/lv3FcfqKxL +h+3VdHRufqBAxiwn9TkUWf0wRqQ7tmpOXR0WXBVpNUtw35bUcvCGGm9ZtIln2LeF +Qqq/4QNJ+3k650Q/P+n00wYBkxu1ezzzrDRTEvxtHYA2wEbkRj9LM6PVteFKfecg +5WWlrS/s8qFiQTWqCxqd1JB2MLFi4HU= +-----END CERTIFICATE-----
diff --git a/net/data/ssl/blacklist/3ab0fcc7287454c405863e3aa204fea8eb0c50a524d2a7e15524a830cd4ab0fe.pem b/net/data/ssl/blacklist/3ab0fcc7287454c405863e3aa204fea8eb0c50a524d2a7e15524a830cd4ab0fe.pem new file mode 100644 index 0000000..a6237cd5 --- /dev/null +++ b/net/data/ssl/blacklist/3ab0fcc7287454c405863e3aa204fea8eb0c50a524d2a7e15524a830cd4ab0fe.pem
@@ -0,0 +1,57 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 0 (0x0) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=FR, ST=IDF, L=GUY, O=Aastra, OU=Aastra, CN=Aastra + Validity + Not Before: Jun 6 09:32:48 2016 GMT + Not After : Jun 4 09:32:48 2026 GMT + Subject: C=FR, ST=IDF, L=GUY, O=Aastra, OU=Aastra, CN=Aastra + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (1024 bit) + Modulus: + 00:ba:85:59:f9:97:e7:f7:b0:b3:21:f6:5f:15:54: + e7:ae:d1:03:f3:03:21:e4:4a:cc:a4:2b:21:db:36: + 11:93:6a:ee:fd:29:b5:a4:f0:90:da:13:65:6c:a8: + e9:82:84:07:8c:04:88:19:b1:ab:01:5e:3f:82:c3: + e2:ba:dc:6a:f1:2d:dd:58:a4:f3:66:f9:89:3a:4b: + 28:8d:cd:88:e9:63:18:5c:1a:9e:eb:a6:58:eb:c6: + 94:b1:99:e3:34:9d:d5:5f:a7:a0:28:5f:3d:cf:84: + f6:18:8f:72:8f:50:66:f4:94:f1:2d:2f:66:92:b8: + 93:f1:41:7a:f5:fb:10:a0:85 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + 77:63:16:DA:A4:70:7D:47:85:84:61:00:90:22:88:5D:D4:CB:65:08 + X509v3 Authority Key Identifier: + keyid:77:63:16:DA:A4:70:7D:47:85:84:61:00:90:22:88:5D:D4:CB:65:08 + + X509v3 Basic Constraints: + CA:TRUE + Signature Algorithm: sha256WithRSAEncryption + 20:f4:98:d8:ea:3d:36:09:ac:aa:30:bb:2f:d6:85:de:74:30: + 47:bb:89:11:35:02:5e:18:cb:49:76:ee:eb:f3:63:36:96:db: + 1e:96:16:26:eb:68:20:a5:85:b5:a3:18:6a:c2:c5:52:16:99: + 6c:ab:a1:e5:75:5a:8a:dd:55:67:43:f0:4c:47:29:e8:3a:25: + dd:35:08:48:19:09:79:c4:7b:d3:3c:81:96:ba:b8:11:4e:74: + d7:ad:54:af:e2:e7:b6:25:77:b8:78:da:36:91:c3:8b:14:85: + a0:60:54:26:33:33:c2:1d:b2:1e:a0:ca:7f:a9:ff:ac:be:14: + 16:b4 +-----BEGIN CERTIFICATE----- +MIICfjCCAeegAwIBAgIBADANBgkqhkiG9w0BAQsFADBcMQswCQYDVQQGEwJGUjEM +MAoGA1UECAwDSURGMQwwCgYDVQQHDANHVVkxDzANBgNVBAoMBkFhc3RyYTEPMA0G +A1UECwwGQWFzdHJhMQ8wDQYDVQQDDAZBYXN0cmEwHhcNMTYwNjA2MDkzMjQ4WhcN +MjYwNjA0MDkzMjQ4WjBcMQswCQYDVQQGEwJGUjEMMAoGA1UECAwDSURGMQwwCgYD +VQQHDANHVVkxDzANBgNVBAoMBkFhc3RyYTEPMA0GA1UECwwGQWFzdHJhMQ8wDQYD +VQQDDAZBYXN0cmEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALqFWfmX5/ew +syH2XxVU567RA/MDIeRKzKQrIds2EZNq7v0ptaTwkNoTZWyo6YKEB4wEiBmxqwFe +P4LD4rrcavEt3Vik82b5iTpLKI3NiOljGFwanuumWOvGlLGZ4zSd1V+noChfPc+E +9hiPco9QZvSU8S0vZpK4k/FBevX7EKCFAgMBAAGjUDBOMB0GA1UdDgQWBBR3Yxba +pHB9R4WEYQCQIohd1MtlCDAfBgNVHSMEGDAWgBR3YxbapHB9R4WEYQCQIohd1Mtl +CDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GBACD0mNjqPTYJrKowuy/W +hd50MEe7iRE1Al4Yy0l27uvzYzaW2x6WFibraCClhbWjGGrCxVIWmWyroeV1Word +VWdD8ExHKeg6Jd01CEgZCXnEe9M8gZa6uBFOdNetVK/i57Yld7h42jaRw4sUhaBg +VCYzM8Idsh6gyn+p/6y+FBa0 +-----END CERTIFICATE-----
diff --git a/net/data/ssl/blacklist/60911c79835c3739432d08c45df64311e06985c5889dc5420ce3d142c8c7ef58.pem b/net/data/ssl/blacklist/60911c79835c3739432d08c45df64311e06985c5889dc5420ce3d142c8c7ef58.pem new file mode 100644 index 0000000..bfd5e5f4 --- /dev/null +++ b/net/data/ssl/blacklist/60911c79835c3739432d08c45df64311e06985c5889dc5420ce3d142c8c7ef58.pem
@@ -0,0 +1,68 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 2 (0x2) + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=CA, ST=ON, L=Ottawa, O=Mitel Networks, OU=VoIP Platforms, CN=Mitel Networks Root CA/emailAddress=Lee_Dilkie@Mitel.com + Validity + Not Before: Jan 24 21:25:44 2002 GMT + Not After : Jun 11 21:25:44 2029 GMT + Subject: C=CA, ST=ON, O=Mitel Networks, OU=VoIP Platforms, CN=Mitel Networks ICP CA/emailAddress=Lee_Dilkie@Mitel.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (1024 bit) + Modulus: + 00:b3:fe:d8:49:63:4a:a4:3a:01:3d:8f:11:31:1f: + 55:8d:43:94:91:39:48:3f:1e:c0:a6:06:55:54:33: + 7c:89:d8:b6:0e:3f:6b:37:63:02:0c:ac:7d:8e:34: + 57:1f:67:78:05:16:ab:29:0f:69:81:b4:39:3f:1a: + b4:a0:ab:96:c8:db:25:c9:44:2a:aa:ba:38:43:cc: + 82:bf:d4:6f:f2:71:c0:7d:08:ae:2c:9d:0f:d5:76: + d1:92:38:57:fb:56:af:1c:22:71:2b:ab:00:59:22: + 50:8d:2b:d9:6a:98:6b:a2:31:80:83:e3:32:e9:68: + 1f:9f:58:a2:91:20:bd:4b:e7 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:TRUE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 75:E9:50:52:78:06:5B:0E:5A:A2:39:1C:AD:8D:3E:6E:91:65:AC:C0 + X509v3 Authority Key Identifier: + keyid:8D:75:06:FA:DB:5F:6E:B8:73:D4:67:C5:FF:DF:43:F8:9D:52:71:3A + DirName:/C=CA/ST=ON/L=Ottawa/O=Mitel Networks/OU=VoIP Platforms/CN=Mitel Networks Root CA/emailAddress=Lee_Dilkie@Mitel.com + serial:00 + + Signature Algorithm: sha1WithRSAEncryption + 5b:38:fe:e7:c7:b0:66:01:88:08:24:c6:f8:de:28:54:c2:ac: + 62:5a:48:33:00:65:fa:47:98:33:b0:b5:7f:fb:65:7e:9f:68: + 49:9f:95:76:59:ce:62:d1:35:e1:8b:36:05:44:04:f4:19:b0: + 67:19:74:af:22:03:74:01:0b:fc:fe:c3:3f:2a:a4:a9:16:d1: + 82:44:a5:2b:90:e7:21:d4:b2:9d:a6:db:9c:e8:62:f1:f8:63: + f5:4e:06:fe:5f:f2:c7:71:08:e2:50:76:a0:73:9a:1a:29:0d: + ee:90:bb:8a:ea:fa:37:63:e9:b0:fb:a8:e9:c9:19:e9:cb:a6: + 7a:60 +-----BEGIN CERTIFICATE----- +MIID4DCCA0mgAwIBAgIBAjANBgkqhkiG9w0BAQUFADCBozELMAkGA1UEBhMCQ0Ex +CzAJBgNVBAgTAk9OMQ8wDQYDVQQHEwZPdHRhd2ExFzAVBgNVBAoTDk1pdGVsIE5l +dHdvcmtzMRcwFQYDVQQLEw5Wb0lQIFBsYXRmb3JtczEfMB0GA1UEAxMWTWl0ZWwg +TmV0d29ya3MgUm9vdCBDQTEjMCEGCSqGSIb3DQEJARYUTGVlX0RpbGtpZUBNaXRl +bC5jb20wHhcNMDIwMTI0MjEyNTQ0WhcNMjkwNjExMjEyNTQ0WjCBkTELMAkGA1UE +BhMCQ0ExCzAJBgNVBAgTAk9OMRcwFQYDVQQKEw5NaXRlbCBOZXR3b3JrczEXMBUG +A1UECxMOVm9JUCBQbGF0Zm9ybXMxHjAcBgNVBAMTFU1pdGVsIE5ldHdvcmtzIElD +UCBDQTEjMCEGCSqGSIb3DQEJARYUTGVlX0RpbGtpZUBNaXRlbC5jb20wgZ8wDQYJ +KoZIhvcNAQEBBQADgY0AMIGJAoGBALP+2EljSqQ6AT2PETEfVY1DlJE5SD8ewKYG +VVQzfInYtg4/azdjAgysfY40Vx9neAUWqykPaYG0OT8atKCrlsjbJclEKqq6OEPM +gr/Ub/JxwH0IriydD9V20ZI4V/tWrxwicSurAFkiUI0r2WqYa6IxgIPjMuloH59Y +opEgvUvnAgMBAAGjggEyMIIBLjAMBgNVHRMEBTADAQH/MCwGCWCGSAGG+EIBDQQf +Fh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUdelQUngG +Ww5aojkcrY0+bpFlrMAwgdAGA1UdIwSByDCBxYAUjXUG+ttfbrhz1GfF/99D+J1S +cTqhgamkgaYwgaMxCzAJBgNVBAYTAkNBMQswCQYDVQQIEwJPTjEPMA0GA1UEBxMG +T3R0YXdhMRcwFQYDVQQKEw5NaXRlbCBOZXR3b3JrczEXMBUGA1UECxMOVm9JUCBQ +bGF0Zm9ybXMxHzAdBgNVBAMTFk1pdGVsIE5ldHdvcmtzIFJvb3QgQ0ExIzAhBgkq +hkiG9w0BCQEWFExlZV9EaWxraWVATWl0ZWwuY29tggEAMA0GCSqGSIb3DQEBBQUA +A4GBAFs4/ufHsGYBiAgkxvjeKFTCrGJaSDMAZfpHmDOwtX/7ZX6faEmflXZZzmLR +NeGLNgVEBPQZsGcZdK8iA3QBC/z+wz8qpKkW0YJEpSuQ5yHUsp2m25zoYvH4Y/VO +Bv5f8sdxCOJQdqBzmhopDe6Qu4rq+jdj6bD7qOnJGenLpnpg +-----END CERTIFICATE-----
diff --git a/net/data/ssl/blacklist/README.md b/net/data/ssl/blacklist/README.md index 5c8da4cb..c033bf7 100644 --- a/net/data/ssl/blacklist/README.md +++ b/net/data/ssl/blacklist/README.md
@@ -120,6 +120,17 @@ * [0f912fd7be760be25afbc56bdc09cd9e5dcc9c6f6a55a778aefcb6aa30e31554.pem](0f912fd7be760be25afbc56bdc09cd9e5dcc9c6f6a55a778aefcb6aa30e31554.pem) * [ec30c9c3065a06bb07dc5b1c6b497f370c1ca65c0f30c08e042ba6bcecc78f2c.pem](ec30c9c3065a06bb07dc5b1c6b497f370c1ca65c0f30c08e042ba6bcecc78f2c.pem) +### Mitel + +For details, see <https://www.mitel.com/support/security-advisories/mitel-product-security-advisory-17-0001> + +Certain Mitel products shipped with extractable private keys, the public certs for which users were encouraged to install as anchors. + + * [2a33f5b48176523fd3c0d854f20093417175bfd498ef354cc7f38b54adabaf1a.pem](2a33f5b48176523fd3c0d854f20093417175bfd498ef354cc7f38b54adabaf1a.pem) + * [2d11e736f0427fd6ba4b372755d34a0edd8d83f7e9e7f6c01b388c9b7afa850d.pem](2d11e736f0427fd6ba4b372755d34a0edd8d83f7e9e7f6c01b388c9b7afa850d.pem) + * [3ab0fcc7287454c405863e3aa204fea8eb0c50a524d2a7e15524a830cd4ab0fe.pem](3ab0fcc7287454c405863e3aa204fea8eb0c50a524d2a7e15524a830cd4ab0fe.pem) + * [60911c79835c3739432d08c45df64311e06985c5889dc5420ce3d142c8c7ef58.pem](60911c79835c3739432d08c45df64311e06985c5889dc5420ce3d142c8c7ef58.pem) + ### sslip.io For details, see <https://blog.pivotal.io/labs/labs/sslip-io-a-valid-ssl-certificate-for-every-ip-address>
diff --git a/net/disk_cache/backend_unittest.cc b/net/disk_cache/backend_unittest.cc index 1ce191c6..479ccf4 100644 --- a/net/disk_cache/backend_unittest.cc +++ b/net/disk_cache/backend_unittest.cc
@@ -4115,7 +4115,7 @@ // Verify that tasks run in priority order when the experiment is enabled. // Test has races, disabling until fixed: https://crbug.com/853283 -TEST_F(DiskCacheBackendTest, DISABLE_SimpleCachePrioritizedEntryOrder) { +TEST_F(DiskCacheBackendTest, DISABLED_SimpleCachePrioritizedEntryOrder) { base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeature( disk_cache::SimpleBackendImpl::kPrioritizedSimpleCacheTasks);
diff --git a/services/audio/service.cc b/services/audio/service.cc index e2b546f..ab30f45 100644 --- a/services/audio/service.cc +++ b/services/audio/service.cc
@@ -63,6 +63,9 @@ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); TRACE_EVENT0("audio", "audio::Service::OnStart") + // This will pre-create AudioManager if AudioManagerAccessor owns it. + CHECK(audio_manager_accessor_->GetAudioManager()); + metrics_ = std::make_unique<ServiceMetrics>(base::DefaultTickClock::GetInstance()); ref_factory_ = std::make_unique<service_manager::ServiceContextRefFactory>(
diff --git a/services/device/BUILD.gn b/services/device/BUILD.gn index 725a365..1091290 100644 --- a/services/device/BUILD.gn +++ b/services/device/BUILD.gn
@@ -84,16 +84,9 @@ "generic_sensor/platform_sensor_provider_unittest_android.cc", "generic_sensor/relative_orientation_euler_angles_fusion_algorithm_using_accelerometer_and_gyroscope_unittest.cc", "generic_sensor/relative_orientation_euler_angles_fusion_algorithm_using_accelerometer_unittest.cc", - "geolocation/geolocation_provider_impl_unittest.cc", "geolocation/geolocation_service_unittest.cc", - "geolocation/location_arbitrator_unittest.cc", - "geolocation/network_location_provider_unittest.cc", "geolocation/public_ip_address_geolocator_unittest.cc", "geolocation/public_ip_address_location_notifier_unittest.cc", - "geolocation/wifi_data_provider_chromeos_unittest.cc", - "geolocation/wifi_data_provider_common_unittest.cc", - "geolocation/wifi_data_provider_win_unittest.cc", - "geolocation/wifi_polling_policy_unittest.cc", "power_monitor/power_monitor_message_broadcaster_unittest.cc", "public/cpp/power_monitor/power_monitor_broadcast_source_unittest.cc", "vibration/vibration_manager_impl_unittest.cc", @@ -104,9 +97,9 @@ ":test_support", "//base", "//base/test:test_support", - "//base/third_party/dynamic_annotations", "//device/base/synchronization", - "//device/geolocation:test_support", + "//device/geolocation", + "//device/geolocation/public/cpp", "//mojo/edk", "//mojo/public/cpp/bindings", "//net", @@ -128,10 +121,7 @@ } if (is_linux && !is_chromeos && use_dbus) { - sources += [ - "battery/battery_status_manager_linux_unittest.cc", - "geolocation/wifi_data_provider_linux_unittest.cc", - ] + sources += [ "battery/battery_status_manager_linux_unittest.cc" ] deps += [ "//dbus:test_support" ] } @@ -146,14 +136,9 @@ } if (is_android) { - sources -= [ - "battery/battery_status_service_unittest.cc", - "geolocation/network_location_provider_unittest.cc", - "geolocation/wifi_data_provider_common_unittest.cc", - ] + sources -= [ "battery/battery_status_service_unittest.cc" ] deps += [ ":device_service_jni_headers", - "//device/geolocation/public/java:geolocation_java_test_support", "//services/device/vibration/android:vibration_jni_headers", ] } else {
diff --git a/services/device/geolocation/DEPS b/services/device/geolocation/DEPS index 79eaacde2..a352a55 100644 --- a/services/device/geolocation/DEPS +++ b/services/device/geolocation/DEPS
@@ -1,6 +1,4 @@ include_rules = [ "+chromeos", - "+dbus", "+net", - "+third_party/cros_system_api/dbus", ]
diff --git a/services/device/geolocation/public_ip_address_location_notifier_unittest.cc b/services/device/geolocation/public_ip_address_location_notifier_unittest.cc index 0709732d..3322b106 100644 --- a/services/device/geolocation/public_ip_address_location_notifier_unittest.cc +++ b/services/device/geolocation/public_ip_address_location_notifier_unittest.cc
@@ -17,7 +17,7 @@ #include "testing/gtest/include/gtest/gtest.h" namespace device { -namespace { + // Simple request context producer that immediately produces a // TestURLRequestContextGetter. void TestRequestContextProducer( @@ -29,8 +29,6 @@ network_task_runner)); } -} // namespace - class PublicIpAddressLocationNotifierTest : public testing::Test { protected: // Helps test a single call to
diff --git a/services/network/BUILD.gn b/services/network/BUILD.gn index 9f3ae58..53f09b0 100644 --- a/services/network/BUILD.gn +++ b/services/network/BUILD.gn
@@ -90,6 +90,8 @@ "tcp_server_socket.h", "throttling/network_conditions.cc", "throttling/network_conditions.h", + "throttling/scoped_throttling_token.cc", + "throttling/scoped_throttling_token.h", "throttling/throttling_controller.cc", "throttling/throttling_controller.h", "throttling/throttling_network_interceptor.cc",
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index 6098a48..9d13361 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -573,7 +573,7 @@ #endif // BUILDFLAG(ENABLE_REPORTING) void NetworkContext::SetNetworkConditions( - const std::string& profile_id, + const base::UnguessableToken& throttling_profile_id, mojom::NetworkConditionsPtr conditions) { std::unique_ptr<NetworkConditions> network_conditions; if (conditions) { @@ -581,7 +581,7 @@ conditions->offline, conditions->latency.InMillisecondsF(), conditions->download_throughput, conditions->upload_throughput)); } - ThrottlingController::SetConditions(profile_id, + ThrottlingController::SetConditions(throttling_profile_id, std::move(network_conditions)); }
diff --git a/services/network/network_context.h b/services/network/network_context.h index 7288bfff..44d9ea1 100644 --- a/services/network/network_context.h +++ b/services/network/network_context.h
@@ -33,6 +33,10 @@ #include "services/network/socket_factory.h" #include "services/network/url_request_context_owner.h" +namespace base { +class UnguessableToken; +} // namespace base + namespace net { class CertVerifier; class ReportSender; @@ -153,7 +157,7 @@ void ClearNetworkErrorLogging( mojom::ClearDataFilterPtr filter, ClearNetworkErrorLoggingCallback callback) override; - void SetNetworkConditions(const std::string& profile_id, + void SetNetworkConditions(const base::UnguessableToken& throttling_profile_id, mojom::NetworkConditionsPtr conditions) override; void SetAcceptLanguage(const std::string& new_accept_language) override; void SetEnableReferrers(bool enable_referrers) override;
diff --git a/services/network/network_service_unittest.cc b/services/network/network_service_unittest.cc index 7cf467c..abf2d0c 100644 --- a/services/network/network_service_unittest.cc +++ b/services/network/network_service_unittest.cc
@@ -817,11 +817,12 @@ } TEST_F(NetworkServiceTestWithService, SetNetworkConditions) { + const base::UnguessableToken profile_id = base::UnguessableToken::Create(); CreateNetworkContext(); mojom::NetworkConditionsPtr network_conditions = mojom::NetworkConditions::New(); network_conditions->offline = true; - context()->SetNetworkConditions("42", std::move(network_conditions)); + context()->SetNetworkConditions(profile_id, std::move(network_conditions)); ResourceRequest request; request.url = test_server()->GetURL("/nocache.html"); @@ -831,8 +832,7 @@ client()->RunUntilComplete(); EXPECT_EQ(net::OK, client()->completion_status().error_code); - request.headers.AddHeaderFromString( - "X-DevTools-Emulate-Network-Conditions-Client-Id: 42"); + request.throttling_profile_id = profile_id; StartLoadingURL(request, 0); client()->RunUntilComplete(); EXPECT_EQ(net::ERR_INTERNET_DISCONNECTED, @@ -840,22 +840,21 @@ network_conditions = mojom::NetworkConditions::New(); network_conditions->offline = false; - context()->SetNetworkConditions("42", std::move(network_conditions)); + context()->SetNetworkConditions(profile_id, std::move(network_conditions)); StartLoadingURL(request, 0); client()->RunUntilComplete(); EXPECT_EQ(net::OK, client()->completion_status().error_code); network_conditions = mojom::NetworkConditions::New(); network_conditions->offline = true; - context()->SetNetworkConditions("42", std::move(network_conditions)); + context()->SetNetworkConditions(profile_id, std::move(network_conditions)); - request.headers.AddHeaderFromString( - "X-DevTools-Emulate-Network-Conditions-Client-Id: 42"); + request.throttling_profile_id = profile_id; StartLoadingURL(request, 0); client()->RunUntilComplete(); EXPECT_EQ(net::ERR_INTERNET_DISCONNECTED, client()->completion_status().error_code); - context()->SetNetworkConditions("42", nullptr); + context()->SetNetworkConditions(profile_id, nullptr); StartLoadingURL(request, 0); client()->RunUntilComplete(); EXPECT_EQ(net::OK, client()->completion_status().error_code);
diff --git a/services/network/public/cpp/cors/cors.cc b/services/network/public/cpp/cors/cors.cc index 08b2f43..4af9236 100644 --- a/services/network/public/cpp/cors/cors.cc +++ b/services/network/public/cpp/cors/cors.cc
@@ -318,8 +318,7 @@ // Treat 'Intervention' as a CORS-safelisted header, since it is added by // Chrome when an intervention is (or may be) applied. static const std::set<std::string> safe_names = { - "accept", "accept-language", "content-language", - "x-devtools-emulate-network-conditions-client-id", "intervention", + "accept", "accept-language", "content-language", "intervention", "content-type", "save-data", // The Device Memory header field is a number that indicates the client’s // device memory i.e. approximate amount of ram in GiB. The header value
diff --git a/services/network/public/cpp/cors/cors_unittest.cc b/services/network/public/cpp/cors/cors_unittest.cc index da5d4597..8748d6c 100644 --- a/services/network/public/cpp/cors/cors_unittest.cc +++ b/services/network/public/cpp/cors/cors_unittest.cc
@@ -249,8 +249,6 @@ EXPECT_TRUE(cors::IsCORSSafelistedHeader("accept", "text/html")); EXPECT_TRUE(cors::IsCORSSafelistedHeader("Accept-Language", "en")); EXPECT_TRUE(cors::IsCORSSafelistedHeader("Content-Language", "ja")); - EXPECT_TRUE(cors::IsCORSSafelistedHeader( - "x-devtools-emulate-network-conditions-client-id", "")); EXPECT_TRUE(cors::IsCORSSafelistedHeader("SAVE-DATA", "on")); EXPECT_TRUE(cors::IsCORSSafelistedHeader("Intervention", "")); EXPECT_FALSE(cors::IsCORSSafelistedHeader("Cache-Control", ""));
diff --git a/services/network/public/cpp/network_ipc_param_traits.h b/services/network/public/cpp/network_ipc_param_traits.h index f0d52ca..4ec5cf9 100644 --- a/services/network/public/cpp/network_ipc_param_traits.h +++ b/services/network/public/cpp/network_ipc_param_traits.h
@@ -161,6 +161,7 @@ IPC_STRUCT_TRAITS_MEMBER(previews_state) IPC_STRUCT_TRAITS_MEMBER(initiated_in_secure_context) IPC_STRUCT_TRAITS_MEMBER(upgrade_if_insecure) + IPC_STRUCT_TRAITS_MEMBER(throttling_profile_id) IPC_STRUCT_TRAITS_END() IPC_STRUCT_TRAITS_BEGIN(network::ResourceResponseInfo)
diff --git a/services/network/public/cpp/resource_request.h b/services/network/public/cpp/resource_request.h index 2dc1e61e..72fee20 100644 --- a/services/network/public/cpp/resource_request.h +++ b/services/network/public/cpp/resource_request.h
@@ -11,6 +11,7 @@ #include "base/component_export.h" #include "base/memory/ref_counted.h" #include "base/optional.h" +#include "base/unguessable_token.h" #include "net/base/request_priority.h" #include "net/http/http_request_headers.h" #include "net/url_request/url_request.h" @@ -203,6 +204,9 @@ // Whether or not this request (including redirects) should be upgraded to // HTTPS due to an Upgrade-Insecure-Requests requirement. bool upgrade_if_insecure = false; + + // The profile ID of network conditions to throttle the network request. + base::Optional<base::UnguessableToken> throttling_profile_id; }; } // namespace network
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom index 444c4863..b44618b 100644 --- a/services/network/public/mojom/network_context.mojom +++ b/services/network/public/mojom/network_context.mojom
@@ -6,6 +6,7 @@ import "mojo/public/mojom/base/file.mojom"; import "mojo/public/mojom/base/file_path.mojom"; +import "mojo/public/mojom/base/unguessable_token.mojom"; import "mojo/public/mojom/base/values.mojom"; import "mojo/public/mojom/base/time.mojom"; import "net/interfaces/address_list.mojom"; @@ -369,12 +370,11 @@ ClearNetworkErrorLogging(ClearDataFilter? filter) => (); // Configures network conditions for the specified throttling profile. - // The throttling will be applied only to requests that have - // X-DevTools-Emulate-Network-Conditions-Client-Id: <profile_id> - // header with matching <profile_id>. + // The throttling will be applied only to requests that have maching + // throttling_profile_id. // Passing null NetworkConditions disables the throttling. - // TODO(caseq): get rid of header, make profile_id part of ResourceRequest. - SetNetworkConditions(string profile_id, NetworkConditions? conditions); + SetNetworkConditions(mojo_base.mojom.UnguessableToken throttling_profile_id, + NetworkConditions? conditions); // Updates the Accept-Language header to be used for requests. SetAcceptLanguage(string new_accept_language);
diff --git a/services/network/session_cleanup_cookie_store_unittest.cc b/services/network/session_cleanup_cookie_store_unittest.cc index b43363d..e3b8cce 100644 --- a/services/network/session_cleanup_cookie_store_unittest.cc +++ b/services/network/session_cleanup_cookie_store_unittest.cc
@@ -13,6 +13,7 @@ #include "base/task_scheduler/task_scheduler.h" #include "base/test/scoped_task_environment.h" #include "base/time/time.h" +#include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -126,6 +127,11 @@ cookies.clear(); } +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#define MAYBE_TestDeleteSessionCookies DISABLED_TestDeleteSessionCookies +#else +#define MAYBE_TestDeleteSessionCookies TestDeleteSessionCookies +#endif TEST_F(SessionCleanupCookieStoreTest, TestDeleteSessionCookies) { CanonicalCookieVector cookies = CreateAndLoad(); ASSERT_EQ(0u, cookies.size());
diff --git a/services/network/test/test_network_context.h b/services/network/test/test_network_context.h index c9f1636..308d32a 100644 --- a/services/network/test/test_network_context.h +++ b/services/network/test/test_network_context.h
@@ -65,7 +65,7 @@ void ClearNetworkErrorLogging( mojom::ClearDataFilterPtr filter, ClearNetworkErrorLoggingCallback callback) override {} - void SetNetworkConditions(const std::string& profile_id, + void SetNetworkConditions(const base::UnguessableToken& throttling_profile_id, mojom::NetworkConditionsPtr conditions) override {} void SetAcceptLanguage(const std::string& new_accept_language) override {} void SetEnableReferrers(bool enable_referrers) override {}
diff --git a/services/network/throttling/scoped_throttling_token.cc b/services/network/throttling/scoped_throttling_token.cc new file mode 100644 index 0000000..55f9caf --- /dev/null +++ b/services/network/throttling/scoped_throttling_token.cc
@@ -0,0 +1,37 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "services/network/throttling/scoped_throttling_token.h" + +#include "base/memory/ptr_util.h" +#include "base/unguessable_token.h" +#include "services/network/throttling/throttling_controller.h" + +namespace network { + +// static +std::unique_ptr<ScopedThrottlingToken> ScopedThrottlingToken::MaybeCreate( + uint32_t net_log_source_id, + const base::Optional<base::UnguessableToken>& throttling_profile_id) { + if (!throttling_profile_id) + return nullptr; + if (!ThrottlingController::HasInterceptor(*throttling_profile_id)) + return nullptr; + return base::WrapUnique( + new ScopedThrottlingToken(net_log_source_id, *throttling_profile_id)); +} + +ScopedThrottlingToken::ScopedThrottlingToken( + uint32_t net_log_source_id, + const base::UnguessableToken& throttling_profile_id) + : net_log_source_id_(net_log_source_id) { + ThrottlingController::RegisterProfileIDForNetLogSource(net_log_source_id, + throttling_profile_id); +} + +ScopedThrottlingToken::~ScopedThrottlingToken() { + ThrottlingController::UnregisterNetLogSource(net_log_source_id_); +} + +} // namespace network
diff --git a/services/network/throttling/scoped_throttling_token.h b/services/network/throttling/scoped_throttling_token.h new file mode 100644 index 0000000..69afce6 --- /dev/null +++ b/services/network/throttling/scoped_throttling_token.h
@@ -0,0 +1,46 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SERVICES_NETWORK_THROTTLING_SCOPED_THROTTLING_TOKEN_H_ +#define SERVICES_NETWORK_THROTTLING_SCOPED_THROTTLING_TOKEN_H_ + +#include <stdint.h> + +#include "base/component_export.h" +#include "base/macros.h" +#include "base/optional.h" + +namespace base { +class UnguessableToken; +} // namespace base + +namespace network { + +// A scoped class that calls +// ThrottlingController::RegisterProfileIDForNetLogSource() in the constructor, +// and ThrottlingController::UnregisterNetLogSource() in the destructor. +class COMPONENT_EXPORT(NETWORK_SERVICE) ScopedThrottlingToken { + public: + // If |throttling_profile_id| is nullopt or there is no network throttling + // conditions registered for the profile ID, returns nullptr. Otherwise + // returns a new ScopedThrottlingToken. It must be kept until + // ThrottlingNetworkTransaction::Start() will be called. + static std::unique_ptr<ScopedThrottlingToken> MaybeCreate( + uint32_t net_log_source_id, + const base::Optional<base::UnguessableToken>& throttling_profile_id); + + ~ScopedThrottlingToken(); + + private: + ScopedThrottlingToken(uint32_t net_log_source_id, + const base::UnguessableToken& throttling_profile_id); + + const uint32_t net_log_source_id_; + + DISALLOW_COPY_AND_ASSIGN(ScopedThrottlingToken); +}; + +} // namespace network + +#endif // SERVICES_NETWORK_THROTTLING_SCOPED_THROTTLING_TOKEN_H_
diff --git a/services/network/throttling/throttling_controller.cc b/services/network/throttling/throttling_controller.cc index d987131a..cc1d68ed 100644 --- a/services/network/throttling/throttling_controller.cc +++ b/services/network/throttling/throttling_controller.cc
@@ -4,10 +4,9 @@ #include "services/network/throttling/throttling_controller.h" -#include <utility> - #include "net/http/http_request_info.h" #include "services/network/throttling/network_conditions.h" +#include "services/network/throttling/scoped_throttling_token.h" #include "services/network/throttling/throttling_network_interceptor.h" namespace network { @@ -18,51 +17,100 @@ ThrottlingController::~ThrottlingController() = default; // static -ThrottlingNetworkInterceptor* ThrottlingController::GetInterceptor( - const std::string& client_id) { - if (!instance_ || client_id.empty()) - return nullptr; - return instance_->FindInterceptor(client_id); -} - -// static void ThrottlingController::SetConditions( - const std::string& client_id, + const base::UnguessableToken& throttling_profile_id, std::unique_ptr<NetworkConditions> conditions) { if (!instance_) { if (!conditions) return; instance_ = new ThrottlingController(); } - instance_->SetNetworkConditions(client_id, std::move(conditions)); + instance_->SetNetworkConditions(throttling_profile_id, std::move(conditions)); } -ThrottlingNetworkInterceptor* ThrottlingController::FindInterceptor( - const std::string& client_id) { +// static +base::Optional<base::UnguessableToken> +ThrottlingController::GetProfileIDForNetLogSource(uint32_t net_log_source_id) { + if (!instance_) + return base::nullopt; + return instance_->GetProfileID(net_log_source_id); +} + +// static +ThrottlingNetworkInterceptor* ThrottlingController::GetInterceptor( + uint32_t net_log_source_id) { + if (!instance_) + return nullptr; + return instance_->FindInterceptor(net_log_source_id); +} + +// static +void ThrottlingController::RegisterProfileIDForNetLogSource( + uint32_t net_log_source_id, + const base::UnguessableToken& throttling_profile_id) { + if (!instance_) + return; + instance_->Register(net_log_source_id, throttling_profile_id); +} + +// static +void ThrottlingController::UnregisterNetLogSource(uint32_t net_log_source_id) { + if (instance_) + instance_->Unregister(net_log_source_id); +} + +// static +bool ThrottlingController::HasInterceptor( + const base::UnguessableToken& throttling_profile_id) { + // Null |instance_| means there is no network condition registered. + if (!instance_) + return false; + return instance_->interceptors_.find(throttling_profile_id) != + instance_->interceptors_.end(); +} + +void ThrottlingController::Register( + uint32_t net_log_source_id, + const base::UnguessableToken& throttling_profile_id) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - auto it = interceptors_.find(client_id); - return it != interceptors_.end() ? it->second.get() : nullptr; + if (interceptors_.find(throttling_profile_id) == interceptors_.end()) + return; + net_log_source_profile_map_[net_log_source_id] = throttling_profile_id; +} + +void ThrottlingController::Unregister(uint32_t net_log_source_id) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + net_log_source_profile_map_.erase(net_log_source_id); +} + +base::Optional<base::UnguessableToken> ThrottlingController::GetProfileID( + uint32_t net_log_source_id) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + auto it = net_log_source_profile_map_.find(net_log_source_id); + if (it == net_log_source_profile_map_.end()) + return base::nullopt; + return it->second; } void ThrottlingController::SetNetworkConditions( - const std::string& client_id, + const base::UnguessableToken& throttling_profile_id, std::unique_ptr<NetworkConditions> conditions) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - auto it = interceptors_.find(client_id); + auto it = interceptors_.find(throttling_profile_id); if (it == interceptors_.end()) { if (!conditions) return; std::unique_ptr<ThrottlingNetworkInterceptor> new_interceptor( new ThrottlingNetworkInterceptor()); new_interceptor->UpdateConditions(std::move(conditions)); - interceptors_[client_id] = std::move(new_interceptor); + interceptors_[throttling_profile_id] = std::move(new_interceptor); } else { if (!conditions) { std::unique_ptr<NetworkConditions> online_conditions( new NetworkConditions()); it->second->UpdateConditions(std::move(online_conditions)); - interceptors_.erase(client_id); + interceptors_.erase(throttling_profile_id); if (interceptors_.empty()) { delete this; instance_ = nullptr; @@ -73,4 +121,15 @@ } } +ThrottlingNetworkInterceptor* ThrottlingController::FindInterceptor( + uint32_t net_log_source_id) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + auto source_profile_map_it = + net_log_source_profile_map_.find(net_log_source_id); + if (source_profile_map_it == net_log_source_profile_map_.end()) + return nullptr; + auto it = interceptors_.find(source_profile_map_it->second); + return it != interceptors_.end() ? it->second.get() : nullptr; +} + } // namespace network
diff --git a/services/network/throttling/throttling_controller.h b/services/network/throttling/throttling_controller.h index c627609..b058a23c 100644 --- a/services/network/throttling/throttling_controller.h +++ b/services/network/throttling/throttling_controller.h
@@ -11,39 +11,81 @@ #include "base/component_export.h" #include "base/macros.h" +#include "base/optional.h" #include "base/threading/thread_checker.h" +#include "base/unguessable_token.h" namespace network { class NetworkConditions; +class ScopedThrottlingToken; class ThrottlingNetworkInterceptor; -// ThrottlingController manages interceptors identified by client id -// and their throttling conditions. +// ThrottlingController manages interceptors identified by NetLog source ID and +// profile ID and their throttling conditions. class COMPONENT_EXPORT(NETWORK_SERVICE) ThrottlingController { public: // Applies network emulation configuration. - static void SetConditions(const std::string& client_id, + static void SetConditions(const base::UnguessableToken& throttling_profile_id, std::unique_ptr<NetworkConditions>); - static void DisableThrottling(const std::string& client_id); + // Returns the profile ID for the NetLog source ID. Returns an empty string if + // not registered. + // Note: This method is used only from ServiceWorkerFetchDispatcher to copy + // the profile ID from the net::URLRequest of original navigation request to + // the network::ResourceRequest of navigation preload request when + // S13nServiceWorker is not enabled. + // TODO(crbug/846235): Remove this method once S13nServiceWorker is shipped. + static base::Optional<base::UnguessableToken> GetProfileIDForNetLogSource( + uint32_t net_log_source_id); + + // Returns the interceptor for the NetLog source ID. static ThrottlingNetworkInterceptor* GetInterceptor( - const std::string& client_id); + uint32_t net_log_source_id); private: + friend class ScopedThrottlingToken; + ThrottlingController(); ~ThrottlingController(); - ThrottlingNetworkInterceptor* FindInterceptor(const std::string& client_id); - void SetNetworkConditions(const std::string& client_id, + // Registers the profile ID for the NetLog source. This is called from + // ScopedThrottlingToken. + static void RegisterProfileIDForNetLogSource( + uint32_t net_log_source_id, + const base::UnguessableToken& throttling_profile_id); + + // Unregister the NetLog source. This is called from ScopedThrottlingToken. + static void UnregisterNetLogSource(uint32_t net_log_source_id); + + // Returns whether there is an interceptor for the profile ID. This is called + // from ScopedThrottlingToken. + static bool HasInterceptor( + const base::UnguessableToken& throttling_profile_id); + + void Register(uint32_t net_log_source_id, + const base::UnguessableToken& throttling_profile_id); + void Unregister(uint32_t net_log_source_id); + + base::Optional<base::UnguessableToken> GetProfileID( + uint32_t net_log_source_id); + + void SetNetworkConditions(const base::UnguessableToken& throttling_profile_id, std::unique_ptr<NetworkConditions> conditions); + ThrottlingNetworkInterceptor* FindInterceptor(uint32_t net_log_source_id); + static ThrottlingController* instance_; using InterceptorMap = - std::map<std::string, std::unique_ptr<ThrottlingNetworkInterceptor>>; + std::map<base::UnguessableToken, + std::unique_ptr<ThrottlingNetworkInterceptor>>; + using NetLogSourceProfileMap = + std::map<uint32_t /* net_log_source_id */, + base::UnguessableToken /* throttling_profile_id */>; InterceptorMap interceptors_; + NetLogSourceProfileMap net_log_source_profile_map_; THREAD_CHECKER(thread_checker_); DISALLOW_COPY_AND_ASSIGN(ThrottlingController);
diff --git a/services/network/throttling/throttling_controller_unittest.cc b/services/network/throttling/throttling_controller_unittest.cc index 24638c7..1864e646 100644 --- a/services/network/throttling/throttling_controller_unittest.cc +++ b/services/network/throttling/throttling_controller_unittest.cc
@@ -17,8 +17,10 @@ #include "base/test/test_mock_time_task_runner.h" #include "net/base/chunked_upload_data_stream.h" #include "net/http/http_transaction_test_util.h" +#include "net/log/net_log.h" #include "net/log/net_log_with_source.h" #include "services/network/throttling/network_conditions.h" +#include "services/network/throttling/scoped_throttling_token.h" #include "services/network/throttling/throttling_network_interceptor.h" #include "services/network/throttling/throttling_network_transaction.h" #include "services/network/throttling/throttling_upload_data_stream.h" @@ -33,8 +35,6 @@ using net::MockTransaction; using net::TEST_MODE_SYNC_NET_START; -const char kClientId[] = "42"; -const char kAnotherClientId[] = "24"; const char kUploadData[] = "upload_data"; int64_t kUploadIdentifier = 17; @@ -53,18 +53,21 @@ int value_; }; -class ThrottlingControllerHelper { +class ThrottlingControllerTestHelper { public: - ThrottlingControllerHelper() + ThrottlingControllerTestHelper() : task_runner_(base::MakeRefCounted<base::TestMockTimeTaskRunner>()), completion_callback_( base::Bind(&TestCallback::Run, base::Unretained(&callback_))), mock_transaction_(kSimpleGET_Transaction), - buffer_(new net::IOBuffer(64)) { + buffer_(new net::IOBuffer(64)), + net_log_(std::make_unique<net::NetLog>()), + net_log_with_source_( + net::NetLogWithSource::Make(net_log_.get(), + net::NetLogSourceType::URL_REQUEST)), + profile_id_(base::UnguessableToken::Create()) { mock_transaction_.test_mode = TEST_MODE_SYNC_NET_START; mock_transaction_.url = "http://dot.com"; - mock_transaction_.request_headers = - "X-DevTools-Emulate-Network-Conditions-Client-Id: 42\r\n"; AddMockTransaction(&mock_transaction_); std::unique_ptr<net::HttpTransaction> network_transaction; @@ -78,10 +81,10 @@ void SetNetworkState(bool offline, double download, double upload) { std::unique_ptr<NetworkConditions> conditions( new NetworkConditions(offline, 0, download, upload)); - ThrottlingController::SetConditions(kClientId, std::move(conditions)); + ThrottlingController::SetConditions(profile_id_, std::move(conditions)); } - void SetNetworkState(const std::string& id, bool offline) { + void SetNetworkState(const base::UnguessableToken& id, bool offline) { std::unique_ptr<NetworkConditions> conditions( new NetworkConditions(offline)); ThrottlingController::SetConditions(id, std::move(conditions)); @@ -89,6 +92,8 @@ int Start(bool with_upload) { request_.reset(new MockHttpRequest(mock_transaction_)); + throttling_token_ = ScopedThrottlingToken::MaybeCreate( + net_log_with_source_.source().id, profile_id_); if (with_upload) { upload_data_stream_.reset( @@ -99,7 +104,7 @@ } int rv = transaction_->Start(request_.get(), completion_callback_, - net::NetLogWithSource()); + net_log_with_source_); EXPECT_EQ(with_upload, !!transaction_->custom_upload_data_stream_); return rv; } @@ -112,7 +117,7 @@ if (transaction_->interceptor_) return transaction_->interceptor_->IsOffline(); ThrottlingNetworkInterceptor* interceptor = - ThrottlingController::GetInterceptor(kClientId); + ThrottlingController::GetInterceptor(net_log_with_source_.source().id); EXPECT_TRUE(!!interceptor); return interceptor->IsOffline(); } @@ -130,7 +135,9 @@ completion_callback_); } - ~ThrottlingControllerHelper() { RemoveMockTransaction(&mock_transaction_); } + ~ThrottlingControllerTestHelper() { + RemoveMockTransaction(&mock_transaction_); + } TestCallback* callback() { return &callback_; } ThrottlingNetworkTransaction* transaction() { return transaction_.get(); } @@ -150,10 +157,14 @@ scoped_refptr<net::IOBuffer> buffer_; std::unique_ptr<net::ChunkedUploadDataStream> upload_data_stream_; std::unique_ptr<MockHttpRequest> request_; + std::unique_ptr<net::NetLog> net_log_; + std::unique_ptr<network::ScopedThrottlingToken> throttling_token_; + const net::NetLogWithSource net_log_with_source_; + const base::UnguessableToken profile_id_; }; TEST(ThrottlingControllerTest, SingleDisableEnable) { - ThrottlingControllerHelper helper; + ThrottlingControllerTestHelper helper; helper.SetNetworkState(false, 0, 0); helper.Start(false); @@ -167,23 +178,25 @@ } TEST(ThrottlingControllerTest, InterceptorIsolation) { - ThrottlingControllerHelper helper; + const base::UnguessableToken another_profile_id = + base::UnguessableToken::Create(); + ThrottlingControllerTestHelper helper; helper.SetNetworkState(false, 0, 0); helper.Start(false); EXPECT_FALSE(helper.ShouldFail()); - helper.SetNetworkState(kAnotherClientId, true); + helper.SetNetworkState(another_profile_id, true); EXPECT_FALSE(helper.ShouldFail()); helper.SetNetworkState(true, 0, 0); EXPECT_TRUE(helper.ShouldFail()); - helper.SetNetworkState(kAnotherClientId, false); + helper.SetNetworkState(another_profile_id, false); helper.SetNetworkState(false, 0, 0); base::RunLoop().RunUntilIdle(); } TEST(ThrottlingControllerTest, FailOnStart) { - ThrottlingControllerHelper helper; + ThrottlingControllerTestHelper helper; helper.SetNetworkState(true, 0, 0); int rv = helper.Start(false); @@ -194,7 +207,7 @@ } TEST(ThrottlingControllerTest, FailRunningTransaction) { - ThrottlingControllerHelper helper; + ThrottlingControllerTestHelper helper; helper.SetNetworkState(false, 0, 0); TestCallback* callback = helper.callback(); @@ -221,7 +234,7 @@ } TEST(ThrottlingControllerTest, ReadAfterFail) { - ThrottlingControllerHelper helper; + ThrottlingControllerTestHelper helper; helper.SetNetworkState(false, 0, 0); int rv = helper.Start(false); @@ -242,7 +255,7 @@ } TEST(ThrottlingControllerTest, CancelTransaction) { - ThrottlingControllerHelper helper; + ThrottlingControllerTestHelper helper; helper.SetNetworkState(false, 0, 0); int rv = helper.Start(false); @@ -257,7 +270,7 @@ } TEST(ThrottlingControllerTest, CancelFailedTransaction) { - ThrottlingControllerHelper helper; + ThrottlingControllerTestHelper helper; helper.SetNetworkState(true, 0, 0); int rv = helper.Start(false); @@ -272,7 +285,7 @@ } TEST(ThrottlingControllerTest, UploadDoesNotFail) { - ThrottlingControllerHelper helper; + ThrottlingControllerTestHelper helper; helper.SetNetworkState(true, 0, 0); int rv = helper.Start(true); EXPECT_EQ(rv, net::ERR_INTERNET_DISCONNECTED); @@ -281,7 +294,7 @@ } TEST(ThrottlingControllerTest, DownloadOnly) { - ThrottlingControllerHelper helper; + ThrottlingControllerTestHelper helper; TestCallback* callback = helper.callback(); helper.SetNetworkState(false, 10000000, 0); @@ -300,7 +313,7 @@ } TEST(ThrottlingControllerTest, UploadOnly) { - ThrottlingControllerHelper helper; + ThrottlingControllerTestHelper helper; TestCallback* callback = helper.callback(); helper.SetNetworkState(false, 0, 1000000);
diff --git a/services/network/throttling/throttling_network_transaction.cc b/services/network/throttling/throttling_network_transaction.cc index f0d98bb2..71720d8 100644 --- a/services/network/throttling/throttling_network_transaction.cc +++ b/services/network/throttling/throttling_network_transaction.cc
@@ -18,12 +18,6 @@ namespace network { -// Keep in sync with X_DevTools_Emulate_Network_Conditions_Client_Id defined in -// HTTPNames.json5. -const char - ThrottlingNetworkTransaction::kDevToolsEmulateNetworkConditionsClientId[] = - "X-DevTools-Emulate-Network-Conditions-Client-Id"; - ThrottlingNetworkTransaction::ThrottlingNetworkTransaction( std::unique_ptr<net::HttpTransaction> network_transaction) : throttled_byte_count_(0), @@ -118,15 +112,11 @@ DCHECK(request); request_ = request; - std::string client_id; - bool has_devtools_client_id = request_->extra_headers.HasHeader( - kDevToolsEmulateNetworkConditionsClientId); - if (has_devtools_client_id) { + ThrottlingNetworkInterceptor* interceptor = + ThrottlingController::GetInterceptor(net_log.source().id); + + if (interceptor) { custom_request_.reset(new net::HttpRequestInfo(*request_)); - custom_request_->extra_headers.GetHeader( - kDevToolsEmulateNetworkConditionsClientId, &client_id); - custom_request_->extra_headers.RemoveHeader( - kDevToolsEmulateNetworkConditionsClientId); if (request_->upload_data_stream) { custom_upload_data_stream_.reset( @@ -135,11 +125,7 @@ } request_ = custom_request_.get(); - } - ThrottlingNetworkInterceptor* interceptor = - ThrottlingController::GetInterceptor(client_id); - if (interceptor) { interceptor_ = interceptor->GetWeakPtr(); if (custom_upload_data_stream_) custom_upload_data_stream_->SetInterceptor(interceptor);
diff --git a/services/network/throttling/throttling_network_transaction.h b/services/network/throttling/throttling_network_transaction.h index df2dd1d7..dd1efe0 100644 --- a/services/network/throttling/throttling_network_transaction.h +++ b/services/network/throttling/throttling_network_transaction.h
@@ -34,7 +34,6 @@ namespace network { class ThrottlingController; -class ThrottlingControllerHelper; class ThrottlingUploadDataStream; // ThrottlingNetworkTransaction is a wrapper for network transaction. All @@ -45,8 +44,6 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) ThrottlingNetworkTransaction : public net::HttpTransaction { public: - static const char kDevToolsEmulateNetworkConditionsClientId[]; - explicit ThrottlingNetworkTransaction( std::unique_ptr<net::HttpTransaction> network_transaction); @@ -93,7 +90,7 @@ void GetConnectionAttempts(net::ConnectionAttempts* out) const override; protected: - friend class ThrottlingControllerHelper; + friend class ThrottlingControllerTestHelper; private: void Fail();
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc index ae4c8df..3ed58f465 100644 --- a/services/network/url_loader.cc +++ b/services/network/url_loader.cc
@@ -35,6 +35,7 @@ #include "services/network/public/cpp/resource_response.h" #include "services/network/public/mojom/url_loader_factory.mojom.h" #include "services/network/resource_scheduler_client.h" +#include "services/network/throttling/scoped_throttling_token.h" namespace network { @@ -340,6 +341,9 @@ url_request_->SetUserData(kUserDataKey, std::make_unique<UnownedPointer>(this)); + throttling_token_ = network::ScopedThrottlingToken::MaybeCreate( + url_request_->net_log().source().id, request.throttling_profile_id); + // Resolve elements from request_body and prepare upload data. if (request.request_body.get()) { scoped_refptr<base::SequencedTaskRunner> task_runner =
diff --git a/services/network/url_loader.h b/services/network/url_loader.h index 2d4fd12..f2add06e 100644 --- a/services/network/url_loader.h +++ b/services/network/url_loader.h
@@ -41,6 +41,7 @@ class NetworkUsageAccumulator; class KeepaliveStatisticsRecorder; struct ResourceResponse; +class ScopedThrottlingToken; class COMPONENT_EXPORT(NETWORK_SERVICE) URLLoader : public mojom::URLLoader, @@ -226,6 +227,8 @@ bool first_auth_attempt_; + std::unique_ptr<ScopedThrottlingToken> throttling_token_; + base::WeakPtrFactory<URLLoader> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(URLLoader);
diff --git a/services/resource_coordinator/memory_instrumentation/coordinator_impl_unittest.cc b/services/resource_coordinator/memory_instrumentation/coordinator_impl_unittest.cc index 7f88a88..eea3202 100644 --- a/services/resource_coordinator/memory_instrumentation/coordinator_impl_unittest.cc +++ b/services/resource_coordinator/memory_instrumentation/coordinator_impl_unittest.cc
@@ -10,6 +10,7 @@ #include "base/test/trace_event_analyzer.h" #include "base/threading/platform_thread.h" #include "base/time/time.h" +#include "base/time/time_override.h" #include "base/trace_event/memory_dump_request_args.h" #include "build/build_config.h" #include "mojo/public/cpp/bindings/binding.h" @@ -305,6 +306,17 @@ TEST_F(CoordinatorImplTest, QueuedRequest) { base::RunLoop run_loop; + // Override TimeTicks::Now with a timer that has extra_time added. + // This variable to be static as the lambda below has to convert to a function + // pointer rather than a functor. + static base::TimeDelta extra_time; + base::subtle::ScopedTimeClockOverrides time_override( + nullptr, + []() { + return base::subtle::TimeTicksNowIgnoringOverride() + extra_time; + }, + nullptr); + NiceMock<MockClientProcess> client_process_1(this, 1, mojom::ProcessType::BROWSER); NiceMock<MockClientProcess> client_process_2(this); @@ -316,9 +328,9 @@ .WillRepeatedly(Invoke( [](const MemoryDumpRequestArgs& args, MockClientProcess::RequestChromeMemoryDumpCallback& callback) { - // Delay the response here to make sure the start times are strictly - // increasing. - base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10)); + // Skip the wall clock time-ticks forward to make sure start_time + // is strictly increasing. + extra_time += base::TimeDelta::FromMilliseconds(10); MemoryDumpArgs dump_args{MemoryDumpLevelOfDetail::DETAILED}; auto pmd = std::make_unique<ProcessMemoryDump>(dump_args); std::move(callback).Run(true, args.dump_guid, std::move(pmd));
diff --git a/services/viz/privileged/interfaces/compositing/display_private.mojom b/services/viz/privileged/interfaces/compositing/display_private.mojom index 3c6ff4c..12498eaa 100644 --- a/services/viz/privileged/interfaces/compositing/display_private.mojom +++ b/services/viz/privileged/interfaces/compositing/display_private.mojom
@@ -46,19 +46,20 @@ }; interface DisplayClient { - OnDisplayReceivedCALayerParams(gfx.mojom.CALayerParams ca_layer_params); - // Notifies that a swap has occured after some latency info with snapshot // component reached the display. DidSwapAfterSnapshotRequestReceived(array<ui.mojom.LatencyInfo> latency_info); - // WINDOWS ONLY: Create a LayeredWindowUpdater implementation to draw into - // layered window. - // Note: This will only be used when running Windows 7 and earlier with - // software compositing and a transparent HWND. + [EnableIf=is_mac] + OnDisplayReceivedCALayerParams(gfx.mojom.CALayerParams ca_layer_params); + + // Creates a LayeredWindowUpdater implementation to draw into a layered + // window. + [EnableIf=is_win] CreateLayeredWindowUpdater(LayeredWindowUpdater& layered_window_updater); - // ANDROID ONLY: Notifies that a swap has occurred and provides information - // about the pixel size of the swapped frame. + // Notifies that a swap has occurred and provides information about the pixel + // size of the swapped frame. + [EnableIf=is_android] DidCompleteSwapWithSize(gfx.mojom.Size size); };
diff --git a/testing/buildbot/filters/browser_tests_cros_asan.filter b/testing/buildbot/filters/browser_tests_cros_asan.filter index 7cb65f4..e8cd0482 100644 --- a/testing/buildbot/filters/browser_tests_cros_asan.filter +++ b/testing/buildbot/filters/browser_tests_cros_asan.filter
@@ -3,3 +3,6 @@ # TODO(crbug.com/778405): Test is flaky on CrOS with ASan. -MemoryTracingBrowserTest.TestBackgroundMemoryInfra + +# TODO(crbug.com/807465): Test is flaky on CrOS with ASan in viz_browser_tests. +-ArcAccessibilityHelperBridgeBrowserTest.PreferenceChange
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 8547b74..aec6ae7 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -4741,9 +4741,8 @@ ], "experiments": [ { - "name": "WorkStealingAndBackgroundCompile", + "name": "Enabled2", "enable_features": [ - "V8BackgroundCompile", "WorkStealingInScriptRunner" ] }
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG index ca15cf9..e9f5f61 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -8,7 +8,6 @@ crbug.com/591099 fast/text/apply-start-width-after-skipped-text.html [ Skip ] # Failures due to 'bad' tests. These tests should be removed/change once we've landed LayoutNG. -crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-004.html [ Failure Pass ] crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-inset-rounded-bottom-right.html [ Failure ] crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-inset-rounded-top-right.html [ Failure ] @@ -338,6 +337,7 @@ crbug.com/591099 external/wpt/editing/run/justifyfull.html [ Pass ] crbug.com/591099 external/wpt/editing/run/justifyright.html [ Pass ] crbug.com/591099 external/wpt/editing/run/multitest.html [ Pass ] +crbug.com/591099 external/wpt/geolocation-API/PositionOptions.https.html [ Pass ] crbug.com/591099 external/wpt/html-media-capture/capture_audio_cancel-manual.html [ Failure ] crbug.com/591099 external/wpt/html-media-capture/capture_image_cancel-manual.html [ Failure ] crbug.com/591099 external/wpt/html-media-capture/capture_video_cancel-manual.html [ Failure ] @@ -366,6 +366,7 @@ crbug.com/591099 external/wpt/shadow-dom/DocumentOrShadowRoot-prototype-elementFromPoint.html [ Failure ] crbug.com/591099 external/wpt/webaudio/the-audio-api/the-mediaelementaudiosourcenode-interface/mediaElementAudioSourceToScriptProcessorTest.html [ Pass ] crbug.com/591099 external/wpt/webrtc/interfaces.html [ Pass Timeout ] +crbug.com/591099 external/wpt/websockets/opening-handshake/003-sets-origin.worker.html [ Pass ] crbug.com/591099 external/wpt/xhr/abort-after-stop.htm [ Pass ] crbug.com/591099 external/wpt/xhr/send-authentication-prompt-2-manual.htm [ Failure ] crbug.com/591099 fast/backgrounds/background-clip-text.html [ Failure ] @@ -582,8 +583,8 @@ crbug.com/591099 fast/table/fixed-table-layout/table-with-percent-width.html [ Failure ] crbug.com/591099 fast/table/height-percent-test-vertical.html [ Failure ] crbug.com/591099 fast/table/large-shrink-wrapped-width.html [ Failure ] -crbug.com/591099 fast/table/percent-height-overflow-auto-content-in-cell.html [ Failure ] -crbug.com/591099 fast/table/percent-height-overflow-scroll-content-in-cell.html [ Failure ] +crbug.com/591099 fast/table/percent-height-overflow-auto-content-in-cell.html [ Failure Pass ] +crbug.com/591099 fast/table/percent-height-overflow-scroll-content-in-cell.html [ Failure Pass ] crbug.com/591099 fast/table/percent-height-replaced-content-in-cell.html [ Failure ] crbug.com/591099 fast/table/table-display-types-vertical.html [ Failure ] crbug.com/591099 fast/table/unbreakable-images-quirk.html [ Failure ] @@ -650,7 +651,7 @@ crbug.com/591099 http/tests/devtools/tracing/timeline-paint/timeline-paint-with-layout-invalidations.js [ Failure ] crbug.com/591099 http/tests/devtools/tracing/timeline-paint/timeline-paint-with-style-recalc-invalidations.js [ Failure ] crbug.com/591099 http/tests/images/restyle-decode-error.html [ Failure ] -crbug.com/783102 http/tests/incremental/frame-focus-before-load.html [ Timeout ] +crbug.com/783102 http/tests/incremental/frame-focus-before-load.html [ Pass Timeout ] crbug.com/591099 http/tests/incremental/slow-utf8-text.pl [ Pass Timeout ] crbug.com/591099 http/tests/loading/nested_bad_objects.php [ Failure ] crbug.com/591099 http/tests/loading/preload-picture-nested.html [ Failure ] @@ -668,6 +669,7 @@ crbug.com/591099 http/tests/permissions/test-api-surface.html [ Pass ] crbug.com/591099 http/tests/security/cors-rfc1918/addressspace-document-appcache.https.html [ Crash Failure ] crbug.com/591099 http/tests/security/cors-rfc1918/addressspace-document-csp-appcache.https.html [ Crash Failure Pass ] +crbug.com/591099 http/tests/security/setDomainRelaxationForbiddenForURLScheme.html [ Pass ] crbug.com/591099 http/tests/security/xssAuditor/block-does-not-leak-location.html [ Failure ] crbug.com/591099 http/tests/websocket/invalid-subprotocol-characters.html [ Pass Timeout ] crbug.com/714962 images/color-profile-background-clip-text.html [ Failure ] @@ -862,9 +864,9 @@ crbug.com/591099 paint/invalidation/table/table-shrink-row-repaint.html [ Failure ] crbug.com/591099 paint/invalidation/table/table-two-pass-layout-overpaint.html [ Failure ] crbug.com/591099 paint/invalidation/text-append-dirty-lines.html [ Failure ] -crbug.com/714962 paint/invalidation/text-match-pre-wrapped-text.html [ Failure ] -crbug.com/714962 paint/invalidation/text-match-transparent-text.html [ Failure ] -crbug.com/714962 paint/invalidation/text-match.html [ Failure ] +crbug.com/714962 paint/invalidation/text-match-pre-wrapped-text.html [ Failure Pass ] +crbug.com/714962 paint/invalidation/text-match-transparent-text.html [ Failure Pass ] +crbug.com/714962 paint/invalidation/text-match.html [ Failure Pass ] crbug.com/591099 paint/invalidation/transform/change-transform.html [ Failure ] crbug.com/591099 paint/invalidation/transform/transform-inline-layered-child.html [ Crash ] crbug.com/591099 paint/invalidation/transform/transform-layout-repaint.html [ Failure ] @@ -883,7 +885,7 @@ crbug.com/591099 paint/markers/ellipsis-mixed-text-in-rtl-flow-with-markers.html [ Failure ] crbug.com/591099 paint/markers/ellipsis-rtl-text-in-ltr-flow-with-markers.html [ Failure ] crbug.com/591099 paint/markers/ellipsis-rtl-text-in-rtl-flow-with-markers.html [ Failure ] -crbug.com/591099 paint/markers/first-letter.html [ Failure ] +crbug.com/591099 paint/markers/first-letter.html [ Failure Pass ] crbug.com/591099 paint/overflow/background-mask-should-be-recorded-full.html [ Failure ] crbug.com/591099 paint/pagination/pagination-change-clip-crash.html [ Failure ] crbug.com/714962 paint/text/text-match-highlights-big-line-height.html [ Failure ] @@ -892,8 +894,8 @@ crbug.com/591099 scrollbars/auto-scrollbar-fit-content.html [ Failure ] crbug.com/591099 scrollbars/scrollbar-miss-mousemove-disabled.html [ Failure ] crbug.com/591099 shapedetection/detection-HTMLVideoElement.html [ Pass ] -crbug.com/591099 storage/indexeddb/cursor-continue-validity.html [ Pass Timeout ] -crbug.com/591099 storage/indexeddb/index-cursor.html [ Timeout ] +crbug.com/591099 storage/indexeddb/cursor-continue-validity.html [ Timeout ] +crbug.com/591099 storage/indexeddb/index-cursor.html [ Pass Timeout ] crbug.com/591099 storage/indexeddb/mozilla/indexes.html [ Timeout ] crbug.com/591099 storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Timeout ] crbug.com/591099 storage/indexeddb/objectstore-cursor.html [ Pass ] @@ -909,7 +911,7 @@ crbug.com/591099 svg/in-html/sizing/svg-inline.html [ Failure ] crbug.com/714962 svg/text/tspan-multiple-outline.svg [ Failure ] crbug.com/591099 svg/transforms/text-with-pattern-inside-transformed-html.xhtml [ Failure ] -crbug.com/591099 svg/wicd/rightsizing-grid.html [ Failure ] +crbug.com/591099 svg/wicd/rightsizing-grid.html [ Failure Pass ] crbug.com/591099 svg/zoom/page/zoom-img-preserveAspectRatio-support-1.html [ Failure ] crbug.com/591099 svg/zoom/page/zoom-svg-through-object-with-absolute-size-2.xhtml [ Failure ] crbug.com/591099 svg/zoom/page/zoom-svg-through-object-with-absolute-size.xhtml [ Failure ] @@ -955,6 +957,7 @@ crbug.com/591099 virtual/mouseevent_fractional/fast/events/wheel/mainthread-touchpad-fling-latching.html [ Pass ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/wheel/wheel-scroll-latching-on-scrollbar.html [ Pass ] crbug.com/591099 virtual/new-remote-playback-pipeline/ [ Skip ] +crbug.com/591099 virtual/off-main-thread-websocket/external/wpt/websockets/opening-handshake/003-sets-origin.worker.html [ Pass ] crbug.com/591099 virtual/off-main-thread-websocket/http/tests/websocket/invalid-subprotocol-characters.html [ Pass Timeout ] crbug.com/591099 virtual/outofblink-cors/ [ Skip ] crbug.com/591099 virtual/paint-timing/external/wpt/paint-timing/sibling-painting-first-image.html [ Failure ] @@ -965,6 +968,15 @@ crbug.com/591099 virtual/spv2/paint/invalidation/box/margin.html [ Failure Pass ] crbug.com/591099 virtual/stable/ [ Skip ] crbug.com/591099 virtual/threaded/ [ Skip ] +crbug.com/591099 virtual/user-activation-v2/fast/events/background-tab-on-submit-ctrl-click.html [ Failure ] +crbug.com/591099 virtual/user-activation-v2/fast/events/background-tab-on-submit-synthesized-ctrl-click.html [ Failure ] +crbug.com/591099 virtual/user-activation-v2/fast/events/event-on-culled_inline.html [ Failure ] +crbug.com/591099 virtual/user-activation-v2/fast/events/mouse-cursor.html [ Failure ] +crbug.com/591099 virtual/user-activation-v2/fast/events/mouse-relative-position.html [ Failure ] +crbug.com/591099 virtual/user-activation-v2/fast/events/onclick-list-marker.html [ Failure ] +crbug.com/591099 virtual/user-activation-v2/fast/events/select-element.html [ Failure ] +crbug.com/591099 virtual/user-activation-v2/fast/events/sequential-focus-navigation-starting-point.html [ Failure ] +crbug.com/591099 virtual/user-activation-v2/fast/events/touch/compositor-touch-hit-rects.html [ Failure ] crbug.com/591099 virtual/video-surface-layer/media/audio-controls-rendering.html [ Failure ] crbug.com/591099 virtual/video-surface-layer/media/media-document-audio-repaint.html [ Failure ] crbug.com/591099 virtual/video-surface-layer/media/picture-in-picture/picture-in-picture-enabled.html [ Pass ]
diff --git a/third_party/WebKit/LayoutTests/SlowTests b/third_party/WebKit/LayoutTests/SlowTests index 36f2852f..c4551e30 100644 --- a/third_party/WebKit/LayoutTests/SlowTests +++ b/third_party/WebKit/LayoutTests/SlowTests
@@ -507,3 +507,9 @@ crbug.com/626703 external/wpt/html/semantics/scripting-1/the-script-element/async_010.htm [ Slow ] crbug.com/840792 [ Mac10.12 Mac10.13 ] external/wpt/pointerevents/pointerevent_touch-action-table-test_touch-manual.html [ Slow ] + +# These tests take 90 seconds on MSAN due to a large amount of JS execution. +crbug.com/853977 [ Linux ] http/tests/fetch/chromium/call-extra-crash-tee.html [ Slow ] +crbug.com/853977 [ Linux ] http/tests/fetch/chromium/release-handle-crash.html [ Slow ] +crbug.com/838057 [ Linux ] virtual/outofblink-cors/http/tests/fetch/chromium/call-extra-crash-tee.html [ Slow ] +crbug.com/838057 [ Linux ] virtual/outofblink-cors/http/tests/fetch/chromium/release-handle-crash.html [ Slow ] \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 97c4e0ce..f6e3fa8d 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -2829,9 +2829,11 @@ crbug.com/805463 external/wpt/acid/acid3/numbered-tests.html [ Skip ] -crbug.com/829567 [ Linux Win ] fast/events/touch/scroll-without-mouse-lacks-mousemove-events.html [ Pass Failure ] -crbug.com/829567 [ Linux Win ] virtual/mouseevent_fractional/fast/events/touch/scroll-without-mouse-lacks-mousemove-events.html [ Pass Failure ] -crbug.com/829567 [ Linux Win ] virtual/scroll_customization/fast/events/touch/scroll-without-mouse-lacks-mousemove-events.html [ Pass Failure ] +crbug.com/828506 [ Linux Win ] fast/events/touch/scroll-without-mouse-lacks-mousemove-events.html [ Pass Failure ] +crbug.com/828506 [ Linux Win ] virtual/mouseevent_fractional/fast/events/touch/scroll-without-mouse-lacks-mousemove-events.html [ Pass Failure ] +crbug.com/828506 [ Linux Win ] virtual/scroll_customization/fast/events/touch/scroll-without-mouse-lacks-mousemove-events.html [ Pass Failure ] +crbug.com/828506 [ Linux Win ] virtual/user-activation-v2/fast/events/touch/scroll-without-mouse-lacks-mousemove-events.html [ Pass Failure ] + # Failure messages are unstable so we cannot create baselines. crbug.com/832071 external/wpt/service-workers/service-worker/worker-client-id.https.html [ Failure ] @@ -4006,6 +4008,8 @@ crbug.com/718155 virtual/video-surface-layer/media/video-controls-fullscreen-iframe-not-allowed.html [ Failure ] crbug.com/718155 virtual/android/fullscreen/full-screen-iframe-not-allowed.html [ Failure ] crbug.com/718155 virtual/android/fullscreen/full-screen-restrictions.html [ Failure Timeout ] +crbug.com/718155 virtual/user-activation-v2/fullscreen/full-screen-iframe-not-allowed.html [ Failure ] +crbug.com/718155 virtual/user-activation-v2/fullscreen/full-screen-restrictions.html [ Failure Timeout ] # Feature Policy changes same-origin allowpaymentrequest behaviour, tests need updating crbug.com/718155 payments/payment-request-in-iframe.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/VirtualTestSuites b/third_party/WebKit/LayoutTests/VirtualTestSuites index 9643e35..6685943 100644 --- a/third_party/WebKit/LayoutTests/VirtualTestSuites +++ b/third_party/WebKit/LayoutTests/VirtualTestSuites
@@ -682,6 +682,11 @@ }, { "prefix": "user-activation-v2", + "base": "fullscreen", + "args": ["--enable-features=UserActivationV2"] + }, + { + "prefix": "user-activation-v2", "base": "user-activation-v2", "args": ["--enable-features=UserActivationV2"] },
diff --git a/third_party/WebKit/LayoutTests/animations/stability/transition-var-gradient-crash.html b/third_party/WebKit/LayoutTests/animations/stability/transition-var-gradient-crash.html new file mode 100644 index 0000000..2350af2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/animations/stability/transition-var-gradient-crash.html
@@ -0,0 +1,19 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<style> +#target { + background-image: linear-gradient(var(--, black), white); + transition: color 1s; +} +</style> +<div id="target"></div> +<script> +'use strict'; +test(() => { + getComputedStyle(target).color; + target.style.color = 'green'; + getComputedStyle(target).color; +}, 'Don\'t crash when transitioning with a var linear-gradient.'); +</script> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index 9269b685..791d3020 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -6831,6 +6831,18 @@ {} ] ], + "css/CSS2/abspos/remove-block-between-inline-and-abspos.html": [ + [ + "/css/CSS2/abspos/remove-block-between-inline-and-abspos.html", + [ + [ + "/css/reference/ref-filled-green-200px-square.html", + "==" + ] + ], + {} + ] + ], "css/CSS2/abspos/table-caption-is-containing-block-001.html": [ [ "/css/CSS2/abspos/table-caption-is-containing-block-001.html", @@ -10279,6 +10291,18 @@ {} ] ], + "css/CSS2/floats/remove-block-between-inline-and-float.html": [ + [ + "/css/CSS2/floats/remove-block-between-inline-and-float.html", + [ + [ + "/css/reference/ref-filled-green-200px-square.html", + "==" + ] + ], + {} + ] + ], "css/CSS2/floats/zero-width-floats.html": [ [ "/css/CSS2/floats/zero-width-floats.html", @@ -109834,6 +109858,11 @@ {} ] ], + "css/css-animations/idlharness-expected.txt": [ + [ + {} + ] + ], "css/css-animations/support/testcommon.js": [ [ {} @@ -111509,6 +111538,11 @@ {} ] ], + "css/css-conditional/idlharness-expected.txt": [ + [ + {} + ] + ], "css/css-conditional/reference/background-lime.html": [ [ {} @@ -141649,6 +141683,16 @@ {} ] ], + "feature-policy/resources/feature-policy-usb-worker.html": [ + [ + {} + ] + ], + "feature-policy/resources/feature-policy-usb-worker.js": [ + [ + {} + ] + ], "feature-policy/resources/feature-policy-usb.html": [ [ {} @@ -142399,6 +142443,16 @@ {} ] ], + "fetch/cors-rfc1918/idlharness.tentative.any-expected.txt": [ + [ + {} + ] + ], + "fetch/cors-rfc1918/idlharness.tentative.any.worker-expected.txt": [ + [ + {} + ] + ], "fetch/cross-origin-resource-policy/fetch-expected.txt": [ [ {} @@ -157209,6 +157263,21 @@ {} ] ], + "interfaces/cors-rfc1918.idl": [ + [ + {} + ] + ], + "interfaces/css-animations.idl": [ + [ + {} + ] + ], + "interfaces/css-conditional.idl": [ + [ + {} + ] + ], "interfaces/css-font-loading.idl": [ [ {} @@ -157229,6 +157298,11 @@ {} ] ], + "interfaces/css-transitions.idl": [ + [ + {} + ] + ], "interfaces/css-typed-om.idl": [ [ {} @@ -169964,6 +170038,16 @@ {} ] ], + "webusb/resources/usb-allowed-by-feature-policy-worker.js": [ + [ + {} + ] + ], + "webusb/resources/usb-disabled-by-feature-policy-worker.js": [ + [ + {} + ] + ], "webusb/resources/usb-helpers.js": [ [ {} @@ -187038,6 +187122,12 @@ {} ] ], + "css/css-animations/idlharness.html": [ + [ + "/css/css-animations/idlharness.html", + {} + ] + ], "css/css-animations/pending-style-changes-001.html": [ [ "/css/css-animations/pending-style-changes-001.html", @@ -187394,6 +187484,12 @@ {} ] ], + "css/css-conditional/idlharness.html": [ + [ + "/css/css-conditional/idlharness.html", + {} + ] + ], "css/css-conditional/js/001.html": [ [ "/css/css-conditional/js/001.html", @@ -187988,6 +188084,12 @@ {} ] ], + "css/css-fonts/font-shorthand-serialization-font-stretch.html": [ + [ + "/css/css-fonts/font-shorthand-serialization-font-stretch.html", + {} + ] + ], "css/css-fonts/font-variant-alternates-parsing.html": [ [ "/css/css-fonts/font-variant-alternates-parsing.html", @@ -192638,6 +192740,12 @@ {} ] ], + "css/css-transitions/idlharness.html": [ + [ + "/css/css-transitions/idlharness.html", + {} + ] + ], "css/css-transitions/properties-value-001.html": [ [ "/css/css-transitions/properties-value-001.html", @@ -194948,6 +195056,12 @@ {} ] ], + "css/css-values/calc-rounding-001.html": [ + [ + "/css/css-values/calc-rounding-001.html", + {} + ] + ], "css/css-values/calc-serialization.html": [ [ "/css/css-values/calc-serialization.html", @@ -209514,6 +209628,16 @@ {} ] ], + "fetch/cors-rfc1918/idlharness.tentative.any.js": [ + [ + "/fetch/cors-rfc1918/idlharness.tentative.any.html", + {} + ], + [ + "/fetch/cors-rfc1918/idlharness.tentative.any.worker.html", + {} + ] + ], "fetch/cross-origin-resource-policy/fetch-in-iframe.html": [ [ "/fetch/cross-origin-resource-policy/fetch-in-iframe.html", @@ -268136,7 +268260,7 @@ "support" ], "FileAPI/OWNERS": [ - "f340bcedd53a21c10c03764d047e2c0c1648628d", + "f3913e32695775691051ca12a9aeb22ff28dc098", "support" ], "FileAPI/blob/Blob-constructor-endings.html": [ @@ -268260,7 +268384,7 @@ "testharness" ], "FileAPI/reading-data-section/filereader_readAsDataURL.html": [ - "52371f9c51952984ea5cb07e2a6e3d8dfcf50d16", + "883decab747ac39e6cf9c946f309e7a26c4257f7", "testharness" ], "FileAPI/reading-data-section/filereader_readAsText.html": [ @@ -276695,6 +276819,10 @@ "44f94feef0ef941a7ac86e1c466dc75e729ba647", "reftest" ], + "css/CSS2/abspos/remove-block-between-inline-and-abspos.html": [ + "79f37a2375f2fbcb133b3926cd7c77a6696eb4aa", + "reftest" + ], "css/CSS2/abspos/table-caption-is-containing-block-001.html": [ "d416e3d830bf172326723ed469d6a5f02de7e9e1", "reftest" @@ -279391,6 +279519,10 @@ "357427f1d71d7137c1ba4c386ae25acc7712928e", "reftest" ], + "css/CSS2/floats/remove-block-between-inline-and-float.html": [ + "3d605f7fcda537953ed52f99772c88bad49e1062", + "reftest" + ], "css/CSS2/floats/zero-space-between-floats-001.html": [ "59cd6c4ac06a611570a3ec21bac7289345b184f7", "testharness" @@ -291275,6 +291407,14 @@ "0115580619b629e47ae0f2635cc84e1e80442a8f", "testharness" ], + "css/css-animations/idlharness-expected.txt": [ + "ecc74ca06a5597b14f48691ce03c5c24bd317510", + "support" + ], + "css/css-animations/idlharness.html": [ + "75e949c1edef367f29d23a1c4921fe7748c78a3f", + "testharness" + ], "css/css-animations/pending-style-changes-001.html": [ "5f2bf4b6712dd230109be62407cd31800451a271", "testharness" @@ -295787,6 +295927,14 @@ "a8e29f1bf5e6e6b4dec9da57036e8d95359f561b", "reftest" ], + "css/css-conditional/idlharness-expected.txt": [ + "2f1d5114b539f4802fd053cfdbe29c8da0eed9eb", + "support" + ], + "css/css-conditional/idlharness.html": [ + "3952fffe4e25eb06467eb2136f63d63c2bfa8191", + "testharness" + ], "css/css-conditional/js/001.html": [ "8da103d0787969a76df019c6d83aa59dd3884a52", "testharness" @@ -300103,6 +300251,10 @@ "003d315d72019673041c63b28a90f436c7e3855f", "testharness" ], + "css/css-fonts/font-shorthand-serialization-font-stretch.html": [ + "478f7730ecd2a733d7f41a75d46ecb2facb6936d", + "testharness" + ], "css/css-fonts/font-size-adjust-001-ref.html": [ "f477ee1d0669cc35acc873d267a5a9e7bcac8dae", "support" @@ -326055,6 +326207,10 @@ "971be3c362daabff565737c0d98be96e2356adb8", "testharness" ], + "css/css-transitions/idlharness.html": [ + "ff6ec5d0e21891ea44637ad97187957c86add0a4", + "testharness" + ], "css/css-transitions/properties-value-001-expected.txt": [ "0e2c13ff5054e8c3b2608ed158686a291c876634", "support" @@ -330851,6 +331007,10 @@ "6fa668d2bcaf01f5c4680e3e14a0e86160d1b5d5", "reftest" ], + "css/css-values/calc-rounding-001.html": [ + "a74b631cd97db18ef120a0a5e7132c9e14b67f81", + "testharness" + ], "css/css-values/calc-serialization-expected.txt": [ "d38b12521063bf2abf97c7481a84977c796296a7", "support" @@ -350179,6 +350339,14 @@ "057973ef7f86c3628948c54d5697fb565e6d0a96", "support" ], + "feature-policy/resources/feature-policy-usb-worker.html": [ + "66c45d83b3ff35d9fb02c52a138b60d393ac42f1", + "support" + ], + "feature-policy/resources/feature-policy-usb-worker.js": [ + "06ff374448653063d8dfe1b0bc9d26cc4ac1baa0", + "support" + ], "feature-policy/resources/feature-policy-usb.html": [ "96ae900bcde19a4ffcab30f1d01b393e07936e99", "support" @@ -351355,6 +351523,18 @@ "465d933f4e52ef4e5a4bd0de40873410195843cd", "testharness" ], + "fetch/cors-rfc1918/idlharness.tentative.any-expected.txt": [ + "ba818428eb9f8eac61c102543676bfc8a8f3969e", + "support" + ], + "fetch/cors-rfc1918/idlharness.tentative.any.js": [ + "08d7db9d67437d64350503f153abfd7015a0d27e", + "testharness" + ], + "fetch/cors-rfc1918/idlharness.tentative.any.worker-expected.txt": [ + "7ea2c38ed1ab46551f94f8e1d00b11ceb22f5106", + "support" + ], "fetch/cross-origin-resource-policy/fetch-expected.txt": [ "25175c716e6e001e25dc48a247f2409e8f890b0d", "support" @@ -373159,6 +373339,18 @@ "bb4c385873deafd746f186058b111193c8aebf01", "support" ], + "interfaces/cors-rfc1918.idl": [ + "d7f133c8dd6e1656f82c077d9795714827b9c869", + "support" + ], + "interfaces/css-animations.idl": [ + "520ed1f6d245c75551aed3f74f988026edf3ff59", + "support" + ], + "interfaces/css-conditional.idl": [ + "0019e54201874e5d2a2b10c887e44b8c42199c32", + "support" + ], "interfaces/css-font-loading.idl": [ "9f2f252c5b63c159d9680de46a932bfa4335bf11", "support" @@ -373175,6 +373367,10 @@ "9939fb7f08cab0f167e6e0762eac6ad94b2dfd9f", "support" ], + "interfaces/css-transitions.idl": [ + "54dd701233a71187c8b675ebbf7336f852a7cace", + "support" + ], "interfaces/css-typed-om.idl": [ "36526913c07a04f9fd329a5650430db82407d766", "support" @@ -373268,7 +373464,7 @@ "support" ], "interfaces/mediacapture-main.idl": [ - "3400c775504ebf32af3f8e1165a53ca60f258495", + "a2a5e12acdc863828532e28574ed4904f0b0b2b8", "support" ], "interfaces/mediasession.idl": [ @@ -374452,11 +374648,11 @@ "testharness" ], "mediacapture-fromelement/idlharness-expected.txt": [ - "36d6f2375c122b2702ae26685bf3f17f748bc0b7", + "376a117c08d7dfcd8e245d18b71bb3eeaece3cc2", "support" ], "mediacapture-fromelement/idlharness.html": [ - "ceeb48e7982eb88561f4c1630cb0fcf15d9cf73c", + "c6b4b7ac4a8caa64fcf662a75ae746acf953c943", "testharness" ], "mediacapture-image/META.yml": [ @@ -374472,7 +374668,7 @@ "support" ], "mediacapture-image/idlharness.html": [ - "7ccf7fcab0344a2e1893e89d7689e2312287b64d", + "bdbb04fda38eacb634b40a12497501b0fe7f0384", "testharness" ], "mediacapture-record/BlobEvent-constructor.html": [ @@ -374492,7 +374688,7 @@ "support" ], "mediacapture-record/idlharness.html": [ - "99adc299359aad8cdd4f08ba920dde780bd06063", + "b47e6c73bca3b00e2cd6c4fa5fd746abb803c99c", "testharness" ], "mediacapture-streams/GUM-api.https.html": [ @@ -374536,11 +374732,11 @@ "support" ], "mediacapture-streams/MediaDevices-IDL-all-expected.txt": [ - "fa2c7f735bff9cf534cea9d16e6d2838050a2a02", + "fd460e66932f5068d58fdb5721c4688243ce1f36", "support" ], "mediacapture-streams/MediaDevices-IDL-all.html": [ - "42f245551c0d64377f949efda4cfad4934323b48", + "9c67c8e7fe285c5bad2497408a830d1d20dcc103", "testharness" ], "mediacapture-streams/MediaDevices-IDL-enumerateDevices-expected.txt": [ @@ -405335,20 +405531,28 @@ "6e6050f742e0da58fc94a5c0a0aa75f16dfcede9", "support" ], + "webusb/resources/usb-allowed-by-feature-policy-worker.js": [ + "05b1cecd77688ef9942bb1d563a2d8ef47df0ad7", + "support" + ], + "webusb/resources/usb-disabled-by-feature-policy-worker.js": [ + "b8c11fa9ff9e33168bb8ef6e7c18f98d27a77838", + "support" + ], "webusb/resources/usb-helpers.js": [ "7a5878c9f4c472bafa8f3db026573feba8e746b0", "support" ], "webusb/usb-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html": [ - "fda5a143afa30b86a318b3ab74baed513a5275bb", + "bb86e36bfa4fcc9ba022a589565bfaba1584d4dc", "testharness" ], "webusb/usb-allowed-by-feature-policy-attribute.https.sub.html": [ - "9e891075241bb843a283193506250285e93740e2", + "6080cc1f628040b3c5b3c01668588429f10e7b49", "testharness" ], "webusb/usb-allowed-by-feature-policy.https.sub.html": [ - "dce5c37e64183ea3d698ef8cc5b751c506a495ed", + "ff891b8b3366f96cd378d0167047a022add35406", "testharness" ], "webusb/usb-allowed-by-feature-policy.https.sub.html.headers": [ @@ -405360,7 +405564,7 @@ "testharness" ], "webusb/usb-disabled-by-feature-policy.https.sub.html": [ - "414b0b8087cbfa333e205a7b42d838c5f8108cf7", + "0000c10f217eb0e53013578d83cfa2ac37147fea", "testharness" ], "webusb/usb-disabled-by-feature-policy.https.sub.html.headers": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-animations/idlharness-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/css/css-animations/idlharness-expected.txt new file mode 100644 index 0000000..dde0732 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-animations/idlharness-expected.txt
@@ -0,0 +1,48 @@ +This is a testharness.js-based test. +PASS Test css-animations IDL implementation +PASS Partial interface CSSRule: original interface defined +FAIL Partial interface GlobalEventHandlers: original interface defined assert_true: Original interface should be defined expected true got false +PASS AnimationEvent interface: existence and properties of interface object +PASS AnimationEvent interface object length +PASS AnimationEvent interface object name +PASS AnimationEvent interface: existence and properties of interface prototype object +PASS AnimationEvent interface: existence and properties of interface prototype object's "constructor" property +PASS AnimationEvent interface: existence and properties of interface prototype object's @@unscopables property +PASS AnimationEvent interface: attribute animationName +PASS Unscopable handled correctly for animationName property on AnimationEvent +PASS AnimationEvent interface: attribute elapsedTime +PASS Unscopable handled correctly for elapsedTime property on AnimationEvent +PASS AnimationEvent interface: attribute pseudoElement +PASS Unscopable handled correctly for pseudoElement property on AnimationEvent +PASS CSSKeyframeRule interface: existence and properties of interface object +PASS CSSKeyframeRule interface object length +PASS CSSKeyframeRule interface object name +PASS CSSKeyframeRule interface: existence and properties of interface prototype object +PASS CSSKeyframeRule interface: existence and properties of interface prototype object's "constructor" property +PASS CSSKeyframeRule interface: existence and properties of interface prototype object's @@unscopables property +PASS CSSKeyframeRule interface: attribute keyText +PASS Unscopable handled correctly for keyText property on CSSKeyframeRule +PASS CSSKeyframeRule interface: attribute style +PASS Unscopable handled correctly for style property on CSSKeyframeRule +PASS CSSKeyframesRule interface: existence and properties of interface object +PASS CSSKeyframesRule interface object length +PASS CSSKeyframesRule interface object name +PASS CSSKeyframesRule interface: existence and properties of interface prototype object +PASS CSSKeyframesRule interface: existence and properties of interface prototype object's "constructor" property +PASS CSSKeyframesRule interface: existence and properties of interface prototype object's @@unscopables property +PASS CSSKeyframesRule interface: attribute name +PASS Unscopable handled correctly for name property on CSSKeyframesRule +PASS CSSKeyframesRule interface: attribute cssRules +PASS Unscopable handled correctly for cssRules property on CSSKeyframesRule +PASS CSSKeyframesRule interface: operation appendRule(CSSOMString) +PASS Unscopable handled correctly for appendRule(CSSOMString) on CSSKeyframesRule +PASS CSSKeyframesRule interface: operation deleteRule(CSSOMString) +PASS Unscopable handled correctly for deleteRule(CSSOMString) on CSSKeyframesRule +PASS CSSKeyframesRule interface: operation findRule(CSSOMString) +PASS Unscopable handled correctly for findRule(CSSOMString) on CSSKeyframesRule +PASS CSSRule interface: constant KEYFRAMES_RULE on interface object +PASS CSSRule interface: constant KEYFRAMES_RULE on interface prototype object +PASS CSSRule interface: constant KEYFRAME_RULE on interface object +PASS CSSRule interface: constant KEYFRAME_RULE on interface prototype object +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-animations/idlharness.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-animations/idlharness.html new file mode 100644 index 0000000..2c6191d4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-animations/idlharness.html
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <title>css-animations IDL tests</title> + <link rel="help" href="https://drafts.csswg.org/css-animations/"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/resources/WebIDLParser.js"></script> + <script src="/resources/idlharness.js"></script> +</head> + +<body> + <div id="log"></div> + + <script> + 'use strict'; + + promise_test(async () => { + const idl = await fetch('/interfaces/css-animations.idl').then(r => r.text()); + const cssom = await fetch('/interfaces/cssom.idl').then(r => r.text()); + const dom = await fetch('/interfaces/dom.idl').then(r => r.text()); + + const idl_array = new IdlArray(); + idl_array.add_idls(idl); + idl_array.add_dependency_idls(cssom); + idl_array.add_dependency_idls(dom); + + idl_array.test(); + }, 'Test css-animations IDL implementation'); + </script> + +</body> + +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-conditional/idlharness-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/css/css-conditional/idlharness-expected.txt new file mode 100644 index 0000000..4dd5d161 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-conditional/idlharness-expected.txt
@@ -0,0 +1,46 @@ +This is a testharness.js-based test. +PASS Test css-conditional IDL implementation +PASS Partial interface CSSRule: original interface defined +PASS Partial interface CSS: original interface defined +PASS CSSGroupingRule interface: existence and properties of interface object +PASS CSSGroupingRule interface object length +PASS CSSGroupingRule interface object name +PASS CSSGroupingRule interface: existence and properties of interface prototype object +PASS CSSGroupingRule interface: existence and properties of interface prototype object's "constructor" property +PASS CSSGroupingRule interface: existence and properties of interface prototype object's @@unscopables property +PASS CSSGroupingRule interface: attribute cssRules +PASS Unscopable handled correctly for cssRules property on CSSGroupingRule +PASS CSSGroupingRule interface: operation insertRule(CSSOMString, unsigned long) +PASS Unscopable handled correctly for insertRule(CSSOMString, unsigned long) on CSSGroupingRule +PASS CSSGroupingRule interface: operation deleteRule(unsigned long) +PASS Unscopable handled correctly for deleteRule(unsigned long) on CSSGroupingRule +PASS CSSConditionRule interface: existence and properties of interface object +PASS CSSConditionRule interface object length +PASS CSSConditionRule interface object name +PASS CSSConditionRule interface: existence and properties of interface prototype object +PASS CSSConditionRule interface: existence and properties of interface prototype object's "constructor" property +PASS CSSConditionRule interface: existence and properties of interface prototype object's @@unscopables property +FAIL CSSConditionRule interface: attribute conditionText assert_equals: setter must be function for PutForwards, Replaceable, or non-readonly attributes expected "function" but got "undefined" +PASS Unscopable handled correctly for conditionText property on CSSConditionRule +PASS CSSMediaRule interface: existence and properties of interface object +PASS CSSMediaRule interface object length +PASS CSSMediaRule interface object name +PASS CSSMediaRule interface: existence and properties of interface prototype object +PASS CSSMediaRule interface: existence and properties of interface prototype object's "constructor" property +PASS CSSMediaRule interface: existence and properties of interface prototype object's @@unscopables property +PASS CSSMediaRule interface: attribute media +PASS Unscopable handled correctly for media property on CSSMediaRule +PASS CSSSupportsRule interface: existence and properties of interface object +PASS CSSSupportsRule interface object length +PASS CSSSupportsRule interface object name +PASS CSSSupportsRule interface: existence and properties of interface prototype object +PASS CSSSupportsRule interface: existence and properties of interface prototype object's "constructor" property +PASS CSSSupportsRule interface: existence and properties of interface prototype object's @@unscopables property +PASS CSSRule interface: constant SUPPORTS_RULE on interface object +PASS CSSRule interface: constant SUPPORTS_RULE on interface prototype object +PASS CSS interface: operation supports(CSSOMString, CSSOMString) +PASS Unscopable handled correctly for supports(CSSOMString, CSSOMString) on CSS +PASS CSS interface: operation supports(CSSOMString) +PASS Unscopable handled correctly for supports(CSSOMString) on CSS +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-conditional/idlharness.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-conditional/idlharness.html new file mode 100644 index 0000000..410466b --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-conditional/idlharness.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <title>css-conditional IDL tests</title> + <link rel="help" href="https://drafts.csswg.org/css-conditional/"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/resources/WebIDLParser.js"></script> + <script src="/resources/idlharness.js"></script> +</head> + +<body> + <div id="log"></div> + + <script> + 'use strict'; + promise_test(async () => { + const idl = await fetch('/interfaces/css-conditional.idl').then(r => r.text()); + const cssom = await fetch('/interfaces/cssom.idl').then(r => r.text()); + const dom = await fetch('/interfaces/dom.idl').then(r => r.text()); + const idl_array = new IdlArray(); + idl_array.add_idls(idl); + idl_array.add_dependency_idls(cssom); + idl_array.add_dependency_idls(dom); + idl_array.test(); + }, 'Test css-conditional IDL implementation'); + </script> + +</body> + +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/font-shorthand-serialization-font-stretch.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/font-shorthand-serialization-font-stretch.html new file mode 100644 index 0000000..f5fff421 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/font-shorthand-serialization-font-stretch.html
@@ -0,0 +1,39 @@ +<!doctype html> +<meta charset="utf-8"> +<title>CSS Test: font shorthand serialization with font-stretch values</title> +<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#propdef-font"> +<link rel="help" href="https://drafts.csswg.org/cssom-1/#serializing-css-values"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="test" style="font: medium serif"></div> +<script> +test(function() { + const div = document.getElementById("test"); + div.style.fontStretch = "50%"; + assert_equals(div.style.font, "ultra-condensed medium serif"); + div.style.fontStretch = "62.5%"; + assert_equals(div.style.font, "extra-condensed medium serif"); + div.style.fontStretch = "75%"; + assert_equals(div.style.font, "condensed medium serif"); + div.style.fontStretch = "87.5%"; + assert_equals(div.style.font, "semi-condensed medium serif"); + div.style.fontStretch = "100%"; + assert_equals(div.style.font, "medium serif", "The keyword normal should be omitted"); + div.style.fontStretch = "112.5%"; + assert_equals(div.style.font, "semi-expanded medium serif"); + div.style.fontStretch = "125%"; + assert_equals(div.style.font, "expanded medium serif"); + div.style.fontStretch = "150%"; + assert_equals(div.style.font, "extra-expanded medium serif"); + div.style.fontStretch = "200%"; + assert_equals(div.style.font, "ultra-expanded medium serif"); +}, "Percentages which can be transformed into keywords should be for serialization"); + +test(function() { + const div = document.getElementById("test"); + div.style.fontStretch = "25%"; + assert_equals(div.style.font, ""); + div.style.fontStretch = "101%"; + assert_equals(div.style.font, ""); +}, "Percentages which cannot be transformed into keywords should prevent the font shorthand from serializing"); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-transitions/idlharness.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-transitions/idlharness.html new file mode 100644 index 0000000..36178b7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-transitions/idlharness.html
@@ -0,0 +1,23 @@ +<!doctype html> +<title>css-transitions IDL tests</title> +<link rel="help" href="https://drafts.csswg.org/css-transitions/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/WebIDLParser.js"></script> +<script src="/resources/idlharness.js"></script> +<script> + "use strict"; + + promise_test(async () => { + const idl_array = new IdlArray(); + const idl = await fetch("/interfaces/css-transitions.idl").then(r => r.text()); + const cssom = await fetch("/interfaces/cssom.idl").then(r => r.text()); + const html = await fetch("/interfaces/html.idl").then(r => r.text()); + const dom = await fetch("/interfaces/dom.idl").then(r => r.text()); + idl_array.add_idls(idl); + idl_array.add_dependency_idls(cssom); + idl_array.add_dependency_idls(html); + idl_array.add_dependency_idls(dom); + idl_array.test(); + }, "Test IDL implementation of css-transitions API"); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-values/calc-rounding-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-values/calc-rounding-001.html new file mode 100644 index 0000000..dfd03a69 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-values/calc-rounding-001.html
@@ -0,0 +1,43 @@ +<!doctype html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<meta charset="utf-8"> +<title>CSS Test: calc rounding doesn't accumulate a lot of error.</title> +<link rel="author" href="mailto:mats@mozilla.com" title="Mats Palmgren"> +<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez"> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1323735"> +<link rel="help" href="https://drafts.csswg.org/css-values/#funcdef-calc"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +body { + background: #f3f5f6; +} + +div { + font-size: 15px; + width: 401px; + margin: 20px; + background: #fff; + display: flex; + flex-wrap: wrap; +} + +b { + height: 50px; + background: red; + width: calc((100% - 4.5em) / 4); /* .5em gutters */ +} + +b:not(:last-child) { + margin-right: 1.5em; +} +</style> +<div><b></b><b></b><b></b><b></b></div> +<script> + test(function() { + assert_equals(document.querySelector("div").offsetHeight, 50); + }, "calc() doesn't accumulate much error that makes flex items overflow"); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/cors-rfc1918/idlharness.tentative.any-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/fetch/cors-rfc1918/idlharness.tentative.any-expected.txt new file mode 100644 index 0000000..cc390d4d --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/fetch/cors-rfc1918/idlharness.tentative.any-expected.txt
@@ -0,0 +1,11 @@ +This is a testharness.js-based test. +PASS Test CORS RFC1918 interfaces +PASS Partial interface Document: original interface defined +PASS Partial interface WorkerGlobalScope: original interface defined +PASS WorkerGlobalScope interface: existence and properties of interface object +PASS WorkerGlobalScope interface: self must not have property "addressSpace" +FAIL Document interface: attribute addressSpace assert_true: The prototype object must have a property "addressSpace" expected true got false +PASS Unscopable handled correctly for addressSpace property on Document +FAIL Document interface: document must inherit property "addressSpace" with the proper type assert_inherits: property "addressSpace" not found in prototype chain +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/cors-rfc1918/idlharness.tentative.any.js b/third_party/WebKit/LayoutTests/external/wpt/fetch/cors-rfc1918/idlharness.tentative.any.js new file mode 100644 index 0000000..c1acdee --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/fetch/cors-rfc1918/idlharness.tentative.any.js
@@ -0,0 +1,20 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +promise_test(async () => { + const idl = await fetch('/interfaces/cors-rfc1918.idl').then(r => r.text()); + const html = await fetch('/interfaces/html.idl').then(r => r.text()); + const dom = await fetch('/interfaces/dom.idl').then(r => r.text()); + + const idlArray = new IdlArray(); + idlArray.add_idls(idl); + idlArray.add_dependency_idls(html); + idlArray.add_dependency_idls(dom); + + const objects = { + Document: ['document'], + WorkerGlobalScope: ['self'], + }; + idlArray.add_objects(objects); + idlArray.test(); +}, 'Test CORS RFC1918 interfaces');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/cors-rfc1918/idlharness.tentative.any.worker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/fetch/cors-rfc1918/idlharness.tentative.any.worker-expected.txt new file mode 100644 index 0000000..74d942b --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/fetch/cors-rfc1918/idlharness.tentative.any.worker-expected.txt
@@ -0,0 +1,12 @@ +This is a testharness.js-based test. +PASS Test CORS RFC1918 interfaces +PASS Partial interface Document: original interface defined +PASS Partial interface WorkerGlobalScope: original interface defined +FAIL WorkerGlobalScope interface: attribute addressSpace assert_true: The prototype object must have a property "addressSpace" expected true got false +PASS Unscopable handled correctly for addressSpace property on WorkerGlobalScope +FAIL WorkerGlobalScope interface: self must inherit property "addressSpace" with the proper type assert_inherits: property "addressSpace" not found in prototype chain +PASS Node interface: existence and properties of interface object +PASS Document interface: existence and properties of interface object +FAIL Document interface: document must not have property "addressSpace" assert_equals: Unexpected exception when evaluating object expected null but got object "ReferenceError: document is not defined" +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/cors-rfc1918.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/cors-rfc1918.idl new file mode 100644 index 0000000..f00d4fa --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/cors-rfc1918.idl
@@ -0,0 +1,14 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content of this file was automatically extracted from the +// "CORS and RFC1918" spec. +// See: https://wicg.github.io/cors-rfc1918/ + +enum AddressSpace { "local", "private", "public" }; + +partial interface Document { + readonly attribute AddressSpace addressSpace; +}; + +partial interface WorkerGlobalScope { + readonly attribute AddressSpace addressSpace; +};
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/css-animations.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/css-animations.idl new file mode 100644 index 0000000..3162c9e --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/css-animations.idl
@@ -0,0 +1,45 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content of this file was automatically extracted from the +// "CSS Animations Level 1" spec. +// See: https://drafts.csswg.org/css-animations/ + +[Exposed=Window, + Constructor(CSSOMString type, optional AnimationEventInit animationEventInitDict)] +interface AnimationEvent : Event { + readonly attribute CSSOMString animationName; + readonly attribute double elapsedTime; + readonly attribute CSSOMString pseudoElement; +}; +dictionary AnimationEventInit : EventInit { + CSSOMString animationName = ""; + double elapsedTime = 0.0; + CSSOMString pseudoElement = ""; +}; + +partial interface CSSRule { + const unsigned short KEYFRAMES_RULE = 7; + const unsigned short KEYFRAME_RULE = 8; +}; + +[Exposed=Window] +interface CSSKeyframeRule : CSSRule { + attribute CSSOMString keyText; + [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style; +}; + +[Exposed=Window] +interface CSSKeyframesRule : CSSRule { + attribute CSSOMString name; + readonly attribute CSSRuleList cssRules; + + void appendRule(CSSOMString rule); + void deleteRule(CSSOMString select); + CSSKeyframeRule? findRule(CSSOMString select); +}; + +partial interface GlobalEventHandlers { + attribute EventHandler onanimationstart; + attribute EventHandler onanimationiteration; + attribute EventHandler onanimationend; + attribute EventHandler onanimationcancel; +};
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/css-conditional.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/css-conditional.idl new file mode 100644 index 0000000..6671de29 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/css-conditional.idl
@@ -0,0 +1,33 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content of this file was automatically extracted from the CSS Conditional Rules spec. +// See https://drafts.csswg.org/css-conditional/ + +partial interface CSSRule { + const unsigned short SUPPORTS_RULE = 12; +}; + +[Exposed=Window] +interface CSSGroupingRule : CSSRule { + readonly attribute CSSRuleList cssRules; + unsigned long insertRule (CSSOMString rule, unsigned long index); + void deleteRule (unsigned long index); +}; + +[Exposed=Window] +interface CSSConditionRule : CSSGroupingRule { + attribute CSSOMString conditionText; +}; + +[Exposed=Window] +interface CSSMediaRule : CSSConditionRule { + [SameObject, PutForwards=mediaText] readonly attribute MediaList media; +}; + +[Exposed=Window] +interface CSSSupportsRule : CSSConditionRule { +}; + +partial interface CSS { + static boolean supports(CSSOMString property, CSSOMString value); + static boolean supports(CSSOMString conditionText); +};
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/css-transitions.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/css-transitions.idl new file mode 100644 index 0000000..478318d9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/css-transitions.idl
@@ -0,0 +1,25 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content of this file was automatically extracted from the +// "CSS Transitions" spec. +// See: https://drafts.csswg.org/css-transitions/ + +[Exposed=Window, + Constructor(CSSOMString type, optional TransitionEventInit transitionEventInitDict)] +interface TransitionEvent : Event { + readonly attribute CSSOMString propertyName; + readonly attribute double elapsedTime; + readonly attribute CSSOMString pseudoElement; +}; + +dictionary TransitionEventInit : EventInit { + CSSOMString propertyName = ""; + double elapsedTime = 0.0; + CSSOMString pseudoElement = ""; +}; + +partial interface GlobalEventHandlers { + attribute EventHandler ontransitionrun; + attribute EventHandler ontransitionstart; + attribute EventHandler ontransitionend; + attribute EventHandler ontransitioncancel; +};
diff --git a/third_party/WebKit/LayoutTests/external/wpt/interfaces/mediacapture-main.idl b/third_party/WebKit/LayoutTests/external/wpt/interfaces/mediacapture-main.idl index 0513f8fa..d5e39e3 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/interfaces/mediacapture-main.idl +++ b/third_party/WebKit/LayoutTests/external/wpt/interfaces/mediacapture-main.idl
@@ -1,39 +1,43 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content of this file was automatically extracted from the Media Capture and Streams spec. +// See https://w3c.github.io/mediacapture-main/ + [Exposed=Window, Constructor, - Constructor(MediaStream stream), - Constructor(sequence<MediaStreamTrack> tracks)] + Constructor (MediaStream stream), + Constructor (sequence<MediaStreamTrack> tracks)] interface MediaStream : EventTarget { - readonly attribute DOMString id; - sequence<MediaStreamTrack> getAudioTracks(); - sequence<MediaStreamTrack> getVideoTracks(); - sequence<MediaStreamTrack> getTracks(); - MediaStreamTrack? getTrackById(DOMString trackId); - void addTrack(MediaStreamTrack track); - void removeTrack(MediaStreamTrack track); - MediaStream clone(); - readonly attribute boolean active; - attribute EventHandler onaddtrack; - attribute EventHandler onremovetrack; + readonly attribute DOMString id; + sequence<MediaStreamTrack> getAudioTracks (); + sequence<MediaStreamTrack> getVideoTracks (); + sequence<MediaStreamTrack> getTracks (); + MediaStreamTrack? getTrackById (DOMString trackId); + void addTrack (MediaStreamTrack track); + void removeTrack (MediaStreamTrack track); + MediaStream clone (); + readonly attribute boolean active; + attribute EventHandler onaddtrack; + attribute EventHandler onremovetrack; }; [Exposed=Window] interface MediaStreamTrack : EventTarget { - readonly attribute DOMString kind; - readonly attribute DOMString id; - readonly attribute DOMString label; - attribute boolean enabled; - readonly attribute boolean muted; - attribute EventHandler onmute; - attribute EventHandler onunmute; - readonly attribute MediaStreamTrackState readyState; - attribute EventHandler onended; - MediaStreamTrack clone(); - void stop(); - MediaTrackCapabilities getCapabilities(); - MediaTrackConstraints getConstraints(); - MediaTrackSettings getSettings(); - Promise<void> applyConstraints(optional MediaTrackConstraints constraints); - attribute EventHandler onoverconstrained; + readonly attribute DOMString kind; + readonly attribute DOMString id; + readonly attribute DOMString label; + attribute boolean enabled; + readonly attribute boolean muted; + attribute EventHandler onmute; + attribute EventHandler onunmute; + readonly attribute MediaStreamTrackState readyState; + attribute EventHandler onended; + MediaStreamTrack clone (); + void stop (); + MediaTrackCapabilities getCapabilities (); + MediaTrackConstraints getConstraints (); + MediaTrackSettings getSettings (); + Promise<void> applyConstraints (optional MediaTrackConstraints constraints); + attribute EventHandler onoverconstrained; }; enum MediaStreamTrackState { @@ -42,71 +46,83 @@ }; dictionary MediaTrackSupportedConstraints { - boolean width = true; - boolean height = true; - boolean aspectRatio = true; - boolean frameRate = true; - boolean facingMode = true; - boolean volume = true; - boolean sampleRate = true; - boolean sampleSize = true; - boolean echoCancellation = true; - boolean latency = true; - boolean channelCount = true; - boolean deviceId = true; - boolean groupId = true; + boolean width = true; + boolean height = true; + boolean aspectRatio = true; + boolean frameRate = true; + boolean facingMode = true; + boolean resizeMode = true; + boolean volume = true; + boolean sampleRate = true; + boolean sampleSize = true; + boolean echoCancellation = true; + boolean autoGainControl = true; + boolean noiseSuppression = true; + boolean latency = true; + boolean channelCount = true; + boolean deviceId = true; + boolean groupId = true; }; dictionary MediaTrackCapabilities { - LongRange width; - LongRange height; - DoubleRange aspectRatio; - DoubleRange frameRate; - sequence<DOMString> facingMode; - DoubleRange volume; - LongRange sampleRate; - LongRange sampleSize; - sequence<boolean> echoCancellation; - DoubleRange latency; - LongRange channelCount; - DOMString deviceId; - DOMString groupId; + ULongRange width; + ULongRange height; + DoubleRange aspectRatio; + DoubleRange frameRate; + sequence<DOMString> facingMode; + sequence<DOMString> resizeMode; + DoubleRange volume; + ULongRange sampleRate; + ULongRange sampleSize; + sequence<boolean> echoCancellation; + sequence<boolean> autoGainControl; + sequence<boolean> noiseSuppression; + DoubleRange latency; + ULongRange channelCount; + DOMString deviceId; + DOMString groupId; }; -dictionary MediaTrackConstraints : MediaTrackConstraintSet { - sequence<MediaTrackConstraintSet> advanced; + dictionary MediaTrackConstraints : MediaTrackConstraintSet { + sequence<MediaTrackConstraintSet> advanced; }; dictionary MediaTrackConstraintSet { - ConstrainLong width; - ConstrainLong height; - ConstrainDouble aspectRatio; - ConstrainDouble frameRate; - ConstrainDOMString facingMode; - ConstrainDouble volume; - ConstrainLong sampleRate; - ConstrainLong sampleSize; - ConstrainBoolean echoCancellation; - ConstrainDouble latency; - ConstrainLong channelCount; - ConstrainDOMString deviceId; - ConstrainDOMString groupId; + ConstrainULong width; + ConstrainULong height; + ConstrainDouble aspectRatio; + ConstrainDouble frameRate; + ConstrainDOMString facingMode; + ConstrainDOMString resizeMode; + ConstrainDouble volume; + ConstrainULong sampleRate; + ConstrainULong sampleSize; + ConstrainBoolean echoCancellation; + ConstrainBoolean autoGainControl; + ConstrainBoolean noiseSuppression; + ConstrainDouble latency; + ConstrainULong channelCount; + ConstrainDOMString deviceId; + ConstrainDOMString groupId; }; dictionary MediaTrackSettings { - long width; - long height; - double aspectRatio; - double frameRate; - DOMString facingMode; - double volume; - long sampleRate; - long sampleSize; - boolean echoCancellation; - double latency; - long channelCount; - DOMString deviceId; - DOMString groupId; + long width; + long height; + double aspectRatio; + double frameRate; + DOMString facingMode; + DOMString resizeMode; + double volume; + long sampleRate; + long sampleSize; + boolean echoCancellation; + boolean autoGainControl; + boolean noiseSuppression; + double latency; + long channelCount; + DOMString deviceId; + DOMString groupId; }; enum VideoFacingModeEnum { @@ -116,11 +132,16 @@ "right" }; +enum VideoResizeModeEnum { + "none", + "crop-and-scale" +}; + [Exposed=Window, - Constructor(DOMString type, MediaStreamTrackEventInit eventInitDict)] + Constructor (DOMString type, MediaStreamTrackEventInit eventInitDict)] interface MediaStreamTrackEvent : Event { [SameObject] - readonly attribute MediaStreamTrack track; + readonly attribute MediaStreamTrack track; }; dictionary MediaStreamTrackEventInit : EventInit { @@ -128,36 +149,35 @@ }; [Exposed=Window, - Constructor(DOMString type, OverconstrainedErrorEventInit eventInitDict)] + Constructor (DOMString type, OverconstrainedErrorEventInit eventInitDict)] interface OverconstrainedErrorEvent : Event { - readonly attribute OverconstrainedError? error; + readonly attribute OverconstrainedError? error; }; dictionary OverconstrainedErrorEventInit : EventInit { - OverconstrainedError? error = null; + OverconstrainedError? error = null; }; -[Exposed=Window, - NoInterfaceObject] +[Exposed=Window, NoInterfaceObject] interface NavigatorUserMedia { [SameObject] - readonly attribute MediaDevices mediaDevices; + readonly attribute MediaDevices mediaDevices; }; Navigator implements NavigatorUserMedia; [Exposed=Window] interface MediaDevices : EventTarget { - attribute EventHandler ondevicechange; - Promise<sequence<MediaDeviceInfo>> enumerateDevices(); + attribute EventHandler ondevicechange; + Promise<sequence<MediaDeviceInfo>> enumerateDevices (); }; [Exposed=Window] interface MediaDeviceInfo { - readonly attribute DOMString deviceId; - readonly attribute MediaDeviceKind kind; - readonly attribute DOMString label; - readonly attribute DOMString groupId; + readonly attribute DOMString deviceId; + readonly attribute MediaDeviceKind kind; + readonly attribute DOMString label; + readonly attribute DOMString groupId; [Default] object toJSON(); }; @@ -167,25 +187,22 @@ "videoinput" }; -[Exposed=Window] -interface InputDeviceInfo : MediaDeviceInfo { - MediaTrackCapabilities getCapabilities(); + [Exposed=Window] interface InputDeviceInfo : MediaDeviceInfo { + MediaTrackCapabilities getCapabilities (); }; partial interface NavigatorUserMedia { - void getUserMedia(MediaStreamConstraints constraints, - NavigatorUserMediaSuccessCallback successCallback, - NavigatorUserMediaErrorCallback errorCallback); + void getUserMedia (MediaStreamConstraints constraints, NavigatorUserMediaSuccessCallback successCallback, NavigatorUserMediaErrorCallback errorCallback); }; partial interface MediaDevices { - MediaTrackSupportedConstraints getSupportedConstraints(); - Promise<MediaStream> getUserMedia(optional MediaStreamConstraints constraints); + MediaTrackSupportedConstraints getSupportedConstraints (); + Promise<MediaStream> getUserMedia (optional MediaStreamConstraints constraints); }; dictionary MediaStreamConstraints { - (boolean or MediaTrackConstraints) video = false; - (boolean or MediaTrackConstraints) audio = false; + (boolean or MediaTrackConstraints) video = false; + (boolean or MediaTrackConstraints) audio = false; }; callback NavigatorUserMediaSuccessCallback = void (MediaStream stream); @@ -196,44 +213,44 @@ [NoInterfaceObject] interface ConstrainablePattern { - Capabilities getCapabilities(); - Constraints getConstraints(); - Settings getSettings(); - Promise<void> applyConstraints(optional Constraints constraints); - attribute EventHandler onoverconstrained; + Capabilities getCapabilities (); + Constraints getConstraints (); + Settings getSettings (); + Promise<void> applyConstraints (optional Constraints constraints); + attribute EventHandler onoverconstrained; }; dictionary DoubleRange { - double max; - double min; + double max; + double min; }; dictionary ConstrainDoubleRange : DoubleRange { - double exact; - double ideal; + double exact; + double ideal; }; -dictionary LongRange { - long max; - long min; +dictionary ULongRange { + [Clamp] unsigned long max; + [Clamp] unsigned long min; }; -dictionary ConstrainLongRange : LongRange { - long exact; - long ideal; +dictionary ConstrainULongRange : ULongRange { + [Clamp] unsigned long exact; + [Clamp] unsigned long ideal; }; dictionary ConstrainBooleanParameters { - boolean exact; - boolean ideal; + boolean exact; + boolean ideal; }; dictionary ConstrainDOMStringParameters { - (DOMString or sequence<DOMString>) exact; - (DOMString or sequence<DOMString>) ideal; + (DOMString or sequence<DOMString>) exact; + (DOMString or sequence<DOMString>) ideal; }; -typedef (long or ConstrainLongRange) ConstrainLong; +typedef ([Clamp] unsigned long or ConstrainULongRange) ConstrainULong; typedef (double or ConstrainDoubleRange) ConstrainDouble; @@ -251,5 +268,5 @@ }; dictionary Constraints : ConstraintSet { - sequence<ConstraintSet> advanced; + sequence<ConstraintSet> advanced; };
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-fromelement/idlharness-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-fromelement/idlharness-expected.txt index 1da140d..f190e91 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-fromelement/idlharness-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-fromelement/idlharness-expected.txt
@@ -1,13 +1,7 @@ This is a testharness.js-based test. +PASS Test mediacapture-fromelement IDL interfaces PASS Partial interface HTMLMediaElement: original interface defined PASS Partial interface HTMLCanvasElement: original interface defined -PASS HTMLCanvasElement interface: operation captureStream(double) -PASS Unscopable handled correctly for captureStream(double) on HTMLCanvasElement -PASS HTMLCanvasElement interface: [object HTMLCanvasElement] must inherit property "captureStream(double)" with the proper type -PASS HTMLCanvasElement interface: calling captureStream(double) on [object HTMLCanvasElement] with too few arguments must throw TypeError -PASS HTMLMediaElement interface: operation captureStream() -PASS Unscopable handled correctly for captureStream() on HTMLMediaElement -FAIL HTMLMediaElement interface: [object HTMLUnknownElement] must inherit property "captureStream()" with the proper type assert_inherits: property "captureStream" not found in prototype chain PASS CanvasCaptureMediaStreamTrack interface: existence and properties of interface object PASS CanvasCaptureMediaStreamTrack interface object length PASS CanvasCaptureMediaStreamTrack interface object name @@ -18,9 +12,16 @@ PASS Unscopable handled correctly for canvas property on CanvasCaptureMediaStreamTrack PASS CanvasCaptureMediaStreamTrack interface: operation requestFrame() PASS Unscopable handled correctly for requestFrame() on CanvasCaptureMediaStreamTrack -PASS CanvasCaptureMediaStreamTrack must be primary interface of [object CanvasCaptureMediaStreamTrack] -PASS Stringification of [object CanvasCaptureMediaStreamTrack] -PASS CanvasCaptureMediaStreamTrack interface: [object CanvasCaptureMediaStreamTrack] must inherit property "canvas" with the proper type -PASS CanvasCaptureMediaStreamTrack interface: [object CanvasCaptureMediaStreamTrack] must inherit property "requestFrame()" with the proper type +PASS CanvasCaptureMediaStreamTrack must be primary interface of canvas.captureStream().getTracks()[0] +PASS Stringification of canvas.captureStream().getTracks()[0] +PASS CanvasCaptureMediaStreamTrack interface: canvas.captureStream().getTracks()[0] must inherit property "canvas" with the proper type +PASS CanvasCaptureMediaStreamTrack interface: canvas.captureStream().getTracks()[0] must inherit property "requestFrame()" with the proper type +PASS HTMLMediaElement interface: operation captureStream() +PASS Unscopable handled correctly for captureStream() on HTMLMediaElement +FAIL HTMLMediaElement interface: document.getElementById("media") must inherit property "captureStream()" with the proper type assert_inherits: property "captureStream" not found in prototype chain +PASS HTMLCanvasElement interface: operation captureStream(double) +PASS Unscopable handled correctly for captureStream(double) on HTMLCanvasElement +PASS HTMLCanvasElement interface: document.getElementById("canvas") must inherit property "captureStream(double)" with the proper type +PASS HTMLCanvasElement interface: calling captureStream(double) on document.getElementById("canvas") with too few arguments must throw TypeError Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-fromelement/idlharness.html b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-fromelement/idlharness.html index 1dad5c4..500720b 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-fromelement/idlharness.html +++ b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-fromelement/idlharness.html
@@ -13,12 +13,6 @@ <media id='media' width=10 height=10/> <canvas id='canvas' width=10 height=10/> - <pre id="untested_idl" style="display: none"> - interface HTMLCanvasElement {}; - interface HTMLMediaElement {}; - interface MediaStream {}; - interface MediaStreamTrack {}; - </pre> <pre id="idl" style="display: none"> // https://w3c.github.io/mediacapture-fromelement/ @@ -37,18 +31,25 @@ </pre> <script> - var canvas = document.getElementById('canvas'); - var media = document.getElementById('media'); + 'use strict'; - var idl_array = new IdlArray(); - idl_array.add_untested_idls(document.getElementById("untested_idl").textContent); - idl_array.add_idls(document.getElementById("idl").textContent); - idl_array.add_objects({ - HTMLMediaElement: [media], - HTMLCanvasElement: [canvas], - CanvasCaptureMediaStreamTrack: [canvas.captureStream().getTracks()[0]], - }); - idl_array.test(); + promise_test(async () => { + const main = await fetch('/interfaces/mediacapture-main.idl').then(r => r.text()); + const html = await fetch('/interfaces/html.idl').then(r => r.text()); + const dom = await fetch('/interfaces/dom.idl').then(r => r.text()); + + var idl_array = new IdlArray(); + idl_array.add_idls(document.getElementById("idl").textContent); + idl_array.add_dependency_idls(main); + idl_array.add_dependency_idls(html); + idl_array.add_dependency_idls(dom); + idl_array.add_objects({ + HTMLMediaElement: ['document.getElementById("media")'], + HTMLCanvasElement: ['document.getElementById("canvas")'], + CanvasCaptureMediaStreamTrack: ['canvas.captureStream().getTracks()[0]'], + }); + idl_array.test(); + }, 'Test mediacapture-fromelement IDL interfaces'); </script> <div id="log"></div> </body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-image/idlharness.html b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-image/idlharness.html index 146e0e85c..46e82a0 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-image/idlharness.html +++ b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-image/idlharness.html
@@ -13,12 +13,6 @@ <body> <canvas id='canvas' width=10 height=10/> - <pre id="untested_idl" style="display: none"> - interface Event {}; - interface EventHandler {}; - interface EventTarget {}; - interface MediaStreamTrack {}; - </pre> <pre id="idl" style="display: none"> // https://w3c.github.io/mediacapture-image @@ -164,7 +158,14 @@ }; </pre> - <script> +<script> + 'use strict'; + + promise_test(async () => { + const main = await fetch('/interfaces/mediacapture-main.idl').then(r => r.text()); + const html = await fetch('/interfaces/html.idl').then(r => r.text()); + const dom = await fetch('/interfaces/dom.idl').then(r => r.text()); + var canvas = document.getElementById('canvas'); var context = canvas.getContext("2d"); context.fillStyle = "red"; @@ -172,13 +173,15 @@ var track = canvas.captureStream().getVideoTracks()[0]; var idl_array = new IdlArray(); - idl_array.add_untested_idls( - document.getElementById("untested_idl").textContent); idl_array.add_idls(document.getElementById("idl").textContent); + idl_array.add_dependency_idls(main); + idl_array.add_dependency_idls(html); + idl_array.add_dependency_idls(dom); idl_array.add_objects({ ImageCapturer : [new ImageCapture(track)] }); idl_array.test(); + }, 'Test mediacapture-image IDL interfaces'); </script> <div id="log"></div> </body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-record/idlharness.html b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-record/idlharness.html index 2da20a1..01cc1511 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-record/idlharness.html +++ b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-record/idlharness.html
@@ -13,12 +13,6 @@ <body> <canvas id='canvas' width=10 height=10/> - <pre id="untested_idl" style="display: none"> - interface Event {}; - interface EventHandler {}; - interface EventTarget {}; - interface MediaStream {}; - </pre> <pre id="idl" style="display: none"> // https://w3c.github.io/mediacapture-record/MediaRecorder.html @@ -81,6 +75,8 @@ </pre> <script> promise_test(async function() { + const main = await fetch('/interfaces/mediacapture-main.idl').then(r => r.text()); + const html = await fetch('/interfaces/html.idl').then(r => r.text()); const dom = await fetch('/interfaces/dom.idl').then(r => r.text()); var canvas = document.getElementById('canvas'); @@ -90,9 +86,10 @@ var stream = canvas.captureStream(); var idl_array = new IdlArray(); - idl_array.add_untested_idls(dom, { only: ['EventInit'] }); - idl_array.add_untested_idls(document.getElementById("untested_idl").textContent); idl_array.add_idls(document.getElementById("idl").textContent); + idl_array.add_dependency_idls(main); + idl_array.add_dependency_idls(html); + idl_array.add_dependency_idls(dom); idl_array.add_objects({ MediaRecorder: [new MediaRecorder(stream)], });
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaDevices-IDL-all-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaDevices-IDL-all-expected.txt index 359e0d6..ec61ea6 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaDevices-IDL-all-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaDevices-IDL-all-expected.txt
@@ -3,13 +3,6 @@ PASS Test driver PASS Partial interface NavigatorUserMedia: original interface defined PASS Partial interface MediaDevices: original interface defined -PASS Navigator interface: attribute mediaDevices -PASS Unscopable handled correctly for mediaDevices property on Navigator -PASS Navigator interface: operation getUserMedia(MediaStreamConstraints, NavigatorUserMediaSuccessCallback, NavigatorUserMediaErrorCallback) -PASS Unscopable handled correctly for getUserMedia(MediaStreamConstraints, NavigatorUserMediaSuccessCallback, NavigatorUserMediaErrorCallback) on Navigator -PASS Navigator interface: navigator must inherit property "mediaDevices" with the proper type -PASS Navigator interface: navigator must inherit property "getUserMedia(MediaStreamConstraints, NavigatorUserMediaSuccessCallback, NavigatorUserMediaErrorCallback)" with the proper type -PASS Navigator interface: calling getUserMedia(MediaStreamConstraints, NavigatorUserMediaSuccessCallback, NavigatorUserMediaErrorCallback) on navigator with too few arguments must throw TypeError PASS MediaStream interface: existence and properties of interface object PASS MediaStream interface object length PASS MediaStream interface object name @@ -137,5 +130,12 @@ PASS InputDeviceInfo interface: existence and properties of interface prototype object's @@unscopables property PASS InputDeviceInfo interface: operation getCapabilities() PASS Unscopable handled correctly for getCapabilities() on InputDeviceInfo +PASS Navigator interface: attribute mediaDevices +PASS Unscopable handled correctly for mediaDevices property on Navigator +PASS Navigator interface: operation getUserMedia(MediaStreamConstraints, NavigatorUserMediaSuccessCallback, NavigatorUserMediaErrorCallback) +PASS Unscopable handled correctly for getUserMedia(MediaStreamConstraints, NavigatorUserMediaSuccessCallback, NavigatorUserMediaErrorCallback) on Navigator +PASS Navigator interface: navigator must inherit property "mediaDevices" with the proper type +PASS Navigator interface: navigator must inherit property "getUserMedia(MediaStreamConstraints, NavigatorUserMediaSuccessCallback, NavigatorUserMediaErrorCallback)" with the proper type +PASS Navigator interface: calling getUserMedia(MediaStreamConstraints, NavigatorUserMediaSuccessCallback, NavigatorUserMediaErrorCallback) on navigator with too few arguments must throw TypeError Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaDevices-IDL-all.html b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaDevices-IDL-all.html index a793bed..e398c8b 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaDevices-IDL-all.html +++ b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaDevices-IDL-all.html
@@ -19,29 +19,20 @@ <script> 'use strict'; - function doIdlTest([dom, idlText]) { + promise_test(async () => { + const main = await fetch('/interfaces/mediacapture-main.idl').then(r => r.text()); + const dom = await fetch('/interfaces/dom.idl').then(r => r.text()); + const html = await fetch('/interfaces/html.idl').then(r => r.text()); + var idl_array = new IdlArray(); - - // dummies - idl_array.add_untested_idls(dom, { only: ['Event', 'EventInit']}); - idl_array.add_untested_idls("interface Navigator {};"); - idl_array.add_untested_idls("interface EventTarget {};"); - idl_array.add_untested_idls("interface EventHandler {};"); - - idl_array.add_idls(idlText); - - idl_array.add_objects({"Navigator": ["navigator"]}); - idl_array.add_objects({"MediaDevices":["navigator.mediaDevices"]}); + idl_array.add_idls(main); + idl_array.add_dependency_idls(html); + idl_array.add_dependency_idls(dom); + idl_array.add_objects({ + Navigator: ["navigator"], + MediaDevices: ["navigator.mediaDevices"] + }); idl_array.test(); - } - - promise_test(() => { - return Promise.all( - [ - '/interfaces/dom.idl', - '/interfaces/mediacapture-main.idl', - ].map(url => fetch(url).then(r => r.text()))) - .then(doIdlTest); }, 'Test driver') </script> </body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-getStats.https.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-getStats.https.html index d03cc83..2c0170f 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-getStats.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-getStats.https.html
@@ -244,26 +244,12 @@ }) .then(t.step_func(mediaStream => { const tracks = mediaStream.getTracks(); - assert_equals(tracks.length, 2, - 'Expect media stream to have one audio and one video track'); + const [audioTrack] = mediaStream.getAudioTracks(); + const [videoTrack] = mediaStream.getVideoTracks(); - let audioTrack; - let videoTrack; - - for (const track of tracks) { + for (const track of mediaStream.getTracks()) { t.add_cleanup(() => track.stop()); - pc1.addTrack(track, mediaStream); - - if (track.kind === 'audio') { - audioTrack = track; - } else if (track.kind === 'video') { - videoTrack = track; - } - } - - if (!audioTrack || ! videoTrack) { - assert_unreached('Expect mediaStream to have both audio and video streams'); } const testStatsReport = (pc, statsReport) => {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-helper.js b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-helper.js index df91133a..f83a590 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-helper.js +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-helper.js
@@ -357,10 +357,7 @@ function getTrackFromUserMedia(kind) { return navigator.mediaDevices.getUserMedia({ [kind]: true }) .then(mediaStream => { - const tracks = mediaStream.getTracks(); - assert_greater_than(tracks.length, 0, - `Expect getUserMedia to return at least one track of kind ${kind}`); - const [ track ] = tracks; + const [track] = mediaStream.getTracks(); return [track, mediaStream]; }); }
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-removeTrack.https.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-removeTrack.https.html index 4315865..c6e2d43 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-removeTrack.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-removeTrack.https.html
@@ -53,11 +53,7 @@ return navigator.mediaDevices.getUserMedia({ audio: true }) .then(mediaStream => { - const tracks = mediaStream.getTracks(); - assert_greater_than(tracks.length, 0, - 'Expect getUserMedia to return at least one audio track'); - - const track = tracks[0]; + const [track] = mediaStream.getTracks(); const sender = pc.addTrack(track, mediaStream); pc.close(); @@ -84,11 +80,7 @@ return navigator.mediaDevices.getUserMedia({ audio: true }) .then(mediaStream => { - const tracks = mediaStream.getTracks(); - assert_greater_than(tracks.length, 0, - 'Expect getUserMedia to return at least one audio track'); - - const track = tracks[0]; + const [track] = mediaStream.getTracks(); const sender = pc.addTrack(track, mediaStream); const pc2 = new RTCPeerConnection(); @@ -119,11 +111,7 @@ return navigator.mediaDevices.getUserMedia({ audio: true }) .then(mediaStream => { - const tracks = mediaStream.getTracks(); - assert_greater_than(tracks.length, 0, - 'Expect getUserMedia to return at least one audio track'); - - const track = tracks[0]; + const [track] = mediaStream.getTracks(); const sender = pc.addTrack(track, mediaStream); const pc2 = new RTCPeerConnection(); @@ -158,11 +146,7 @@ return navigator.mediaDevices.getUserMedia({ audio: true }) .then(mediaStream => { - const tracks = mediaStream.getTracks(); - assert_greater_than(tracks.length, 0, - 'Expect getUserMedia to return at least one audio track'); - - const track = tracks[0]; + const [track] = mediaStream.getTracks(); const sender = pc.addTrack(track, mediaStream); assert_equals(sender.track, track);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/interfaces.https.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/interfaces.https.html index 2cb1ecf..5807a63 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/interfaces.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/interfaces.https.html
@@ -81,11 +81,7 @@ function asyncInitMediaStreamTrack() { return navigator.mediaDevices.getUserMedia({ audio: true }) .then(mediaStream => { - const tracks = mediaStream.getTracks(); - assert_greater_than(tracks.length, 0, - 'Expect media stream to have at least one track'); - - idlTestObjects.mediaStreamTrack = tracks[0]; + idlTestObjects.mediaStreamTrack = mediaStream.getTracks()[0]; }); }
diff --git a/third_party/WebKit/LayoutTests/fast/css/pseudo-element-rebuild-crash.html b/third_party/WebKit/LayoutTests/fast/css/pseudo-element-rebuild-crash.html new file mode 100644 index 0000000..779804f --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/pseudo-element-rebuild-crash.html
@@ -0,0 +1,28 @@ +<!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<style> + #after { display: contents } + #after::after { content: "" } +</style> +<div id="host"> + <span id="after"> + <span id="changeDisplay"></span> + </span> +</div> +<script> + host.attachShadow({mode:"open"}); + host.offsetTop; + test(() => { + // #after is not in the flat tree, but a bug causes getComputedStyle to + // store a ComputedStyle on it. + getComputedStyle(after).color; + // This should not trigger a layout tree rebuild, but it does because we + // traverse down into #after because it now has a ComputedStyle. That + // causes a crash in RebuildPseudoElementLayoutTree when trying to update + // ::after which does not have a LayoutParent(). + changeDisplay.style.display = "block"; + + assert_equals(host.offsetTop, 8, "Should not crash"); + }, "Changing display of an element not in the flat tree should not update pseudo elements."); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/shadow/style-change-tree-scope.html b/third_party/WebKit/LayoutTests/fast/dom/shadow/style-change-tree-scope.html new file mode 100644 index 0000000..7349b0fc0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/dom/shadow/style-change-tree-scope.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<div id="shadowHost"></div> +<style id="style"></style> +<script> +function moveAndReentrantlyAppendToStyleElement() { + let sr = shadowHost.createShadowRoot(); + let script = document.createElement('script'); + sr.appendChild(script); + + let scriptText = ` + let s = shadowHost.shadowRoot.querySelector('style'); + let text = document.createTextNode('div { background-color: skyblue; }'); + s.appendChild(text);`; + + // Appending scriptText and style in the same call is important here. This way + // scriptText will be evaluated synchronously while in script.append. + // Having that script execute before the tree-scope-move was fully completed + // is what caused a crash previously. + script.append(scriptText, style); +} + +test(function () { + try { + moveAndReentrantlyAppendToStyleElement(); + } catch (e) {} + let bg = shadowHost.shadowRoot.styleSheets[0].cssRules[0].styleMap + .get('background-color').toString(); + assert_equals(bg, 'skyblue'); // Don't crash. +}, 'Reentrantly appending to style element while changing tree scope does not crash'); + +</script>
diff --git a/third_party/WebKit/LayoutTests/fullscreen/full-screen-iframe-zIndex-expected.txt b/third_party/WebKit/LayoutTests/fullscreen/full-screen-iframe-zIndex-expected.txt new file mode 100644 index 0000000..80227d1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fullscreen/full-screen-iframe-zIndex-expected.txt
@@ -0,0 +1,5 @@ +This tests that an element with a positive z-index appears behind the full screen iframe element. After entering full screen mode, the whole screen should be white. Click go full screen to run the test. + +EVENT(webkitfullscreenchange) +END OF TEST +
diff --git a/third_party/WebKit/LayoutTests/fullscreen/full-screen-iframe-zIndex.html b/third_party/WebKit/LayoutTests/fullscreen/full-screen-iframe-zIndex.html index 7f7e8e4..5b626ba 100644 --- a/third_party/WebKit/LayoutTests/fullscreen/full-screen-iframe-zIndex.html +++ b/third_party/WebKit/LayoutTests/fullscreen/full-screen-iframe-zIndex.html
@@ -7,7 +7,10 @@ function init() { var iframe = document.getElementById('block1'); var element = iframe.contentDocument.documentElement; - waitForEventAndEnd(element, 'webkitfullscreenchange'); + if (!internals.runtimeFlags.userActivationV2Enabled) + waitForEventAndEnd(element, 'webkitfullscreenchange'); + else + waitForEventAndEnd(element, 'webkitfullscreenerror'); runWithKeyDown(goFullScreen); } @@ -39,7 +42,7 @@ </style> </head> <body onload="init()"> - <div>This tests that an element with a positive z-index appears behind the full screen element. + <div>This tests that an element with a positive z-index appears behind the full screen iframe element. After entering full screen mode, the whole screen should be white. Click <button onclick="goFullScreen()">go full screen</button> to run the test.</div> <div id="block2"></div>
diff --git a/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/call-extra-crash-construct-from-stream.html b/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/call-extra-crash-construct-from-stream.html new file mode 100644 index 0000000..065a682 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/call-extra-crash-construct-from-stream.html
@@ -0,0 +1,10 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/stack-overflow.js"></script> +<script> +test(() => { + const rs = new ReadableStream(); + fillStackAndRun(() => new Response(rs)); +}, 'stack overflow in Response construction from stream should not crash the browser'); +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/call-extra-crash-construct.html b/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/call-extra-crash-construct.html new file mode 100644 index 0000000..1d479220 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/call-extra-crash-construct.html
@@ -0,0 +1,9 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/stack-overflow.js"></script> +<script> +test(() => { + fillStackAndRun(() => new Response('hi')); +}, 'stack overflow in Response constructor should not crash the browser'); +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/call-extra-crash-is-disturbed.html b/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/call-extra-crash-is-disturbed.html new file mode 100644 index 0000000..7beeb473 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/call-extra-crash-is-disturbed.html
@@ -0,0 +1,11 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/stack-overflow.js"></script> +<script> +test(() => { + const rs = new ReadableStream(); + const response = new Response(rs); + fillStackAndRun(() => response.bodyUsed); +}, 'stack overflow in bodyUsed should not crash the browser'); +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/call-extra-crash-is-locked.html b/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/call-extra-crash-is-locked.html new file mode 100644 index 0000000..ae651ec0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/call-extra-crash-is-locked.html
@@ -0,0 +1,34 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +// Running put several times is necessary to trigger the crash, but running too +// many times causes the test to timeout on windows. +let putRunsLeft = 64; +// fillStackAndRun() doesn't not cause a stack overflow in this test. This is +// probably because put() takes two arguments. +function fillStackThenCallPut(foo, request, response) { + try { + fillStackThenCallPut(foo, request, response); + } finally { + // This runs thousands of times, causing the console to spew "Uncaught + // (in promise) TypeError: Response body is already used" messages, but + // it's harmless. + if (putRunsLeft > 0) { + --putRunsLeft; + foo.put(request, response); + } + } +} + +promise_test(async t => { + const request = new Request('/'); + const response = new Response('foo'); + const foo = await caches.open('foo'); + t.add_cleanup(() => caches.delete('foo')); + await foo.put(request, response); + assert_throws( + new RangeError(), () => fillStackThenCallPut(foo, request, response), + 'fillStackThenCallPut should throw'); +}, 'stack overflow in IsLocked() should not crash the browser'); +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/call-extra-crash-release.html b/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/call-extra-crash-release.html new file mode 100644 index 0000000..9e45bae --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/call-extra-crash-release.html
@@ -0,0 +1,10 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/stack-overflow.js"></script> +<script> +test(() => { + const request = new Request('/', {method: 'POST', body: 'hi'}); + fillStackAndRun(() => fetch(request)); +}, 'stack overflow during fetch should not crash the browser'); +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/call-extra-crash-tee.html b/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/call-extra-crash-tee.html new file mode 100644 index 0000000..3d46271a --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/call-extra-crash-tee.html
@@ -0,0 +1,20 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/stack-overflow.js"></script> +<script> + +// This test unhelpfully crashes in IsReadableStream when compiled with DCHECKs +// enabled. For best coverage, it should be compiled without DCHECKs. +test(() => { + const rs = new ReadableStream(); + const response = new Response(rs); + try { + // This throws different errors depending on how Blink is built, so + // assert_throws() cannot be used. + fillStackAndRun(() => response.clone(), 784); + assert_unreached('stack should overflow'); + } catch (e) { + } +}, 'stack overflow in clone() should not crash the browser'); +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/release-handle-crash.html b/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/release-handle-crash.html new file mode 100644 index 0000000..b05c01b --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/release-handle-crash.html
@@ -0,0 +1,37 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/stack-overflow.js"></script> +<script> +// Trigger the following crash: + +// #0 0x7ffff7d8092c base::debug::StackTrace::StackTrace() +// #1 0x7ffff7d80491 base::debug::(anonymous namespace)::StackDumpSignalHandler() +// #2 0x7ffff00130c0 <unknown> +// #3 0x7ffff41c113d v8::internal::GlobalHandles::MakeWeak() +// #4 0x7ffff308198e blink::ReadableStreamBytesConsumer::ReadableStreamBytesConsumer() +// #5 0x7ffff306bc6f blink::BodyStreamBuffer::ReleaseHandle() +// #6 0x7ffff306b883 blink::BodyStreamBuffer::StartLoading() +// #7 0x7ffff306914d blink::Body::blob() +// #8 0x7ffff37a9d20 blink::V8Response::blobMethodCallback() +// #9 0x7ffff3f02097 v8::internal::FunctionCallbackArguments::Call() +// #10 0x7ffff3f015a3 v8::internal::(anonymous namespace)::HandleApiCallHelper<>() +// #11 0x7ffff3f00ca6 v8::internal::Builtin_Impl_HandleApiCall() + +// This happens on Linux release build at 70ddf623, no DCHECK. It may be +// possible to reproduce in other environments by bisecting the second argument +// to fillStackAndRun() until you get the above crash. + +// See https://bugs.chromium.org/p/chromium/issues/detail?id=829790#c5 + +test(() => { + const rs = new ReadableStream(); + const response = new Response(rs); + try { + // This throws an exception in debug builds but not in release builds. + // If the process doesn't crash, the test passed. + fillStackAndRun(() => response.blob(), 784); + } catch (e) { + } +}, 'stack overflow in response.blob() should not crash the browser'); +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/resources/stack-overflow.js b/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/resources/stack-overflow.js new file mode 100644 index 0000000..17784a5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/resources/stack-overflow.js
@@ -0,0 +1,23 @@ +// The bugs in this file are necessary to reproduce the crashes. Don't fix them. + +// Run |func| with a full stack, so that any Javascript running inside it is hit +// with a stack overflow exception. |extraPadLevels| can be set to a non-zero +// value to add a bit more stack space. Sometimes this makes it possible to +// avoid crashing inside a small uninteresting function and instead crash inside +// the function of interest which is called later and requires more stack +// space. Useful |extraPadLevels| values are not portable and can only be +// determined by experiment. +function fillStackAndRun(func, extraPadLevels = 0) { + try { + padStack(extraPadLevels); + fillStackAndRun(func, extraPadLevels); + } catch (e) { + return func(); + } +} + +// Recurse |n| levels and then return. If it doesn't throw then an amount of +// stack space proportional to |n| is available. +function padStack(n) { + if (n > 0) padStack(n - 1); +}
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/page/frameScheduledNavigation-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/page/frameScheduledNavigation-expected.txt index 16268903..0b95236 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/page/frameScheduledNavigation-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/page/frameScheduledNavigation-expected.txt
@@ -1,20 +1,14 @@ Tests frameScheduledNavigation events when navigation is initiated in JS followed by other navigations. Scheduled navigation with delay 0 and reason scriptInitiated to url navigation-chain1.html -Started loading Cleared scheduled navigation Scheduled navigation with delay 0 and reason metaTagRefresh to url navigation-chain2.pl -Started loading Cleared scheduled navigation Scheduled navigation with delay 0 and reason httpHeaderRefresh to url navigation-chain3.pl -Started loading Cleared scheduled navigation Scheduled navigation with delay 0 and reason formSubmissionGet to url navigation-chain3.pl?afterGetForm=bar -Started loading Cleared scheduled navigation Scheduled navigation with delay 0 and reason formSubmissionPost to url navigation-chain3.pl?afterGetForm=bar -Started loading Cleared scheduled navigation Scheduled navigation with delay 0 and reason reload to url navigation-chain3.pl?afterGetForm=bar -Started loading Cleared scheduled navigation
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/page/frameScheduledNavigation.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/page/frameScheduledNavigation.js index 4c1d3177..e8c21e2 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/page/frameScheduledNavigation.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/page/frameScheduledNavigation.js
@@ -1,6 +1,10 @@ (async function(testRunner) { var {page, session, dp} = await testRunner.startBlank('Tests frameScheduledNavigation events when navigation is initiated in JS followed by other navigations.'); + let isLoading = false; + dp.Page.onFrameStartedLoading(() => isLoading = true); + dp.Page.onFrameStoppedLoading(() => isLoading = false); + dp.Page.enable(); session.evaluate(` var frame = document.createElement('iframe'); @@ -13,9 +17,11 @@ testRunner.log('Scheduled navigation with delay ' + msg.params.delay + ' and reason ' + msg.params.reason + ' to url ' + msg.params.url.split('/').pop()); - await dp.Page.onceFrameStartedLoading(); - // This event should be received before the scheduled navigation is cleared. - testRunner.log('Started loading'); + + // This event should be received before the scheduled navigation is cleared, + // unless the frame was already loading. + if (!isLoading) + await dp.Page.onceFrameStartedLoading(); await dp.Page.onceFrameClearedScheduledNavigation(); testRunner.log('Cleared scheduled navigation');
diff --git a/third_party/WebKit/LayoutTests/http/tests/loading/307-after-303-after-post-expected.txt b/third_party/WebKit/LayoutTests/http/tests/loading/307-after-303-after-post-expected.txt index 0f5e7ac9..639c53a 100644 --- a/third_party/WebKit/LayoutTests/http/tests/loading/307-after-303-after-post-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/loading/307-after-303-after-post-expected.txt
@@ -7,9 +7,7 @@ main frame - didStartProvisionalLoadForFrame http://127.0.0.1:8000/loading/resources/post-to-303-target.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/post-to-303-target.php, main document URL http://127.0.0.1:8000/loading/resources/post-to-303-target.php, http method POST> http://127.0.0.1:8000/loading/resources/303-to-307-target.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/303-to-307-target.php, main document URL http://127.0.0.1:8000/loading/resources/303-to-307-target.php, http method GET> -main frame - didReceiveServerRedirectForProvisionalLoadForFrame http://127.0.0.1:8000/loading/resources/307-post-output-target.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/307-post-output-target.php, main document URL http://127.0.0.1:8000/loading/resources/307-post-output-target.php, http method GET> -main frame - didReceiveServerRedirectForProvisionalLoadForFrame http://127.0.0.1:8000/loading/resources/307-post-output-target.php - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/307-post-output-target.php, http status code 200> main frame - didCommitLoadForFrame main frame - didReceiveTitle:
diff --git a/third_party/WebKit/LayoutTests/http/tests/loading/redirect-methods-expected.txt b/third_party/WebKit/LayoutTests/http/tests/loading/redirect-methods-expected.txt index 14a38f5..da998e2 100644 --- a/third_party/WebKit/LayoutTests/http/tests/loading/redirect-methods-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/loading/redirect-methods-expected.txt
@@ -22,7 +22,6 @@ frame "0" - didStartProvisionalLoadForFrame http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method POST> http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method GET> -frame "0" - didReceiveServerRedirectForProvisionalLoadForFrame http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, http status code 200> frame "0" - didCommitLoadForFrame frame "0" - didReceiveTitle: @@ -47,7 +46,6 @@ frame "1" - didStartProvisionalLoadForFrame http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method POST> http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method GET> -frame "1" - didReceiveServerRedirectForProvisionalLoadForFrame http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, http status code 200> frame "1" - didCommitLoadForFrame frame "1" - didReceiveTitle: @@ -72,7 +70,6 @@ frame "2" - didStartProvisionalLoadForFrame http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method POST> http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method GET> -frame "2" - didReceiveServerRedirectForProvisionalLoadForFrame http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, http status code 200> frame "2" - didCommitLoadForFrame frame "2" - didReceiveTitle: @@ -97,7 +94,6 @@ frame "3" - didStartProvisionalLoadForFrame http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method POST> http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method POST> -frame "3" - didReceiveServerRedirectForProvisionalLoadForFrame http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, http status code 200> frame "3" - didCommitLoadForFrame frame "3" - didReceiveTitle:
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/text/unicode-fallback-font-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/text/unicode-fallback-font-expected.png index 451671a..19c41003 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/text/unicode-fallback-font-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/text/unicode-fallback-font-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/user-activation-v2/fullscreen/README.txt b/third_party/WebKit/LayoutTests/virtual/user-activation-v2/fullscreen/README.txt new file mode 100644 index 0000000..ef3197a --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/user-activation-v2/fullscreen/README.txt
@@ -0,0 +1,2 @@ +# This suite runs tests with --enable-features=UserActivationV2. +# See http://bit.ly/2E9E3IA
diff --git a/third_party/WebKit/LayoutTests/virtual/user-activation-v2/fullscreen/full-screen-iframe-zIndex-expected.html b/third_party/WebKit/LayoutTests/virtual/user-activation-v2/fullscreen/full-screen-iframe-zIndex-expected.html new file mode 100644 index 0000000..bf7fbbcf --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/user-activation-v2/fullscreen/full-screen-iframe-zIndex-expected.html
@@ -0,0 +1,32 @@ +<!DOCTYPE html> +<html> + <head> + <style> + #block1 { + width: 200px; + height: 100px; + border: 4px solid darkgreen; + background-color: white; + z-index: 0; + } + #block2 { + width: 100px; + height: 50px; + border: 4px solid darkred; + background-color: red; + z-index: 500; + position: relative; + left: 50px; + top: 25px; + } + </style> + </head> + <body> + <div>This tests that an element with a positive z-index appears behind the full screen iframe element. + After entering full screen mode, the whole screen should be white. + Click <button>go full screen</button> to run the test.</div> + <div id="block2"></div> + <iframe id="block1"></iframe> + <div>EVENT(webkitfullscreenerror)<br>END OF TEST<br></div> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/virtual/user-activation-v2/fullscreen/full-screen-iframe-zIndex-expected.txt b/third_party/WebKit/LayoutTests/virtual/user-activation-v2/fullscreen/full-screen-iframe-zIndex-expected.txt new file mode 100644 index 0000000..3bd193f --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/user-activation-v2/fullscreen/full-screen-iframe-zIndex-expected.txt
@@ -0,0 +1,6 @@ +CONSOLE WARNING: line 20: Failed to execute 'requestFullscreen' on 'Element': API can only be initiated by a user gesture. +This tests that an element with a positive z-index appears behind the full screen iframe element. After entering full screen mode, the whole screen should be white. Click go full screen to run the test. + +EVENT(webkitfullscreenerror) +END OF TEST +
diff --git a/third_party/blink/public/platform/web_database_observer.h b/third_party/blink/public/platform/web_database_observer.h index 6a17167..abe32e96 100644 --- a/third_party/blink/public/platform/web_database_observer.h +++ b/third_party/blink/public/platform/web_database_observer.h
@@ -31,6 +31,8 @@ #ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_DATABASE_OBSERVER_H_ #define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_DATABASE_OBSERVER_H_ +#include "base/time/time.h" + namespace blink { class WebString; @@ -51,7 +53,7 @@ int error_site, int web_sql_error_code, int sqlite_error_code, - double call_time) {} + base::TimeDelta call_time) {} virtual void ReportChangeVersionResult(const WebSecurityOrigin&, const WebString& database_name, int error_site,
diff --git a/third_party/blink/public/platform/web_url_request.h b/third_party/blink/public/platform/web_url_request.h index adfcda3..f969fe1 100644 --- a/third_party/blink/public/platform/web_url_request.h +++ b/third_party/blink/public/platform/web_url_request.h
@@ -34,6 +34,7 @@ #include <memory> #include "base/optional.h" #include "base/time/time.h" +#include "base/unguessable_token.h" #include "services/network/public/mojom/cors.mojom-shared.h" #include "services/network/public/mojom/fetch_api.mojom-shared.h" #include "services/network/public/mojom/request_context_frame_type.mojom-shared.h" @@ -358,6 +359,10 @@ BLINK_PLATFORM_EXPORT bool SupportsAsyncRevalidation() const; + // Returns the DevTools ID to throttle the network request. + BLINK_PLATFORM_EXPORT const base::Optional<base::UnguessableToken>& + GetDevToolsToken() const; + #if INSIDE_BLINK BLINK_PLATFORM_EXPORT ResourceRequest& ToMutableResourceRequest(); BLINK_PLATFORM_EXPORT const ResourceRequest& ToResourceRequest() const;
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h index 8b1282b3..a04ac6a 100644 --- a/third_party/blink/public/web/web_local_frame_client.h +++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -405,9 +405,6 @@ virtual void DidStartProvisionalLoad(WebDocumentLoader* document_loader, WebURLRequest& request) {} - // The provisional load was redirected via a HTTP 3xx response. - virtual void DidReceiveServerRedirectForProvisionalLoad() {} - // The provisional load failed. The WebHistoryCommitType is the commit type // that would have been used had the load succeeded. virtual void DidFailProvisionalLoad(const WebURLError&,
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h index 4168a4d..e5896cb 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h +++ b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h
@@ -95,8 +95,7 @@ const String& file_name, const TextPosition&); - // Utilities for calling functions added to the V8 extras binding object. - + // Calls a function on the V8 extras binding object. template <size_t N> static v8::MaybeLocal<v8::Value> CallExtra(ScriptState* script_state, const char* name, @@ -104,14 +103,6 @@ return CallExtraHelper(script_state, name, N, args); } - template <size_t N> - static v8::Local<v8::Value> CallExtraOrCrash( - ScriptState* script_state, - const char* name, - v8::Local<v8::Value> (&args)[N]) { - return CallExtraHelper(script_state, name, N, args).ToLocalChecked(); - } - // Reports an exception to the message handler, as if it were an uncaught // exception. Can only be called on the main thread. //
diff --git a/third_party/blink/renderer/core/OWNERS b/third_party/blink/renderer/core/OWNERS index a53ea7657..cad509d 100644 --- a/third_party/blink/renderer/core/OWNERS +++ b/third_party/blink/renderer/core/OWNERS
@@ -2,7 +2,6 @@ # For example, core/rendering/OWNERS for rendering changes. # Reviewers (comments indicate areas of expertise): -ager@chromium.org # alancutter reviews changes in core/animation, core/css and core/style. alancutter@chromium.org alexis.menard@intel.com
diff --git a/third_party/blink/renderer/core/animation/element_animations.cc b/third_party/blink/renderer/core/animation/element_animations.cc index b3eb02c..9c202260 100644 --- a/third_party/blink/renderer/core/animation/element_animations.cc +++ b/third_party/blink/renderer/core/animation/element_animations.cc
@@ -30,6 +30,8 @@ #include "third_party/blink/renderer/core/animation/element_animations.h" +#include "third_party/blink/renderer/core/css/css_property_equality.h" +#include "third_party/blink/renderer/core/css/properties/css_property.h" #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { @@ -51,6 +53,29 @@ style.SetHasCurrentBackdropFilterAnimation(true); } +#if DCHECK_IS_ON() +// Under certain conditions ComputedStyle::operator==() may return false for +// differences that are permitted during an animation. +bool ShouldCheckComputedStyles(const ComputedStyle& base_computed_style, + const ComputedStyle& computed_style) { + // The FontFaceCache version number may be increased without forcing a style + // recalc (see crbug.com/471079). + if (!base_computed_style.GetFont().IsFallbackValid()) + return false; + // Images use instance equality rather than value equality (see + // crbug.com/781461). + for (CSSPropertyID id : + {CSSPropertyBackgroundImage, CSSPropertyWebkitMaskImage}) { + if (!CSSPropertyEquality::PropertiesEqual( + PropertyHandle(CSSProperty::Get(id)), base_computed_style, + computed_style)) { + return false; + } + } + return true; +} +#endif // DCHECK_IS_ON() + } // namespace ElementAnimations::ElementAnimations() : animation_style_change_(false) {} @@ -136,8 +161,10 @@ // internally. To ensure this we disable the optimization when DCHECKs are // enabled, but keep the internal base computed style and make sure the // equivalency holds here. - if (base_computed_style_ && computed_style) + if (base_computed_style_ && computed_style && + ShouldCheckComputedStyles(*base_computed_style_, *computed_style)) { DCHECK(*base_computed_style_ == *computed_style); + } #endif base_computed_style_ = ComputedStyle::Clone(*computed_style); } @@ -146,17 +173,4 @@ base_computed_style_ = nullptr; } -bool ElementAnimations::IsAnimationStyleChange() const { - // TODO(futhark@chromium.org): The FontFaceCache version number may be - // increased without forcing a style recalc (see crbug.com/471079). - // ComputedStyle objects created with different cache versions will not be - // considered equal as Font::operator== will compare versions, hence - // ComputedStyle::operator== will return false. We avoid using - // base_computed_style (the check for IsFallbackValid()) in that case to avoid - // triggering the ComputedStyle comparison DCHECK in UpdateBaseComputedStyle. - return animation_style_change_ && - (!base_computed_style_ || - base_computed_style_->GetFont().IsFallbackValid()); -} - } // namespace blink
diff --git a/third_party/blink/renderer/core/animation/element_animations.h b/third_party/blink/renderer/core/animation/element_animations.h index 5eb5348..63743d1c 100644 --- a/third_party/blink/renderer/core/animation/element_animations.h +++ b/third_party/blink/renderer/core/animation/element_animations.h
@@ -87,7 +87,7 @@ void Trace(blink::Visitor*); private: - bool IsAnimationStyleChange() const; + bool IsAnimationStyleChange() const { return animation_style_change_; } EffectStack effect_stack_; CSSAnimations css_animations_;
diff --git a/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map_test.cc b/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map_test.cc index 9ae84f12..e0cc71c8 100644 --- a/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map_test.cc +++ b/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map_test.cc
@@ -8,6 +8,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/core/css/css_computed_style_declaration.h" #include "third_party/blink/renderer/core/dom/element.h" +#include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -38,13 +39,13 @@ {CSSPropertyColor, CSSPropertyAlignItems}); Vector<AtomicString> empty_custom_properties; + GetDocument().View()->UpdateAllLifecyclePhases(); Node* node = PageNode(); - const ComputedStyle& style = *node->EnsureComputedStyle(); PrepopulatedComputedStylePropertyMap* map = - new PrepopulatedComputedStylePropertyMap(GetDocument(), style, node, - native_properties, - empty_custom_properties); + new PrepopulatedComputedStylePropertyMap( + GetDocument(), node->ComputedStyleRef(), node, native_properties, + empty_custom_properties); DummyExceptionStateForTesting exception_state; @@ -74,13 +75,13 @@ Vector<CSSPropertyID> empty_native_properties; Vector<AtomicString> custom_properties({"--foo", "--bar"}); + GetDocument().View()->UpdateAllLifecyclePhases(); Node* node = PageNode(); - const ComputedStyle& style = *node->EnsureComputedStyle(); PrepopulatedComputedStylePropertyMap* map = - new PrepopulatedComputedStylePropertyMap(GetDocument(), style, node, - empty_native_properties, - custom_properties); + new PrepopulatedComputedStylePropertyMap( + GetDocument(), node->ComputedStyleRef(), node, + empty_native_properties, custom_properties); DummyExceptionStateForTesting exception_state;
diff --git a/third_party/blink/renderer/core/css/resolver/css_variable_resolver_test.cc b/third_party/blink/renderer/core/css/resolver/css_variable_resolver_test.cc index ad91c1c..6179efcd 100644 --- a/third_party/blink/renderer/core/css/resolver/css_variable_resolver_test.cc +++ b/third_party/blink/renderer/core/css/resolver/css_variable_resolver_test.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/core/css/document_style_environment_variables.h" #include "third_party/blink/renderer/core/css/style_engine.h" +#include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/html/html_element.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" @@ -45,6 +46,7 @@ "<div>" " <div id=target></div>" "</div>"); + GetDocument().View()->UpdateAllLifecyclePhases(); } }; @@ -54,9 +56,8 @@ // Check that the element has the background color provided by the // nested variable. Element* target = GetDocument().getElementById("target"); - EXPECT_EQ(kMainBgTestColor, - target->EnsureComputedStyle()->VisitedDependentColor( - GetCSSPropertyBackgroundColor())); + EXPECT_EQ(kMainBgTestColor, target->ComputedStyleRef().VisitedDependentColor( + GetCSSPropertyBackgroundColor())); } TEST_F(CSSVariableResolverTest, ParseEnvVariable_Missing_NestedVar_Fallback) { @@ -65,7 +66,7 @@ // Check that the element has the fallback background color. Element* target = GetDocument().getElementById("target"); EXPECT_EQ(kFallbackTestColor, - target->EnsureComputedStyle()->VisitedDependentColor( + target->ComputedStyleRef().VisitedDependentColor( GetCSSPropertyBackgroundColor())); } @@ -75,7 +76,7 @@ // Check that the element has the fallback background color. Element* target = GetDocument().getElementById("target"); EXPECT_EQ(kFallbackTestColor, - target->EnsureComputedStyle()->VisitedDependentColor( + target->ComputedStyleRef().VisitedDependentColor( GetCSSPropertyBackgroundColor())); } @@ -84,7 +85,7 @@ // Check that the element has the background color provided by the variable. Element* target = GetDocument().getElementById("target"); - EXPECT_EQ(kTestColor, target->EnsureComputedStyle()->VisitedDependentColor( + EXPECT_EQ(kTestColor, target->ComputedStyleRef().VisitedDependentColor( GetCSSPropertyBackgroundColor())); } @@ -93,7 +94,7 @@ // Check that the element has the background color provided by the variable. Element* target = GetDocument().getElementById("target"); - EXPECT_EQ(kTestColor, target->EnsureComputedStyle()->VisitedDependentColor( + EXPECT_EQ(kTestColor, target->ComputedStyleRef().VisitedDependentColor( GetCSSPropertyBackgroundColor())); } @@ -102,9 +103,8 @@ // Check that the element has the background color provided by var(). Element* target = GetDocument().getElementById("target"); - EXPECT_EQ(kMainBgTestColor, - target->EnsureComputedStyle()->VisitedDependentColor( - GetCSSPropertyBackgroundColor())); + EXPECT_EQ(kMainBgTestColor, target->ComputedStyleRef().VisitedDependentColor( + GetCSSPropertyBackgroundColor())); } TEST_F(CSSVariableResolverTest, ParseEnvVariable_WhenNested_WillFallback) { @@ -112,7 +112,7 @@ // Check that the element has the background color provided by the variable. Element* target = GetDocument().getElementById("target"); - EXPECT_EQ(kTestColor, target->EnsureComputedStyle()->VisitedDependentColor( + EXPECT_EQ(kTestColor, target->ComputedStyleRef().VisitedDependentColor( GetCSSPropertyBackgroundColor())); }
diff --git a/third_party/blink/renderer/core/css/style_environment_variables_test.cc b/third_party/blink/renderer/core/css/style_environment_variables_test.cc index 1fd89f1..f53c232 100644 --- a/third_party/blink/renderer/core/css/style_environment_variables_test.cc +++ b/third_party/blink/renderer/core/css/style_environment_variables_test.cc
@@ -6,6 +6,7 @@ #include "third_party/blink/renderer/core/css/document_style_environment_variables.h" #include "third_party/blink/renderer/core/css/style_engine.h" +#include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/html/html_element.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" @@ -81,7 +82,7 @@ // Check that the element has the background color provided by the variable. Element* target = GetDocument().getElementById("target"); - EXPECT_EQ(kTestColorRed, target->EnsureComputedStyle()->VisitedDependentColor( + EXPECT_EQ(kTestColorRed, target->ComputedStyleRef().VisitedDependentColor( GetCSSPropertyBackgroundColor())); } @@ -98,7 +99,7 @@ // Check that the element has the background color provided by the variable. Element* target = GetDocument().getElementById("target"); - EXPECT_EQ(kTestColorRed, target->EnsureComputedStyle()->VisitedDependentColor( + EXPECT_EQ(kTestColorRed, target->ComputedStyleRef().VisitedDependentColor( GetCSSPropertyBackgroundColor())); } @@ -112,7 +113,7 @@ // Check that the element has the background color provided by the global // variable. Element* target = GetDocument().getElementById("target"); - EXPECT_EQ(kAltTestColor, target->EnsureComputedStyle()->VisitedDependentColor( + EXPECT_EQ(kAltTestColor, target->ComputedStyleRef().VisitedDependentColor( GetCSSPropertyBackgroundColor())); // Change the variable value on the document after we have loaded the page. @@ -124,7 +125,7 @@ // Check that the element has the background color provided by the document // variable. - EXPECT_EQ(kTestColorRed, target->EnsureComputedStyle()->VisitedDependentColor( + EXPECT_EQ(kTestColorRed, target->ComputedStyleRef().VisitedDependentColor( GetCSSPropertyBackgroundColor())); // Remove the document variable. @@ -136,7 +137,7 @@ // Check that the element has the background color provided by the global // variable. - EXPECT_EQ(kAltTestColor, target->EnsureComputedStyle()->VisitedDependentColor( + EXPECT_EQ(kAltTestColor, target->ComputedStyleRef().VisitedDependentColor( GetCSSPropertyBackgroundColor())); } @@ -149,7 +150,7 @@ // Check that the element has the background color provided by the global // variable. Element* target = GetDocument().getElementById("target"); - EXPECT_EQ(kAltTestColor, target->EnsureComputedStyle()->VisitedDependentColor( + EXPECT_EQ(kAltTestColor, target->ComputedStyleRef().VisitedDependentColor( GetCSSPropertyBackgroundColor())); // Change the variable value on the document after we have loaded the page. @@ -161,7 +162,7 @@ // Check that the element has the background color provided by the document // variable. - EXPECT_EQ(kTestColorRed, target->EnsureComputedStyle()->VisitedDependentColor( + EXPECT_EQ(kTestColorRed, target->ComputedStyleRef().VisitedDependentColor( GetCSSPropertyBackgroundColor())); // Remove the global variable. @@ -177,7 +178,7 @@ // Check that the element has the background color provided by the variable. Element* target = GetDocument().getElementById("target"); - EXPECT_EQ(kTestColorRed, target->EnsureComputedStyle()->VisitedDependentColor( + EXPECT_EQ(kTestColorRed, target->ComputedStyleRef().VisitedDependentColor( GetCSSPropertyBackgroundColor())); } @@ -187,7 +188,7 @@ // Check that the element has the background color provided by the variable. Element* target = GetDocument().getElementById("target"); - EXPECT_EQ(kTestColorRed, target->EnsureComputedStyle()->VisitedDependentColor( + EXPECT_EQ(kTestColorRed, target->ComputedStyleRef().VisitedDependentColor( GetCSSPropertyBackgroundColor())); // Change the variable value after we have loaded the page. @@ -198,7 +199,7 @@ GetDocument().View()->UpdateAllLifecyclePhases(); // Check that the element does not have the background color any more. - EXPECT_NE(kTestColorRed, target->EnsureComputedStyle()->VisitedDependentColor( + EXPECT_NE(kTestColorRed, target->ComputedStyleRef().VisitedDependentColor( GetCSSPropertyBackgroundColor())); } @@ -248,7 +249,7 @@ // Check that the element has no background color. Element* target = GetDocument().getElementById("target"); - EXPECT_EQ(kNoColor, target->EnsureComputedStyle()->VisitedDependentColor( + EXPECT_EQ(kNoColor, target->ComputedStyleRef().VisitedDependentColor( GetCSSPropertyBackgroundColor())); } @@ -263,7 +264,7 @@ // Check that the element has the background color provided by the variable. Element* target = GetDocument().getElementById("target"); - EXPECT_EQ(kTestColorRed, target->EnsureComputedStyle()->VisitedDependentColor( + EXPECT_EQ(kTestColorRed, target->ComputedStyleRef().VisitedDependentColor( GetCSSPropertyBackgroundColor())); } @@ -282,7 +283,7 @@ // Check that the element has the background color provided by the variable. Element* target = GetDocument().getElementById("target"); - EXPECT_EQ(kTestColorRed, target->EnsureComputedStyle()->VisitedDependentColor( + EXPECT_EQ(kTestColorRed, target->ComputedStyleRef().VisitedDependentColor( GetCSSPropertyBackgroundColor())); } @@ -293,7 +294,7 @@ // Check that the element has the background color provided by the variable. Element* target = GetDocument().getElementById("target"); - EXPECT_EQ(kTestColorRed, target->EnsureComputedStyle()->VisitedDependentColor( + EXPECT_EQ(kTestColorRed, target->ComputedStyleRef().VisitedDependentColor( GetCSSPropertyBackgroundColor())); } @@ -304,7 +305,7 @@ // Check that the element has the background color provided by the variable. Element* target = GetDocument().getElementById("target"); - EXPECT_EQ(kTestColorRed, target->EnsureComputedStyle()->VisitedDependentColor( + EXPECT_EQ(kTestColorRed, target->ComputedStyleRef().VisitedDependentColor( GetCSSPropertyBackgroundColor())); // Change the variable value after we have loaded the page. @@ -315,7 +316,7 @@ GetDocument().View()->UpdateAllLifecyclePhases(); // Check that the element does not have the background color any more. - EXPECT_NE(kTestColorRed, target->EnsureComputedStyle()->VisitedDependentColor( + EXPECT_NE(kTestColorRed, target->ComputedStyleRef().VisitedDependentColor( GetCSSPropertyBackgroundColor())); }
diff --git a/third_party/blink/renderer/core/css/style_property_serializer.cc b/third_party/blink/renderer/core/css/style_property_serializer.cc index c803479..38f7f21 100644 --- a/third_party/blink/renderer/core/css/style_property_serializer.cc +++ b/third_party/blink/renderer/core/css/style_property_serializer.cc
@@ -526,16 +526,53 @@ } } -void StylePropertySerializer::AppendFontLonghandValueIfNotNormal( +// The font shorthand only allows keyword font-stretch values. Thus, we check if +// a percentage value can be parsed as a keyword, and if so, serialize it as +// that keyword. +const CSSValue* GetFontStretchKeyword(const CSSValue* font_stretch_value) { + if (font_stretch_value->IsIdentifierValue()) + return font_stretch_value; + if (font_stretch_value->IsPrimitiveValue()) { + double value = ToCSSPrimitiveValue(font_stretch_value)->GetDoubleValue(); + if (value == 50) + return CSSIdentifierValue::Create(CSSValueUltraCondensed); + if (value == 62.5) + return CSSIdentifierValue::Create(CSSValueExtraCondensed); + if (value == 75) + return CSSIdentifierValue::Create(CSSValueCondensed); + if (value == 87.5) + return CSSIdentifierValue::Create(CSSValueSemiCondensed); + if (value == 100) + return CSSIdentifierValue::Create(CSSValueNormal); + if (value == 112.5) + return CSSIdentifierValue::Create(CSSValueSemiExpanded); + if (value == 125) + return CSSIdentifierValue::Create(CSSValueExpanded); + if (value == 150) + return CSSIdentifierValue::Create(CSSValueExtraExpanded); + if (value == 200) + return CSSIdentifierValue::Create(CSSValueUltraExpanded); + } + return nullptr; +} + +// Returns false if the value cannot be represented in the font shorthand +bool StylePropertySerializer::AppendFontLonghandValueIfNotNormal( const CSSProperty& property, StringBuilder& result) const { int found_property_index = property_set_.FindPropertyIndex(property); DCHECK_NE(found_property_index, -1); const CSSValue* val = property_set_.PropertyAt(found_property_index).Value(); + if (property.IDEquals(CSSPropertyFontStretch)) { + const CSSValue* keyword = GetFontStretchKeyword(val); + if (!keyword) + return false; + val = keyword; + } if (val->IsIdentifierValue() && ToCSSIdentifierValue(val)->GetValueID() == CSSValueNormal) - return; + return true; char prefix = '\0'; switch (property.PropertyID()) { @@ -570,10 +607,11 @@ "no-common-ligatures no-discretionary-ligatures " "no-historical-ligatures no-contextual"; } else { - value = property_set_.PropertyAt(found_property_index).Value()->CssText(); + value = val->CssText(); } result.Append(value); + return true; } String StylePropertySerializer::FontValue() const { @@ -637,7 +675,10 @@ AppendFontLonghandValueIfNotNormal(GetCSSPropertyFontVariantCaps(), result); AppendFontLonghandValueIfNotNormal(GetCSSPropertyFontWeight(), result); - AppendFontLonghandValueIfNotNormal(GetCSSPropertyFontStretch(), result); + bool font_stretch_valid = + AppendFontLonghandValueIfNotNormal(GetCSSPropertyFontStretch(), result); + if (!font_stretch_valid) + return String(); if (!result.IsEmpty()) result.Append(' '); result.Append(font_size_property.Value()->CssText());
diff --git a/third_party/blink/renderer/core/css/style_property_serializer.h b/third_party/blink/renderer/core/css/style_property_serializer.h index 365cad2..addd6aa 100644 --- a/third_party/blink/renderer/core/css/style_property_serializer.h +++ b/third_party/blink/renderer/core/css/style_property_serializer.h
@@ -54,7 +54,7 @@ String separator = " ") const; String FontValue() const; String FontVariantValue() const; - void AppendFontLonghandValueIfNotNormal(const CSSProperty&, + bool AppendFontLonghandValueIfNotNormal(const CSSProperty&, StringBuilder& result) const; String OffsetValue() const; String BackgroundRepeatPropertyValue() const;
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index d17be56b..8d7fdf6 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -2385,16 +2385,27 @@ PseudoId pseudo_id, WhitespaceAttacher& whitespace_attacher) { PseudoElement* element = GetPseudoElement(pseudo_id); - if (element) { - if (pseudo_id == kPseudoIdFirstLetter && UpdateFirstLetter(element)) - return; - } else { - element = CreatePseudoElementIfNeeded(pseudo_id); + if (pseudo_id == kPseudoIdFirstLetter) { + // Need to create a ::first-letter element here for the following case: + // + // <style>#outer::first-letter {...}</style> + // <div id=outer><div id=inner style="display:none">Text</div></div> + // <script> outer.offsetTop; inner.style.display = "block" </script> + // + // The creation of FirstLetterPseudoElement relies on the layout tree of the + // block contents. In this case, the ::first-letter element is not created + // initially since the #inner div is not displayed. On RecalcStyle it's not + // created since the layout tree is still not built, and AttachLayoutTree + // for #inner will not update the ::first-letter of outer. However, we end + // up here for #outer after AttachLayoutTree is called on #inner at which + // point the layout sub-tree is available for deciding on creating the + // ::first-letter. if (!element) + element = CreatePseudoElementIfNeeded(pseudo_id); + else if (UpdateFirstLetter(element)) return; } - - if (element->NeedsRebuildLayoutTree(whitespace_attacher)) + if (element && element->NeedsRebuildLayoutTree(whitespace_attacher)) element->RebuildLayoutTree(whitespace_attacher); }
diff --git a/third_party/blink/renderer/core/dom/events/event_queue_impl.cc b/third_party/blink/renderer/core/dom/events/event_queue_impl.cc index 2ac1883..b03827e 100644 --- a/third_party/blink/renderer/core/dom/events/event_queue_impl.cc +++ b/third_party/blink/renderer/core/dom/events/event_queue_impl.cc
@@ -34,21 +34,19 @@ namespace blink { -EventQueueImpl* EventQueueImpl::Create(EventTarget* target, +EventQueueImpl* EventQueueImpl::Create(ExecutionContext* context, TaskType task_type) { - return new EventQueueImpl(target, task_type); + return new EventQueueImpl(context, task_type); } -EventQueueImpl::EventQueueImpl(EventTarget* target, TaskType task_type) - : ContextLifecycleObserver(target->GetExecutionContext()), +EventQueueImpl::EventQueueImpl(ExecutionContext* context, TaskType task_type) + : ContextLifecycleObserver(context), task_type_(task_type), - target_(target), is_closed_(false) {} EventQueueImpl::~EventQueueImpl() = default; void EventQueueImpl::Trace(blink::Visitor* visitor) { - visitor->Trace(target_); visitor->Trace(queued_events_); EventQueue::Trace(visitor); ContextLifecycleObserver::Trace(visitor); @@ -101,10 +99,14 @@ DCHECK(GetExecutionContext()); probe::AsyncTask async_task(GetExecutionContext(), event); - if (LocalDOMWindow* window = target_->ToLocalDOMWindow()) + // TODO(hajimehoshi): Don't use |event->target()| here. Assuming the taget + // exists here is weird since event target is set later at + // |EventTarget::DispatchEvent|. + EventTarget* event_target = event->target(); + if (LocalDOMWindow* window = event_target->ToLocalDOMWindow()) window->DispatchEvent(event, nullptr); else - target_->DispatchEvent(event); + event_target->DispatchEvent(event); } void EventQueueImpl::ContextDestroyed(ExecutionContext* context) {
diff --git a/third_party/blink/renderer/core/dom/events/event_queue_impl.h b/third_party/blink/renderer/core/dom/events/event_queue_impl.h index af717cb..5300ea1 100644 --- a/third_party/blink/renderer/core/dom/events/event_queue_impl.h +++ b/third_party/blink/renderer/core/dom/events/event_queue_impl.h
@@ -44,7 +44,7 @@ public: // TODO(hajimehoshi): TaskType should be determined based on an event instead // of specifying here. - static EventQueueImpl* Create(EventTarget*, TaskType); + static EventQueueImpl* Create(ExecutionContext*, TaskType); ~EventQueueImpl() override; // EventQueue @@ -53,7 +53,7 @@ void CancelAllEvents() override; private: - EventQueueImpl(EventTarget*, TaskType); + EventQueueImpl(ExecutionContext*, TaskType); bool RemoveEvent(Event*); void DispatchEvent(Event*); @@ -63,7 +63,6 @@ void DoCancelAllEvents(ExecutionContext*); const TaskType task_type_; - Member<EventTarget> target_; HeapLinkedHashSet<Member<Event>> queued_events_; bool is_closed_; };
diff --git a/third_party/blink/renderer/core/dom/events/media_element_event_queue.cc b/third_party/blink/renderer/core/dom/events/media_element_event_queue.cc index 34c9718..bd0edf0 100644 --- a/third_party/blink/renderer/core/dom/events/media_element_event_queue.cc +++ b/third_party/blink/renderer/core/dom/events/media_element_event_queue.cc
@@ -32,14 +32,13 @@ namespace blink { -MediaElementEventQueue* MediaElementEventQueue::Create(EventTarget* owner) { - return new MediaElementEventQueue(owner); +MediaElementEventQueue* MediaElementEventQueue::Create( + ExecutionContext* context) { + return new MediaElementEventQueue(context); } -MediaElementEventQueue::MediaElementEventQueue(EventTarget* owner) - : ContextLifecycleObserver(owner->GetExecutionContext()), - owner_(owner), - is_closed_(false) { +MediaElementEventQueue::MediaElementEventQueue(ExecutionContext* context) + : ContextLifecycleObserver(context), is_closed_(false) { if (!GetExecutionContext()) Close(nullptr); } @@ -47,7 +46,6 @@ MediaElementEventQueue::~MediaElementEventQueue() = default; void MediaElementEventQueue::Trace(blink::Visitor* visitor) { - visitor->Trace(owner_); visitor->Trace(pending_events_); ContextLifecycleObserver::Trace(visitor); } @@ -57,6 +55,7 @@ if (is_closed_) return false; + DCHECK(event->target()); DCHECK(GetExecutionContext()); TRACE_EVENT_ASYNC_BEGIN1("event", "MediaElementEventQueue:enqueueEvent", @@ -90,9 +89,7 @@ probe::AsyncTask async_task(GetExecutionContext(), event); TRACE_EVENT_ASYNC_STEP_INTO1("event", "MediaElementEventQueue:enqueueEvent", event, "dispatch", "type", type); - // TODO(hajimehoshi): Always use |owner_| instead of |event->target()| - EventTarget* target = event->target() ? event->target() : owner_.Get(); - target->DispatchEvent(event); + event->target()->DispatchEvent(event); TRACE_EVENT_ASYNC_END1("event", "MediaElementEventQueue:enqueueEvent", event, "type", type); } @@ -116,7 +113,6 @@ void MediaElementEventQueue::Close(ExecutionContext* context) { is_closed_ = true; DoCancelAllEvents(context); - owner_.Clear(); } void MediaElementEventQueue::DoCancelAllEvents(ExecutionContext* context) {
diff --git a/third_party/blink/renderer/core/dom/events/media_element_event_queue.h b/third_party/blink/renderer/core/dom/events/media_element_event_queue.h index 90a314e..9286be42 100644 --- a/third_party/blink/renderer/core/dom/events/media_element_event_queue.h +++ b/third_party/blink/renderer/core/dom/events/media_element_event_queue.h
@@ -44,7 +44,7 @@ USING_GARBAGE_COLLECTED_MIXIN(MediaElementEventQueue); public: - static MediaElementEventQueue* Create(EventTarget*); + static MediaElementEventQueue* Create(ExecutionContext*); ~MediaElementEventQueue(); void Trace(blink::Visitor*) override; @@ -54,7 +54,7 @@ bool HasPendingEvents() const; private: - explicit MediaElementEventQueue(EventTarget*); + explicit MediaElementEventQueue(ExecutionContext*); bool RemoveEvent(Event* event); void DispatchEvent(Event* event); @@ -62,7 +62,6 @@ void Close(ExecutionContext*); void DoCancelAllEvents(ExecutionContext*); - Member<EventTarget> owner_; HeapHashSet<Member<Event>> pending_events_; bool is_closed_;
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc index 17f430c0..1a330629 100644 --- a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc +++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
@@ -376,13 +376,6 @@ web_frame_->Client()->DidHandleOnloadEvents(); } -void LocalFrameClientImpl:: - DispatchDidReceiveServerRedirectForProvisionalLoad() { - if (web_frame_->Client()) { - web_frame_->Client()->DidReceiveServerRedirectForProvisionalLoad(); - } -} - void LocalFrameClientImpl::DidFinishSameDocumentNavigation( HistoryItem* item, WebHistoryCommitType commit_type,
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.h b/third_party/blink/renderer/core/exported/local_frame_client_impl.h index 0879dab..70366b7 100644 --- a/third_party/blink/renderer/core/exported/local_frame_client_impl.h +++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.h
@@ -93,7 +93,6 @@ void DispatchDidLoadResourceFromMemoryCache(const ResourceRequest&, const ResourceResponse&) override; void DispatchDidHandleOnloadEvents() override; - void DispatchDidReceiveServerRedirectForProvisionalLoad() override; void DidFinishSameDocumentNavigation(HistoryItem*, WebHistoryCommitType, bool content_initiated) override;
diff --git a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc index fe11a654..81e65b97 100644 --- a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc +++ b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
@@ -457,6 +457,7 @@ void WebPluginContainerImpl::EnqueueMessageEvent( const WebDOMMessageEvent& event) { + static_cast<Event*>(event)->SetTarget(element_); if (!element_->GetExecutionContext()) return; event_queue_->EnqueueEvent(FROM_HERE, event); @@ -737,7 +738,8 @@ : ContextClient(element.GetDocument().GetFrame()), element_(element), event_queue_( - EventQueueImpl::Create(&element, TaskType::kInternalDefault)), + EventQueueImpl::Create(element.GetDocument().GetExecutionContext(), + TaskType::kInternalDefault)), web_plugin_(web_plugin), layer_(nullptr), touch_event_request_type_(kTouchEventRequestTypeNone),
diff --git a/third_party/blink/renderer/core/fetch/body_stream_buffer.cc b/third_party/blink/renderer/core/fetch/body_stream_buffer.cc index 9276faf..f613ad9 100644 --- a/third_party/blink/renderer/core/fetch/body_stream_buffer.cc +++ b/third_party/blink/renderer/core/fetch/body_stream_buffer.cc
@@ -13,6 +13,7 @@ #include "third_party/blink/renderer/core/streams/readable_stream_operations.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h" #include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h" +#include "third_party/blink/renderer/platform/bindings/exception_code.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/bindings/v8_private_property.h" @@ -103,12 +104,27 @@ DCHECK(body_value->IsObject()); v8::Local<v8::Object> body = body_value.As<v8::Object>(); - ScriptValue readable_stream = ReadableStreamOperations::CreateReadableStream( - script_state, this, - ReadableStreamOperations::CreateCountQueuingStrategy(script_state, 0)); - DCHECK(!readable_stream.IsEmpty()); - V8PrivateProperty::GetInternalBodyStream(script_state->GetIsolate()) - .Set(body, readable_stream.V8Value()); + { + // Leaving an exception pending will cause Blink to crash in the bindings + // code later, so catch instead. + v8::TryCatch try_catch(script_state->GetIsolate()); + ScriptValue strategy = + ReadableStreamOperations::CreateCountQueuingStrategy(script_state, 0); + if (!strategy.IsEmpty()) { + ScriptValue readable_stream = + ReadableStreamOperations::CreateReadableStream(script_state, this, + strategy); + if (!readable_stream.IsEmpty()) { + V8PrivateProperty::GetInternalBodyStream(script_state->GetIsolate()) + .Set(body, readable_stream.V8Value()); + } else { + stream_broken_ = true; + } + } else { + stream_broken_ = true; + } + DCHECK_EQ(stream_broken_, try_catch.HasCaught()); + } consumer_->SetClient(this); if (signal) { if (signal->aborted()) { @@ -122,12 +138,19 @@ } BodyStreamBuffer::BodyStreamBuffer(ScriptState* script_state, - ScriptValue stream) + ScriptValue stream, + ExceptionState& exception_state) : UnderlyingSourceBase(script_state), script_state_(script_state), signal_(nullptr), made_from_readable_stream_(true) { - DCHECK(ReadableStreamOperations::IsReadableStream(script_state, stream)); + DCHECK(ReadableStreamOperations::IsReadableStream(script_state, stream, + exception_state) + .value_or(true)); + + if (exception_state.HadException()) + return; + v8::Local<v8::Value> body_value = ToV8(this, script_state); DCHECK(!body_value.IsEmpty()); DCHECK(body_value->IsObject()); @@ -138,6 +161,10 @@ } ScriptValue BodyStreamBuffer::Stream() { + // Since this is the implementation of response.body, we return the stream + // even if |stream_broken_| is true, so that expected Javascript attribute + // behaviour is not changed. User code is still permitted to access the + // stream even when it has thrown an exception. ScriptState::Scope scope(script_state_.get()); v8::Local<v8::Value> body_value = ToV8(this, script_state_.get()); DCHECK(!body_value.IsEmpty()); @@ -204,18 +231,42 @@ } void BodyStreamBuffer::Tee(BodyStreamBuffer** branch1, - BodyStreamBuffer** branch2) { + BodyStreamBuffer** branch2, + ExceptionState& exception_state) { DCHECK(!IsStreamLocked()); DCHECK(!IsStreamDisturbed()); *branch1 = nullptr; *branch2 = nullptr; if (made_from_readable_stream_) { + if (stream_broken_) { + // We don't really know what state the stream is in, so throw an exception + // rather than making things worse. + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidStateError, + "Unsafe to tee stream in unknown state"); + return; + } ScriptValue stream1, stream2; ReadableStreamOperations::Tee(script_state_.get(), Stream(), &stream1, - &stream2); - *branch1 = new BodyStreamBuffer(script_state_.get(), stream1); - *branch2 = new BodyStreamBuffer(script_state_.get(), stream2); + &stream2, exception_state); + if (exception_state.HadException()) { + stream_broken_ = true; + return; + } + + // Exceptions here imply that |stream1| and/or |stream2| are broken, not the + // stream owned by this object, so we shouldn't set |stream_broken_|. + auto* tmp1 = + new BodyStreamBuffer(script_state_.get(), stream1, exception_state); + if (exception_state.HadException()) + return; + auto* tmp2 = + new BodyStreamBuffer(script_state_.get(), stream2, exception_state); + if (exception_state.HadException()) + return; + *branch1 = tmp1; + *branch2 = tmp2; return; } BytesConsumer* dest1 = nullptr; @@ -282,28 +333,28 @@ } bool BodyStreamBuffer::IsStreamReadable() { - ScriptState::Scope scope(script_state_.get()); - return ReadableStreamOperations::IsReadable(script_state_.get(), Stream()); + return BooleanStreamOperationOrFallback(ReadableStreamOperations::IsReadable, + false); } bool BodyStreamBuffer::IsStreamClosed() { - ScriptState::Scope scope(script_state_.get()); - return ReadableStreamOperations::IsClosed(script_state_.get(), Stream()); + return BooleanStreamOperationOrFallback(ReadableStreamOperations::IsClosed, + true); } bool BodyStreamBuffer::IsStreamErrored() { - ScriptState::Scope scope(script_state_.get()); - return ReadableStreamOperations::IsErrored(script_state_.get(), Stream()); + return BooleanStreamOperationOrFallback(ReadableStreamOperations::IsErrored, + true); } bool BodyStreamBuffer::IsStreamLocked() { - ScriptState::Scope scope(script_state_.get()); - return ReadableStreamOperations::IsLocked(script_state_.get(), Stream()); + return BooleanStreamOperationOrFallback(ReadableStreamOperations::IsLocked, + true); } bool BodyStreamBuffer::IsStreamDisturbed() { - ScriptState::Scope scope(script_state_.get()); - return ReadableStreamOperations::IsDisturbed(script_state_.get(), Stream()); + return BooleanStreamOperationOrFallback(ReadableStreamOperations::IsDisturbed, + true); } void BodyStreamBuffer::CloseAndLockAndDisturb() { @@ -312,11 +363,14 @@ // the internal buffer. Close(); } + if (stream_broken_) + return; ScriptState::Scope scope(script_state_.get()); - NonThrowableExceptionState exception_state; - ScriptValue reader = ReadableStreamOperations::GetReader( - script_state_.get(), Stream(), exception_state); + ScriptValue reader = + ReadableStreamOperations::GetReader(script_state_.get(), Stream()); + if (reader.IsEmpty()) + return; ReadableStreamOperations::DefaultReaderRead(script_state_.get(), reader); } @@ -409,10 +463,29 @@ loader_ = nullptr; } +bool BodyStreamBuffer::BooleanStreamOperationOrFallback( + base::Optional<bool> (*predicate)(ScriptState*, ScriptValue), + bool fallback_value) { + if (stream_broken_) + return fallback_value; + ScriptState::Scope scope(script_state_.get()); + const base::Optional<bool> result = predicate(script_state_.get(), Stream()); + if (!result.has_value()) { + stream_broken_ = true; + return fallback_value; + } + return result.value(); +} + BytesConsumer* BodyStreamBuffer::ReleaseHandle() { DCHECK(!IsStreamLocked()); DCHECK(!IsStreamDisturbed()); + if (stream_broken_) { + return BytesConsumer::CreateErrored( + BytesConsumer::Error("ReleaseHandle called with broken stream")); + } + if (made_from_readable_stream_) { ScriptState::Scope scope(script_state_.get()); // We need to have |reader| alive by some means (as written in @@ -421,9 +494,13 @@ // - This branch cannot be taken when called from tee. // - startLoading makes hasPendingActivity return true while loading. // , we don't need to keep the reader explicitly. - NonThrowableExceptionState exception_state; - ScriptValue reader = ReadableStreamOperations::GetReader( - script_state_.get(), Stream(), exception_state); + ScriptValue reader = + ReadableStreamOperations::GetReader(script_state_.get(), Stream()); + if (reader.IsEmpty()) { + stream_broken_ = true; + return BytesConsumer::CreateErrored( + BytesConsumer::Error("Failed to GetReader in ReleaseHandle")); + } return new ReadableStreamBytesConsumer(script_state_.get(), reader); } // We need to call these before calling closeAndLockAndDisturb.
diff --git a/third_party/blink/renderer/core/fetch/body_stream_buffer.h b/third_party/blink/renderer/core/fetch/body_stream_buffer.h index 9bbcc178e3..24a452e 100644 --- a/third_party/blink/renderer/core/fetch/body_stream_buffer.h +++ b/third_party/blink/renderer/core/fetch/body_stream_buffer.h
@@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_BODY_STREAM_BUFFER_H_ #include <memory> +#include "base/optional.h" #include "third_party/blink/public/platform/web_data_consumer_handle.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" @@ -20,6 +21,7 @@ namespace blink { class EncodedFormData; +class ExceptionState; class ScriptState; class CORE_EXPORT BodyStreamBuffer final : public UnderlyingSourceBase, @@ -36,7 +38,7 @@ AbortSignal* /* signal */); // |ReadableStreamOperations::isReadableStream(stream)| must hold. // This function must be called with entering an appropriate V8 context. - BodyStreamBuffer(ScriptState*, ScriptValue stream); + BodyStreamBuffer(ScriptState*, ScriptValue stream, ExceptionState&); ScriptValue Stream(); @@ -45,7 +47,7 @@ BytesConsumer::BlobSizePolicy); scoped_refptr<EncodedFormData> DrainAsFormData(); void StartLoading(FetchDataLoader*, FetchDataLoader::Client* /* client */); - void Tee(BodyStreamBuffer**, BodyStreamBuffer**); + void Tee(BodyStreamBuffer**, BodyStreamBuffer**, ExceptionState&); // UnderlyingSourceBase ScriptPromise pull(ScriptState*) override; @@ -86,6 +88,13 @@ void EndLoading(); void StopLoading(); + // Implementation of IsStream*() methods. Sets |stream_broken_| if |predicate| + // returns empty. Returns |fallback_value| if |stream_broken_| is or becomes + // true. + bool BooleanStreamOperationOrFallback( + base::Optional<bool> (*predicate)(ScriptState*, ScriptValue), + bool fallback_value); + scoped_refptr<ScriptState> script_state_; Member<BytesConsumer> consumer_; // We need this member to keep it alive while loading. @@ -96,6 +105,7 @@ bool stream_needs_more_ = false; bool made_from_readable_stream_; bool in_process_data_ = false; + bool stream_broken_ = false; DISALLOW_COPY_AND_ASSIGN(BodyStreamBuffer); };
diff --git a/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc b/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc index e65abd5..2ab6ca3 100644 --- a/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc +++ b/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc
@@ -14,6 +14,7 @@ #include "third_party/blink/renderer/core/fetch/bytes_consumer_test_util.h" #include "third_party/blink/renderer/core/fetch/form_data_bytes_consumer.h" #include "third_party/blink/renderer/core/html/forms/form_data.h" +#include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/blob/blob_data.h" #include "third_party/blink/renderer/platform/blob/blob_url.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" @@ -87,6 +88,7 @@ TEST_F(BodyStreamBufferTest, Tee) { V8TestingScope scope; + NonThrowableExceptionState exception_state; Checkpoint checkpoint; MockFetchDataLoaderClient* client1 = MockFetchDataLoaderClient::Create(); MockFetchDataLoaderClient* client2 = MockFetchDataLoaderClient::Create(); @@ -110,7 +112,7 @@ BodyStreamBuffer* new1; BodyStreamBuffer* new2; - buffer->Tee(&new1, &new2); + buffer->Tee(&new1, &new2, exception_state); EXPECT_TRUE(buffer->IsStreamLocked()); EXPECT_TRUE(buffer->IsStreamDisturbed()); @@ -130,6 +132,7 @@ TEST_F(BodyStreamBufferTest, TeeFromHandleMadeFromStream) { V8TestingScope scope; + NonThrowableExceptionState exception_state; ScriptValue stream = EvalWithPrintingError( scope.GetScriptState(), "stream = new ReadableStream({start: c => controller = c});" @@ -150,11 +153,11 @@ EXPECT_CALL(checkpoint, Call(4)); BodyStreamBuffer* buffer = - new BodyStreamBuffer(scope.GetScriptState(), stream); + new BodyStreamBuffer(scope.GetScriptState(), stream, exception_state); BodyStreamBuffer* new1; BodyStreamBuffer* new2; - buffer->Tee(&new1, &new2); + buffer->Tee(&new1, &new2, exception_state); EXPECT_TRUE(buffer->IsStreamLocked()); // Note that this behavior is slightly different from for the behavior of @@ -228,10 +231,11 @@ TEST_F(BodyStreamBufferTest, DrainAsBlobFromBufferMadeFromBufferMadeFromStream) { V8TestingScope scope; + NonThrowableExceptionState exception_state; ScriptValue stream = EvalWithPrintingError(scope.GetScriptState(), "new ReadableStream()"); BodyStreamBuffer* buffer = - new BodyStreamBuffer(scope.GetScriptState(), stream); + new BodyStreamBuffer(scope.GetScriptState(), stream, exception_state); EXPECT_FALSE(buffer->HasPendingActivity()); EXPECT_FALSE(buffer->IsStreamLocked()); @@ -293,10 +297,11 @@ TEST_F(BodyStreamBufferTest, DrainAsFormDataFromBufferMadeFromBufferMadeFromStream) { V8TestingScope scope; + NonThrowableExceptionState exception_state; ScriptValue stream = EvalWithPrintingError(scope.GetScriptState(), "new ReadableStream()"); BodyStreamBuffer* buffer = - new BodyStreamBuffer(scope.GetScriptState(), stream); + new BodyStreamBuffer(scope.GetScriptState(), stream, exception_state); EXPECT_FALSE(buffer->HasPendingActivity()); EXPECT_FALSE(buffer->IsStreamLocked());
diff --git a/third_party/blink/renderer/core/fetch/fetch_request_data.cc b/third_party/blink/renderer/core/fetch/fetch_request_data.cc index d78319d..90d145c7 100644 --- a/third_party/blink/renderer/core/fetch/fetch_request_data.cc +++ b/third_party/blink/renderer/core/fetch/fetch_request_data.cc
@@ -13,6 +13,7 @@ #include "third_party/blink/renderer/core/fetch/fetch_header_list.h" #include "third_party/blink/renderer/core/fetch/form_data_bytes_consumer.h" #include "third_party/blink/renderer/core/loader/threadable_loader.h" +#include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_request.h" @@ -83,12 +84,15 @@ return request; } -FetchRequestData* FetchRequestData::Clone(ScriptState* script_state) { +FetchRequestData* FetchRequestData::Clone(ScriptState* script_state, + ExceptionState& exception_state) { FetchRequestData* request = FetchRequestData::CloneExceptBody(); if (buffer_) { BodyStreamBuffer* new1 = nullptr; BodyStreamBuffer* new2 = nullptr; - buffer_->Tee(&new1, &new2); + buffer_->Tee(&new1, &new2, exception_state); + if (exception_state.HadException()) + return nullptr; buffer_ = new1; request->buffer_ = new2; }
diff --git a/third_party/blink/renderer/core/fetch/fetch_request_data.h b/third_party/blink/renderer/core/fetch/fetch_request_data.h index 14a1d8b4..0be408c87 100644 --- a/third_party/blink/renderer/core/fetch/fetch_request_data.h +++ b/third_party/blink/renderer/core/fetch/fetch_request_data.h
@@ -22,6 +22,7 @@ namespace blink { class BodyStreamBuffer; +class ExceptionState; class FetchHeaderList; class SecurityOrigin; class ScriptState; @@ -35,7 +36,7 @@ static FetchRequestData* Create(); static FetchRequestData* Create(ScriptState*, const WebServiceWorkerRequest&); // Call Request::refreshBody() after calling clone() or pass(). - FetchRequestData* Clone(ScriptState*); + FetchRequestData* Clone(ScriptState*, ExceptionState&); FetchRequestData* Pass(ScriptState*); ~FetchRequestData();
diff --git a/third_party/blink/renderer/core/fetch/fetch_response_data.cc b/third_party/blink/renderer/core/fetch/fetch_response_data.cc index be9274f..cb01a0f 100644 --- a/third_party/blink/renderer/core/fetch/fetch_response_data.cc +++ b/third_party/blink/renderer/core/fetch/fetch_response_data.cc
@@ -8,6 +8,7 @@ #include "third_party/blink/renderer/core/fetch/body_stream_buffer.h" #include "third_party/blink/renderer/core/fetch/fetch_header_list.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h" +#include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/loader/fetch/fetch_utils.h" #include "third_party/blink/renderer/platform/network/http_names.h" @@ -171,7 +172,8 @@ return url_list_; } -FetchResponseData* FetchResponseData::Clone(ScriptState* script_state) { +FetchResponseData* FetchResponseData::Clone(ScriptState* script_state, + ExceptionState& exception_state) { FetchResponseData* new_response = Create(); new_response->type_ = type_; if (termination_reason_) { @@ -194,7 +196,9 @@ DCHECK_EQ(buffer_, internal_response_->buffer_); DCHECK_EQ(internal_response_->type_, Type::kDefault); new_response->internal_response_ = - internal_response_->Clone(script_state); + internal_response_->Clone(script_state, exception_state); + if (exception_state.HadException()) + return nullptr; buffer_ = internal_response_->buffer_; new_response->buffer_ = new_response->internal_response_->buffer_; break; @@ -203,7 +207,9 @@ if (buffer_) { BodyStreamBuffer* new1 = nullptr; BodyStreamBuffer* new2 = nullptr; - buffer_->Tee(&new1, &new2); + buffer_->Tee(&new1, &new2, exception_state); + if (exception_state.HadException()) + return nullptr; buffer_ = new1; new_response->buffer_ = new2; } @@ -219,7 +225,9 @@ DCHECK(!buffer_); DCHECK_EQ(internal_response_->type_, Type::kDefault); new_response->internal_response_ = - internal_response_->Clone(script_state); + internal_response_->Clone(script_state, exception_state); + if (exception_state.HadException()) + return nullptr; break; } return new_response;
diff --git a/third_party/blink/renderer/core/fetch/fetch_response_data.h b/third_party/blink/renderer/core/fetch/fetch_response_data.h index dec0cea..cf88119 100644 --- a/third_party/blink/renderer/core/fetch/fetch_response_data.h +++ b/third_party/blink/renderer/core/fetch/fetch_response_data.h
@@ -24,6 +24,7 @@ namespace blink { class BodyStreamBuffer; +class ExceptionState; class FetchHeaderList; class ScriptState; class WebServiceWorkerResponse; @@ -54,7 +55,7 @@ return internal_response_; } - FetchResponseData* Clone(ScriptState*); + FetchResponseData* Clone(ScriptState*, ExceptionState& exception_state); network::mojom::FetchResponseType GetType() const { return type_; } const KURL* Url() const;
diff --git a/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer_test.cc b/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer_test.cc index 42f7167..a701e14d 100644 --- a/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer_test.cc +++ b/third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer_test.cc
@@ -83,9 +83,8 @@ } ReadableStreamBytesConsumer* CreateConsumer(ScriptValue stream) { - NonThrowableExceptionState es; ScriptValue reader = - ReadableStreamOperations::GetReader(GetScriptState(), stream, es); + ReadableStreamOperations::GetReader(GetScriptState(), stream); DCHECK(!reader.IsEmpty()); DCHECK(reader.V8Value()->IsObject()); return new ReadableStreamBytesConsumer(GetScriptState(), reader);
diff --git a/third_party/blink/renderer/core/fetch/request.cc b/third_party/blink/renderer/core/fetch/request.cc index 1ebe656f2..17c81ec 100644 --- a/third_party/blink/renderer/core/fetch/request.cc +++ b/third_party/blink/renderer/core/fetch/request.cc
@@ -26,6 +26,7 @@ #include "third_party/blink/renderer/core/html/forms/form_data.h" #include "third_party/blink/renderer/core/loader/threadable_loader.h" #include "third_party/blink/renderer/core/url/url_search_params.h" +#include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/v8_private_property.h" #include "third_party/blink/renderer/platform/blob/blob_data.h" #include "third_party/blink/renderer/platform/loader/cors/cors.h" @@ -830,7 +831,9 @@ return nullptr; } - FetchRequestData* request = request_->Clone(script_state); + FetchRequestData* request = request_->Clone(script_state, exception_state); + if (exception_state.HadException()) + return nullptr; RefreshBody(script_state); Headers* headers = Headers::Create(request->HeaderList()); headers->SetGuard(headers_->GetGuard());
diff --git a/third_party/blink/renderer/core/fetch/request.h b/third_party/blink/renderer/core/fetch/request.h index e2f09630..ecf43e5 100644 --- a/third_party/blink/renderer/core/fetch/request.h +++ b/third_party/blink/renderer/core/fetch/request.h
@@ -22,6 +22,7 @@ class AbortSignal; class BodyStreamBuffer; +class ExceptionState; class RequestInit; class WebServiceWorkerRequest;
diff --git a/third_party/blink/renderer/core/fetch/response.cc b/third_party/blink/renderer/core/fetch/response.cc index cb7f8f7..a12ce57 100644 --- a/third_party/blink/renderer/core/fetch/response.cc +++ b/third_party/blink/renderer/core/fetch/response.cc
@@ -236,11 +236,17 @@ new FormDataBytesConsumer(execution_context, std::move(form_data)), nullptr /* AbortSignal */); content_type = "application/x-www-form-urlencoded;charset=UTF-8"; - } else if (ReadableStreamOperations::IsReadableStream(script_state, - body_value)) { + } else if (ReadableStreamOperations::IsReadableStream( + script_state, body_value, exception_state) + .value_or(true)) { + if (exception_state.HadException()) + return nullptr; UseCounter::Count(execution_context, WebFeature::kFetchResponseConstructionWithStream); - body_buffer = new BodyStreamBuffer(script_state, body_value); + body_buffer = + new BodyStreamBuffer(script_state, body_value, exception_state); + if (exception_state.HadException()) + return nullptr; } else { String string = NativeValueTraits<IDLUSVString>::NativeValue( isolate, body, exception_state); @@ -450,7 +456,9 @@ return nullptr; } - FetchResponseData* response = response_->Clone(script_state); + FetchResponseData* response = response_->Clone(script_state, exception_state); + if (exception_state.HadException()) + return nullptr; RefreshBody(script_state); Headers* headers = Headers::Create(response->HeaderList()); headers->SetGuard(headers_->GetGuard());
diff --git a/third_party/blink/renderer/core/frame/local_frame_client.h b/third_party/blink/renderer/core/frame/local_frame_client.h index ee0e09b..e96840c 100644 --- a/third_party/blink/renderer/core/frame/local_frame_client.h +++ b/third_party/blink/renderer/core/frame/local_frame_client.h
@@ -122,7 +122,6 @@ const ResourceResponse&) = 0; virtual void DispatchDidHandleOnloadEvents() = 0; - virtual void DispatchDidReceiveServerRedirectForProvisionalLoad() = 0; virtual void DidFinishSameDocumentNavigation(HistoryItem*, WebHistoryCommitType, bool content_initiated) {}
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index bb7d05e..753b56c 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -2781,12 +2781,6 @@ // TODO(pdr): prePaint should be under the "Paint" devtools timeline // step for slimming paint v2. PrePaint(); - - if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) { - if (layout_view->Compositor()->InCompositingMode()) { - GetScrollingCoordinator()->UpdateAfterPrePaint(this); - } - } } } @@ -2804,7 +2798,11 @@ if (!print_mode_enabled) PaintTree(); - GetScrollingCoordinator()->UpdateTouchActionRects(this); + if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) { + if (layout_view->Compositor()->InCompositingMode()) { + GetScrollingCoordinator()->UpdateAfterPaint(this); + } + } if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() || RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
diff --git a/third_party/blink/renderer/core/html/html_style_element.cc b/third_party/blink/renderer/core/html/html_style_element.cc index 11a2f2c..9822de60 100644 --- a/third_party/blink/renderer/core/html/html_style_element.cc +++ b/third_party/blink/renderer/core/html/html_style_element.cc
@@ -77,7 +77,14 @@ Node::InsertionNotificationRequest HTMLStyleElement::InsertedInto( ContainerNode* insertion_point) { HTMLElement::InsertedInto(insertion_point); - return kInsertionShouldCallDidNotifySubtreeInsertions; + if (isConnected()) { + if (StyleElement::ProcessStyleSheet(GetDocument(), *this) == + StyleElement::kProcessingFatalError) { + NotifyLoadedSheetAndAllCriticalSubresources( + kErrorOccurredLoadingSubresource); + } + } + return kInsertionDone; } void HTMLStyleElement::RemovedFrom(ContainerNode* insertion_point) { @@ -85,13 +92,6 @@ StyleElement::RemovedFrom(*this, insertion_point); } -void HTMLStyleElement::DidNotifySubtreeInsertionsToDocument() { - if (StyleElement::ProcessStyleSheet(GetDocument(), *this) == - StyleElement::kProcessingFatalError) - NotifyLoadedSheetAndAllCriticalSubresources( - kErrorOccurredLoadingSubresource); -} - void HTMLStyleElement::ChildrenChanged(const ChildrenChange& change) { HTMLElement::ChildrenChanged(change); if (StyleElement::ChildrenChanged(*this) ==
diff --git a/third_party/blink/renderer/core/html/html_style_element.h b/third_party/blink/renderer/core/html/html_style_element.h index b5e1b4b..c8b6726 100644 --- a/third_party/blink/renderer/core/html/html_style_element.h +++ b/third_party/blink/renderer/core/html/html_style_element.h
@@ -56,7 +56,6 @@ // overload from HTMLElement void ParseAttribute(const AttributeModificationParams&) override; InsertionNotificationRequest InsertedInto(ContainerNode*) override; - void DidNotifySubtreeInsertionsToDocument() override; void RemovedFrom(ContainerNode*) override; void ChildrenChanged(const ChildrenChange&) override;
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.cc b/third_party/blink/renderer/core/html/media/html_media_element.cc index 72c8fd1..b852854 100644 --- a/third_party/blink/renderer/core/html/media/html_media_element.cc +++ b/third_party/blink/renderer/core/html/media/html_media_element.cc
@@ -464,7 +464,7 @@ this, &HTMLMediaElement::CheckViewportIntersectionTimerFired), played_time_ranges_(), - async_event_queue_(MediaElementEventQueue::Create(this)), + async_event_queue_(MediaElementEventQueue::Create(GetExecutionContext())), playback_rate_(1.0f), default_playback_rate_(1.0f), network_state_(kNetworkEmpty), @@ -751,7 +751,9 @@ } void HTMLMediaElement::ScheduleEvent(const AtomicString& event_name) { - ScheduleEvent(Event::CreateCancelable(event_name)); + Event* event = Event::CreateCancelable(event_name); + event->SetTarget(this); + ScheduleEvent(event); } void HTMLMediaElement::ScheduleEvent(Event* event) {
diff --git a/third_party/blink/renderer/core/html/track/text_track_list.cc b/third_party/blink/renderer/core/html/track/text_track_list.cc index 5936dbf..d55f04e 100644 --- a/third_party/blink/renderer/core/html/track/text_track_list.cc +++ b/third_party/blink/renderer/core/html/track/text_track_list.cc
@@ -36,7 +36,9 @@ namespace blink { TextTrackList::TextTrackList(HTMLMediaElement* owner) - : owner_(owner), async_event_queue_(MediaElementEventQueue::Create(this)) {} + : owner_(owner), + async_event_queue_( + MediaElementEventQueue::Create(GetExecutionContext())) {} TextTrackList::~TextTrackList() = default; @@ -247,8 +249,9 @@ void TextTrackList::ScheduleTrackEvent(const AtomicString& event_name, TextTrack* track) { - async_event_queue_->EnqueueEvent(FROM_HERE, - TrackEvent::Create(event_name, track)); + Event* event = TrackEvent::Create(event_name, track); + event->SetTarget(this); + async_event_queue_->EnqueueEvent(FROM_HERE, event); } void TextTrackList::ScheduleAddTrackEvent(TextTrack* track) { @@ -270,8 +273,9 @@ // Fire a simple event named change at the media element's textTracks // attribute's TextTrackList object. - async_event_queue_->EnqueueEvent(FROM_HERE, - Event::Create(EventTypeNames::change)); + Event* event = Event::Create(EventTypeNames::change); + event->SetTarget(this); + async_event_queue_->EnqueueEvent(FROM_HERE, event); } void TextTrackList::ScheduleRemoveTrackEvent(TextTrack* track) {
diff --git a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc index 3b5c05c3..e7ebb8d9 100644 --- a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
@@ -869,6 +869,8 @@ request.SetReportRawHeaders(true); + request.SetDevToolsToken(devtools_token_); + if (state_->booleanProperty(NetworkAgentState::kCacheDisabled, false)) { if (LoadsFromCacheOnly(request) && request.GetRequestContext() != WebURLRequest::kRequestContextInternal) { @@ -886,12 +888,6 @@ WillSendRequestInternal(execution_context, identifier, loader, request, redirect_response, initiator_info, type); - - if (!conditions_token_.IsEmpty()) { - request.AddHTTPHeaderField( - HTTPNames::X_DevTools_Emulate_Network_Conditions_Client_Id, - AtomicString(conditions_token_)); - } } void InspectorNetworkAgent::MarkResourceAsCached(DocumentLoader* loader, @@ -1676,6 +1672,9 @@ resources_data_( NetworkResourcesData::Create(g_maximum_total_buffer_size, g_maximum_resource_buffer_size)), + devtools_token_(worker_global_scope_ + ? worker_global_scope_->GetParentDevToolsToken() + : inspected_frames->Root()->GetDevToolsFrameToken()), pending_request_(nullptr), remove_finished_replay_xhr_timer_( worker_global_scope_ @@ -1687,9 +1686,6 @@ max_post_data_size_(0) { DCHECK((IsMainThread() && !worker_global_scope_) || (!IsMainThread() && worker_global_scope_)); - conditions_token_ = IdentifiersFactory::IdFromToken( - worker_global_scope_ ? worker_global_scope_->GetParentDevToolsToken() - : inspected_frames->Root()->GetDevToolsFrameToken()); } void InspectorNetworkAgent::ShouldForceCORSPreflight(bool* result) {
diff --git a/third_party/blink/renderer/core/inspector/inspector_network_agent.h b/third_party/blink/renderer/core/inspector/inspector_network_agent.h index eeba181..db6291ff 100644 --- a/third_party/blink/renderer/core/inspector/inspector_network_agent.h +++ b/third_party/blink/renderer/core/inspector/inspector_network_agent.h
@@ -31,6 +31,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECTOR_NETWORK_AGENT_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECTOR_NETWORK_AGENT_H_ +#include "base/unguessable_token.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/inspector/inspected_frames.h" #include "third_party/blink/renderer/core/inspector/inspector_base_agent.h" @@ -257,7 +258,7 @@ Member<WorkerGlobalScope> worker_global_scope_; v8_inspector::V8InspectorSession* v8_session_; Member<NetworkResourcesData> resources_data_; - String conditions_token_; + const base::UnguessableToken devtools_token_; // Stores the pending ThreadableLoaderClient till an identifier for // the load is generated by the loader and passed to the inspector
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc index 3e4f9ca..df42b3c 100644 --- a/third_party/blink/renderer/core/loader/document_loader.cc +++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -508,13 +508,6 @@ fetcher_->StopFetching(); return false; } - if (GetFrameLoader().ShouldContinueForRedirectNavigationPolicy( - request_, SubstituteData(), this, kCheckContentSecurityPolicy, - navigation_type_, kNavigationPolicyCurrentTab, load_type_, - IsClientRedirect(), nullptr) != kNavigationPolicyCurrentTab) { - fetcher_->StopFetching(); - return false; - } DCHECK(!GetTiming().FetchStart().is_null()); AppendRedirect(request_url); @@ -525,8 +518,8 @@ // back/forward navigation only. In the other case, clearing it is a no-op. history_item_.Clear(); - GetLocalFrameClient().DispatchDidReceiveServerRedirectForProvisionalLoad(); - + // TODO(creis): Determine if we need to clear any history state + // in embedder to fix https://crbug.com/671276. return true; }
diff --git a/third_party/blink/renderer/core/loader/empty_clients.h b/third_party/blink/renderer/core/loader/empty_clients.h index 8724e54..5cde4f89 100644 --- a/third_party/blink/renderer/core/loader/empty_clients.h +++ b/third_party/blink/renderer/core/loader/empty_clients.h
@@ -250,7 +250,6 @@ const ResourceResponse&) override {} void DispatchDidHandleOnloadEvents() override {} - void DispatchDidReceiveServerRedirectForProvisionalLoad() override {} void DispatchWillCommitProvisionalLoad() override {} void DispatchDidStartProvisionalLoad(DocumentLoader*, ResourceRequest&) override {}
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc index 5c5575c3..fd795aa8 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.cc +++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -1370,29 +1370,6 @@ return policy; } -NavigationPolicy FrameLoader::ShouldContinueForRedirectNavigationPolicy( - const ResourceRequest& request, - const SubstituteData& substitute_data, - DocumentLoader* loader, - ContentSecurityPolicyDisposition - should_check_main_world_content_security_policy, - WebNavigationType type, - NavigationPolicy policy, - WebFrameLoadType frame_load_type, - bool is_client_redirect, - HTMLFormElement* form) { - return ShouldContinueForNavigationPolicy( - request, - // |origin_document| is not set. It doesn't really matter here. It is - // useful for PlzNavigate (aka browser-side-navigation). It is used - // during the first navigation and not during redirects. - nullptr, // origin_document - substitute_data, loader, should_check_main_world_content_security_policy, - type, policy, frame_load_type, is_client_redirect, - WebTriggeringEventInfo::kNotFromEvent, form, nullptr /* blob_url_token */, - true /* check_with_client */); -} - void FrameLoader::ClientDroppedNavigation() { if (!provisional_document_loader_ || provisional_document_loader_->DidStart()) return;
diff --git a/third_party/blink/renderer/core/loader/frame_loader.h b/third_party/blink/renderer/core/loader/frame_loader.h index c74fc21..2106efb 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.h +++ b/third_party/blink/renderer/core/loader/frame_loader.h
@@ -220,19 +220,6 @@ mojom::blink::BlobURLTokenPtr, bool check_with_client); - // Like ShouldContinueForNavigationPolicy, but should be used when following - // redirects. - NavigationPolicy ShouldContinueForRedirectNavigationPolicy( - const ResourceRequest&, - const SubstituteData&, - DocumentLoader*, - ContentSecurityPolicyDisposition, - WebNavigationType, - NavigationPolicy, - WebFrameLoadType, - bool is_client_redirect, - HTMLFormElement*); - // Note: When a PlzNavigtate navigation is handled by the client, we will // have created a dummy provisional DocumentLoader, so this will return true // while the client handles the navigation.
diff --git a/third_party/blink/renderer/core/page/page.cc b/third_party/blink/renderer/core/page/page.cc index 3cb5ca7..183d14f 100644 --- a/third_party/blink/renderer/core/page/page.cc +++ b/third_party/blink/renderer/core/page/page.cc
@@ -261,11 +261,11 @@ return *overscroll_controller_; } -DOMRectList* Page::NonFastScrollableRects(const LocalFrame* frame) { +DOMRectList* Page::NonFastScrollableRectsForTesting(const LocalFrame* frame) { // Update lifecycle to kPrePaintClean. This includes the compositing update - // and ScrollingCoordinator::UpdateAfterPrePaint, which computes the non-fast + // and ScrollingCoordinator::UpdateAfterPaint, which computes the non-fast // scrollable region. - frame->View()->UpdateAllLifecyclePhasesExceptPaint(); + frame->View()->UpdateAllLifecyclePhases(); GraphicsLayer* layer = frame->View()->LayoutViewport()->LayerForScrolling(); if (!layer)
diff --git a/third_party/blink/renderer/core/page/page.h b/third_party/blink/renderer/core/page/page.h index 68ea2ac..5adaf6d 100644 --- a/third_party/blink/renderer/core/page/page.h +++ b/third_party/blink/renderer/core/page/page.h
@@ -189,7 +189,7 @@ SmoothScrollSequencer* GetSmoothScrollSequencer(); - DOMRectList* NonFastScrollableRects(const LocalFrame*); + DOMRectList* NonFastScrollableRectsForTesting(const LocalFrame*); Settings& GetSettings() const { return *settings_; }
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc index 6ce8a2f..5171539 100644 --- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc +++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
@@ -127,6 +127,14 @@ if (frame->View()->NeedsLayout()) return; + if (RuntimeEnabledFeatures::PaintTouchActionRectsEnabled()) { + // PaintTouchActionRects does not keep a list of layers with touch rects so + // just do an update if transforms change. + frame->View()->GetScrollingContext()->SetTouchEventTargetRectsAreDirty( + true); + return; + } + for (PaintLayer* layer = box.EnclosingLayer(); layer; layer = layer->Parent()) { if (frame->View() @@ -163,7 +171,7 @@ // safely ignore the DidScroll callback. } -void ScrollingCoordinator::UpdateAfterPrePaint(LocalFrameView* frame_view) { +void ScrollingCoordinator::UpdateAfterPaint(LocalFrameView* frame_view) { LocalFrame* frame = &frame_view->GetFrame(); DCHECK(frame->IsLocalRoot()); @@ -181,7 +189,7 @@ } SCOPED_BLINK_UMA_HISTOGRAM_TIMER("Blink.ScrollingCoordinator.UpdateTime"); - TRACE_EVENT0("input", "ScrollingCoordinator::UpdateAfterPrePaint"); + TRACE_EVENT0("input", "ScrollingCoordinator::UpdateAfterPaint"); // TODO(pdr): Move the scroll gesture region logic to use touch action rects. // These features are similar and do not need independent implementations. @@ -243,6 +251,8 @@ // Set the touch action rects on the cc layer from the touch action data stored // on the GraphicsLayer's paint chunks. static void UpdateLayerTouchActionRects(GraphicsLayer& layer) { + DCHECK(RuntimeEnabledFeatures::PaintTouchActionRectsEnabled()); + // TODO(pdr): This will need to be moved to PaintArtifactCompositor (or later) // for SPV2 because composited layers are not known until then. The SPV2 // implementation will iterate over the paint chunks in each composited layer @@ -274,24 +284,6 @@ TouchActionRect::BuildRegion(touch_action_rects_in_layer_space)); } -void ScrollingCoordinator::UpdateTouchActionRects(LocalFrameView* frame_view) { - LocalFrame* frame = &frame_view->GetFrame(); - DCHECK(frame->IsLocalRoot()); - - SCOPED_BLINK_UMA_HISTOGRAM_TIMER( - "Blink.ScrollingCoordinator.UpdateTouchActionRectsTime"); - TRACE_EVENT0("input", "ScrollingCoordinator::UpdateTouchActionRects"); - - // TODO(pdr): Use a bit for whether any touch action data changed and - // early-out if no work is needed. - - if (RuntimeEnabledFeatures::PaintTouchActionRectsEnabled()) { - auto* view_layer = frame_view->GetLayoutView()->Layer(); - if (auto* root = view_layer->Compositor()->PaintRootGraphicsLayer()) - ForAllGraphicsLayers(*root, UpdateLayerTouchActionRects); - } -} - static void ClearPositionConstraintExceptForLayer(GraphicsLayer* layer, GraphicsLayer* except) { if (layer && layer != except && GraphicsLayerToCcLayer(layer)) { @@ -812,12 +804,15 @@ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) return; - if (RuntimeEnabledFeatures::PaintTouchActionRectsEnabled()) - return; - - LayerHitTestRects touch_event_target_rects; - ComputeTouchEventTargetRects(frame, touch_event_target_rects); - SetTouchEventTargetRects(frame, touch_event_target_rects); + if (RuntimeEnabledFeatures::PaintTouchActionRectsEnabled()) { + auto* view_layer = frame->View()->GetLayoutView()->Layer(); + if (auto* root = view_layer->Compositor()->PaintRootGraphicsLayer()) + ForAllGraphicsLayers(*root, UpdateLayerTouchActionRects); + } else { + LayerHitTestRects touch_event_target_rects; + ComputeTouchEventTargetRects(frame, touch_event_target_rects); + SetTouchEventTargetRects(frame, touch_event_target_rects); + } } void ScrollingCoordinator::UpdateUserInputScrollable( @@ -853,6 +848,8 @@ LayerHitTestRects& layer_rects) { TRACE_EVENT0("input", "ScrollingCoordinator::setTouchEventTargetRects"); + DCHECK(!RuntimeEnabledFeatures::PaintTouchActionRectsEnabled()); + // Ensure we have an entry for each composited layer that previously had rects // (so that old ones will get cleared out). Note that ideally we'd track this // on GraphicsLayer instead of Layer, but we have no good hook into the @@ -1245,6 +1242,8 @@ LayerHitTestRects& rects) { TRACE_EVENT0("input", "ScrollingCoordinator::computeTouchEventTargetRects"); + DCHECK(!RuntimeEnabledFeatures::PaintTouchActionRectsEnabled()); + Document* document = frame->GetDocument(); if (!document || !document->View() || !document->GetFrame()) return;
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h index 8a618837..e60573c 100644 --- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h +++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h
@@ -106,12 +106,8 @@ // Update non-fast scrollable regions, touch event target rects, main thread // scrolling reasons, and whether the visual viewport is user scrollable. - void UpdateAfterPrePaint(LocalFrameView*); - - // Set the touch action rects on cc Layer's. This is the BlinkGenPropertyTrees - // version of |ComputeTouchEventTargetRects|. - // TODO(pdr): We may want to move this to a different file. - void UpdateTouchActionRects(LocalFrameView*); + // TODO(pdr): Refactor this out of ScrollingCoordinator. + void UpdateAfterPaint(LocalFrameView*); // Should be called whenever the slow repaint objects counter changes between // zero and one.
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc index 84242167..cb8934b 100644 --- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc
@@ -1488,7 +1488,7 @@ } // LocalFrameView::FrameIsScrollableDidChange is used as a dirty bit and is -// set to clean in ScrollingCoordinator::UpdateAfterPrePaint. This test ensures +// set to clean in ScrollingCoordinator::UpdateAfterPaint. This test ensures // that the dirty bit is set and unset properly. TEST_P(ScrollingCoordinatorTest, FrameIsScrollableDidChange) { LoadHTML(R"HTML(
diff --git a/third_party/blink/renderer/core/scheduler/frame_throttling_test.cc b/third_party/blink/renderer/core/scheduler/frame_throttling_test.cc index 04712a1..70744d0 100644 --- a/third_party/blink/renderer/core/scheduler/frame_throttling_test.cc +++ b/third_party/blink/renderer/core/scheduler/frame_throttling_test.cc
@@ -585,16 +585,16 @@ frame_element->contentDocument()->body()->setAttribute(styleAttr, "background: green"); // Change root frame's layout so that the next lifecycle update will call - // ScrollingCoordinator::UpdateAfterPrePaint(). + // ScrollingCoordinator::UpdateAfterPaint(). GetDocument().body()->setAttribute(styleAttr, "margin: 20px"); EXPECT_EQ(DocumentLifecycle::kVisualUpdatePending, frame_element->contentDocument()->Lifecycle().GetState()); DocumentLifecycle::AllowThrottlingScope throttling_scope( GetDocument().Lifecycle()); - // This will call ScrollingCoordinator::UpdateAfterPrePaint() - // and should not cause assert failure about - // isAllowedToQueryCompositingState() in the throttled frame. + // This will call ScrollingCoordinator::UpdateAfterPaint() and should not + // cause assert failure about isAllowedToQueryCompositingState() in the + // throttled frame. GetDocument().View()->UpdateAllLifecyclePhases(); test::RunPendingTasks(); EXPECT_EQ(DocumentLifecycle::kVisualUpdatePending, @@ -649,14 +649,14 @@ frame_element->contentDocument()->body()->setAttribute(styleAttr, "background: green"); // Change root frame's layout so that the next lifecycle update will call - // ScrollingCoordinator::UpdateAfterPrePaint(). + // ScrollingCoordinator::UpdateAfterPaint(). GetDocument().body()->setAttribute(styleAttr, "margin: 20px"); EXPECT_EQ(DocumentLifecycle::kVisualUpdatePending, frame_element->contentDocument()->Lifecycle().GetState()); DocumentLifecycle::AllowThrottlingScope throttling_scope( GetDocument().Lifecycle()); - // This will call ScrollingCoordinator::UpdateAfterPrePaint() and should not + // This will call ScrollingCoordinator::UpdateAfterPaint() and should not // cause an assert failure about isAllowedToQueryCompositingState() in the // throttled frame. GetDocument().View()->UpdateAllLifecyclePhases(); @@ -691,14 +691,14 @@ frame_element->contentDocument()->body()->setAttribute(styleAttr, "background: green"); // Change root frame's layout so that the next lifecycle update will call - // ScrollingCoordinator::UpdateAfterPrePaint(). + // ScrollingCoordinator::UpdateAfterPaint(). GetDocument().body()->setAttribute(styleAttr, "margin: 20px"); EXPECT_EQ(DocumentLifecycle::kVisualUpdatePending, frame_element->contentDocument()->Lifecycle().GetState()); DocumentLifecycle::AllowThrottlingScope throttling_scope( GetDocument().Lifecycle()); - // This will call ScrollingCoordinator::UpdateAfterPrePaint() and should not + // This will call ScrollingCoordinator::UpdateAfterPaint() and should not // cause an assert failure about isAllowedToQueryCompositingState() in the // throttled frame. CompositeFrame();
diff --git a/third_party/blink/renderer/core/streams/readable_stream_operations.cc b/third_party/blink/renderer/core/streams/readable_stream_operations.cc index eaaf3028..7153c92 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_operations.cc +++ b/third_party/blink/renderer/core/streams/readable_stream_operations.cc
@@ -4,14 +4,102 @@ #include "third_party/blink/renderer/core/streams/readable_stream_operations.h" +#include <utility> + #include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_script_runner.h" #include "third_party/blink/renderer/core/streams/underlying_source_base.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" +#include "third_party/blink/renderer/platform/wtf/assertions.h" namespace blink { +namespace { + +base::Optional<bool> BooleanOperation(ScriptState* script_state, + ScriptValue value, + const char* operation) { + v8::Local<v8::Value> args[] = {value.V8Value()}; + v8::Local<v8::Value> result_value; + bool result_bool = false; + if (V8ScriptRunner::CallExtra(script_state, operation, args) + .ToLocal(&result_value) && + result_value->BooleanValue(script_state->GetContext()).To(&result_bool)) { + return result_bool; + } + return base::nullopt; +} + +base::Optional<bool> BooleanOperationWithRethrow( + ScriptState* script_state, + ScriptValue value, + const char* operation, + ExceptionState& exception_state) { + DCHECK(!value.IsEmpty()); + + if (!value.IsObject()) + return false; + + v8::TryCatch block(script_state->GetIsolate()); + v8::Local<v8::Value> args[] = {value.V8Value()}; + v8::Local<v8::Value> local_value; + bool result_bool = false; + + if (!V8ScriptRunner::CallExtra(script_state, operation, args) + .ToLocal(&local_value) || + !local_value->BooleanValue(script_state->GetContext()).To(&result_bool)) { + DCHECK(block.HasCaught()); + exception_state.RethrowV8Exception(block.Exception()); + return base::nullopt; + } + + DCHECK(!block.HasCaught()); + return result_bool; +} + +// Performs |operation| on |value|, catching any exceptions. This is for use in +// DCHECK(). It is unsafe for general use because it ignores errors. Returns +// |fallback_value|, which must be chosen so that the DCHECK() passed if an +// exception was thrown, so that the behaviour matches a release build. +bool BooleanOperationForDCheck(ScriptState* script_state, + ScriptValue value, + const char* operation, + bool fallback_value) { + v8::TryCatch block(script_state->GetIsolate()); + base::Optional<bool> result = + BooleanOperation(script_state, value, operation); + if (block.HasCaught()) { + DCHECK(!result.has_value()); + return fallback_value; + } + DCHECK(result.has_value()); + return result.value(); +} + +// Performs IsReadableStream(value), catching exceptions. Should only be used in +// DCHECK(). Returns true on exception. +bool IsReadableStreamForDCheck(ScriptState* script_state, ScriptValue value) { + return BooleanOperationForDCheck(script_state, value, "IsReadableStream", + true); +} + +// Performs IsReadableStreamLocked(stream), catching exceptions. Should only be +// used in DCHECK(). Returns false on exception. +bool IsLockedForDCheck(ScriptState* script_state, ScriptValue stream) { + return BooleanOperationForDCheck(script_state, stream, + "IsReadableStreamLocked", false); +} + +// Performs IsReadableStreamDefaultReader(value), catching exceptions. Should +// only be used in DCHECK(). Returns true on exception. +bool IsDefaultReaderForDCheck(ScriptState* script_state, ScriptValue value) { + return BooleanOperationForDCheck(script_state, value, + "IsReadableStreamDefaultReader", true); +} + +} // namespace + ScriptValue ReadableStreamOperations::CreateReadableStream( ScriptState* script_state, UnderlyingSourceBase* underlying_source, @@ -24,7 +112,7 @@ v8::Local<v8::Value> args[] = {js_underlying_source, js_strategy}; return ScriptValue( script_state, - V8ScriptRunner::CallExtraOrCrash( + V8ScriptRunner::CallExtra( script_state, "createReadableStreamWithExternalController", args)); } @@ -37,14 +125,13 @@ v8::Number::New(script_state->GetIsolate(), high_water_mark)}; return ScriptValue( script_state, - V8ScriptRunner::CallExtraOrCrash( - script_state, "createBuiltInCountQueuingStrategy", args)); + V8ScriptRunner::CallExtra(script_state, + "createBuiltInCountQueuingStrategy", args)); } ScriptValue ReadableStreamOperations::GetReader(ScriptState* script_state, - ScriptValue stream, - ExceptionState& es) { - DCHECK(IsReadableStream(script_state, stream)); + ScriptValue stream) { + DCHECK(IsReadableStreamForDCheck(script_state, stream)); v8::TryCatch block(script_state->GetIsolate()); v8::Local<v8::Value> args[] = {stream.V8Value()}; @@ -52,131 +139,122 @@ script_state, V8ScriptRunner::CallExtra(script_state, "AcquireReadableStreamDefaultReader", args)); - if (block.HasCaught()) - es.RethrowV8Exception(block.Exception()); + DCHECK(block.HasCaught() || !result.IsEmpty()); return result; } -bool ReadableStreamOperations::IsReadableStream(ScriptState* script_state, - ScriptValue value) { - DCHECK(!value.IsEmpty()); - - if (!value.IsObject()) - return false; - - v8::Local<v8::Value> args[] = {value.V8Value()}; - return V8ScriptRunner::CallExtraOrCrash(script_state, "IsReadableStream", - args) - ->ToBoolean() - ->Value(); -} - -bool ReadableStreamOperations::IsDisturbed(ScriptState* script_state, - ScriptValue stream) { - DCHECK(IsReadableStream(script_state, stream)); - - v8::Local<v8::Value> args[] = {stream.V8Value()}; - return V8ScriptRunner::CallExtraOrCrash(script_state, - "IsReadableStreamDisturbed", args) - ->ToBoolean() - ->Value(); -} - -bool ReadableStreamOperations::IsLocked(ScriptState* script_state, - ScriptValue stream) { - DCHECK(IsReadableStream(script_state, stream)); - - v8::Local<v8::Value> args[] = {stream.V8Value()}; - return V8ScriptRunner::CallExtraOrCrash(script_state, - "IsReadableStreamLocked", args) - ->ToBoolean() - ->Value(); -} - -bool ReadableStreamOperations::IsReadable(ScriptState* script_state, - ScriptValue stream) { - DCHECK(IsReadableStream(script_state, stream)); - - v8::Local<v8::Value> args[] = {stream.V8Value()}; - return V8ScriptRunner::CallExtraOrCrash(script_state, - "IsReadableStreamReadable", args) - ->ToBoolean() - ->Value(); -} - -bool ReadableStreamOperations::IsClosed(ScriptState* script_state, - ScriptValue stream) { - DCHECK(IsReadableStream(script_state, stream)); - - v8::Local<v8::Value> args[] = {stream.V8Value()}; - return V8ScriptRunner::CallExtraOrCrash(script_state, - "IsReadableStreamClosed", args) - ->ToBoolean() - ->Value(); -} - -bool ReadableStreamOperations::IsErrored(ScriptState* script_state, - ScriptValue stream) { - DCHECK(IsReadableStream(script_state, stream)); - - v8::Local<v8::Value> args[] = {stream.V8Value()}; - return V8ScriptRunner::CallExtraOrCrash(script_state, - "IsReadableStreamErrored", args) - ->ToBoolean() - ->Value(); -} - -bool ReadableStreamOperations::IsReadableStreamDefaultReader( +base::Optional<bool> ReadableStreamOperations::IsReadableStream( ScriptState* script_state, ScriptValue value) { - DCHECK(!value.IsEmpty()); + return BooleanOperation(script_state, value, "IsReadableStream"); +} - if (!value.IsObject()) - return false; +base::Optional<bool> ReadableStreamOperations::IsReadableStream( + ScriptState* script_state, + ScriptValue value, + ExceptionState& exception_state) { + return BooleanOperationWithRethrow(script_state, value, "IsReadableStream", + exception_state); +} - v8::Local<v8::Value> args[] = {value.V8Value()}; - return V8ScriptRunner::CallExtraOrCrash(script_state, - "IsReadableStreamDefaultReader", args) - ->ToBoolean() - ->Value(); +base::Optional<bool> ReadableStreamOperations::IsDisturbed( + ScriptState* script_state, + ScriptValue stream) { + DCHECK(IsReadableStreamForDCheck(script_state, stream)); + return BooleanOperation(script_state, stream, "IsReadableStreamDisturbed"); +} + +base::Optional<bool> ReadableStreamOperations::IsLocked( + ScriptState* script_state, + ScriptValue stream) { + DCHECK(IsReadableStreamForDCheck(script_state, stream)); + return BooleanOperation(script_state, stream, "IsReadableStreamLocked"); +} + +base::Optional<bool> ReadableStreamOperations::IsReadable( + ScriptState* script_state, + ScriptValue stream) { + DCHECK(IsReadableStreamForDCheck(script_state, stream)); + return BooleanOperation(script_state, stream, "IsReadableStreamReadable"); +} + +base::Optional<bool> ReadableStreamOperations::IsClosed( + ScriptState* script_state, + ScriptValue stream) { + DCHECK(IsReadableStreamForDCheck(script_state, stream)); + return BooleanOperation(script_state, stream, "IsReadableStreamClosed"); +} + +base::Optional<bool> ReadableStreamOperations::IsErrored( + ScriptState* script_state, + ScriptValue stream) { + DCHECK(IsReadableStreamForDCheck(script_state, stream)); + return BooleanOperation(script_state, stream, "IsReadableStreamErrored"); +} + +base::Optional<bool> ReadableStreamOperations::IsReadableStreamDefaultReader( + ScriptState* script_state, + ScriptValue value) { + return BooleanOperation(script_state, value, "IsReadableStreamDefaultReader"); } ScriptPromise ReadableStreamOperations::DefaultReaderRead( ScriptState* script_state, ScriptValue reader) { - DCHECK(IsReadableStreamDefaultReader(script_state, reader)); + DCHECK(IsDefaultReaderForDCheck(script_state, reader)); + v8::TryCatch block(script_state->GetIsolate()); v8::Local<v8::Value> args[] = {reader.V8Value()}; - return ScriptPromise::Cast( - script_state, V8ScriptRunner::CallExtraOrCrash( - script_state, "ReadableStreamDefaultReaderRead", args)); + v8::MaybeLocal<v8::Value> maybe_result = V8ScriptRunner::CallExtra( + script_state, "ReadableStreamDefaultReaderRead", args); + if (maybe_result.IsEmpty()) { + DCHECK(block.HasCaught()); + return ScriptPromise::Reject(script_state, block.Exception()); + } + return ScriptPromise::Cast(script_state, maybe_result.ToLocalChecked()); } void ReadableStreamOperations::Tee(ScriptState* script_state, ScriptValue stream, ScriptValue* new_stream1, - ScriptValue* new_stream2) { - DCHECK(IsReadableStream(script_state, stream)); - DCHECK(!IsLocked(script_state, stream)); + ScriptValue* new_stream2, + ExceptionState& exception_state) { + DCHECK(IsReadableStreamForDCheck(script_state, stream)); + DCHECK(!IsLockedForDCheck(script_state, stream)); v8::Local<v8::Value> args[] = {stream.V8Value()}; - ScriptValue result(script_state, - V8ScriptRunner::CallExtraOrCrash( - script_state, "ReadableStreamTee", args)); - DCHECK(result.V8Value()->IsArray()); - v8::Local<v8::Array> branches = result.V8Value().As<v8::Array>(); + v8::TryCatch block(script_state->GetIsolate()); + v8::Local<v8::Value> result; + if (!V8ScriptRunner::CallExtra(script_state, "ReadableStreamTee", args) + .ToLocal(&result)) { + DCHECK(block.HasCaught()); + exception_state.RethrowV8Exception(block.Exception()); + return; + } + + DCHECK(result->IsArray()); + v8::Local<v8::Array> branches = result.As<v8::Array>(); DCHECK_EQ(2u, branches->Length()); - *new_stream1 = ScriptValue( - script_state, - branches->Get(script_state->GetContext(), 0).ToLocalChecked()); - *new_stream2 = ScriptValue( - script_state, - branches->Get(script_state->GetContext(), 1).ToLocalChecked()); + ScriptValue result1(script_state, + branches->Get(script_state->GetContext(), 0)); + DCHECK(!result1.IsEmpty()); + DCHECK( + IsReadableStream(script_state, result1, exception_state).value_or(true)); + if (exception_state.HadException()) + return; - DCHECK(IsReadableStream(script_state, *new_stream1)); - DCHECK(IsReadableStream(script_state, *new_stream2)); + ScriptValue result2(script_state, + branches->Get(script_state->GetContext(), 1)); + DCHECK(!result2.IsEmpty()); + DCHECK( + IsReadableStream(script_state, result2, exception_state).value_or(true)); + if (exception_state.HadException()) + return; + + *new_stream1 = std::move(result1); + *new_stream2 = std::move(result2); } } // namespace blink
diff --git a/third_party/blink/renderer/core/streams/readable_stream_operations.h b/third_party/blink/renderer/core/streams/readable_stream_operations.h index 278ffa72..09becb9 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_operations.h +++ b/third_party/blink/renderer/core/streams/readable_stream_operations.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_READABLE_STREAM_OPERATIONS_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_READABLE_STREAM_OPERATIONS_H_ +#include "base/optional.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/core/core_export.h" @@ -20,65 +21,82 @@ // V8 Extras. // All methods should be called in an appropriate V8 context. All ScriptValue // arguments must not be empty. +// +// Boolean methods return an optional bool, where an empty value indicates that +// Javascript failed to return a value (ie. an exception occurred). Exceptions +// are not caught, so that they can be handled by user Javascript. This implicit +// exception passing is error-prone and bad. +// +// TODO(ricea): Add ExceptionState arguments and make exception passing +// explicit. https://crbug.com/853189. class CORE_EXPORT ReadableStreamOperations { STATIC_ONLY(ReadableStreamOperations); public: // createReadableStreamWithExternalController // If the caller supplies an invalid strategy (e.g. one that returns - // negative sizes, or doesn't have appropriate properties), this will crash. + // negative sizes, or doesn't have appropriate properties), or an exception + // occurs for another reason, this will return an empty value. static ScriptValue CreateReadableStream(ScriptState*, UnderlyingSourceBase*, ScriptValue strategy); // createBuiltInCountQueuingStrategy + // If the constructor throws, this will return an empty value. static ScriptValue CreateCountQueuingStrategy(ScriptState*, size_t high_water_mark); // AcquireReadableStreamDefaultReader - // This function assumes |isReadableStream(stream)|. - // Returns an empty value and throws an error via the ExceptionState when - // errored. - static ScriptValue GetReader(ScriptState*, - ScriptValue stream, - ExceptionState&); + // This function assumes |IsReadableStream(stream)|. + static ScriptValue GetReader(ScriptState*, ScriptValue stream); - // IsReadableStream - static bool IsReadableStream(ScriptState*, ScriptValue); + // IsReadableStream. Exceptions are not caught. + static base::Optional<bool> IsReadableStream(ScriptState*, ScriptValue); - // IsReadableStreamDisturbed - // This function assumes |isReadableStream(stream)|. - static bool IsDisturbed(ScriptState*, ScriptValue stream); + // IsReadableStream, exception-catching version. Exceptions will be passed to + // |exception_state|. + static base::Optional<bool> IsReadableStream(ScriptState*, + ScriptValue, + ExceptionState& exception_state); - // IsReadableStreamLocked - // This function assumes |isReadableStream(stream)|. - static bool IsLocked(ScriptState*, ScriptValue stream); + // IsReadableStreamDisturbed. + // This function assumes |IsReadableStream(stream)|. + static base::Optional<bool> IsDisturbed(ScriptState*, ScriptValue stream); - // IsReadableStreamReadable - // This function assumes |isReadableStream(stream)|. - static bool IsReadable(ScriptState*, ScriptValue stream); + // IsReadableStreamLocked. + // This function assumes |IsReadableStream(stream)|. + static base::Optional<bool> IsLocked(ScriptState*, ScriptValue stream); - // IsReadableStreamClosed - // This function assumes |isReadableStream(stream)|. - static bool IsClosed(ScriptState*, ScriptValue stream); + // IsReadableStreamReadable. + // This function assumes |IsReadableStream(stream)|. + static base::Optional<bool> IsReadable(ScriptState*, ScriptValue stream); - // IsReadableStreamErrored - // This function assumes |isReadableStream(stream)|. - static bool IsErrored(ScriptState*, ScriptValue stream); + // IsReadableStreamClosed. + // This function assumes |IsReadableStream(stream)|. + static base::Optional<bool> IsClosed(ScriptState*, ScriptValue stream); - // IsReadableStreamDefaultReader - static bool IsReadableStreamDefaultReader(ScriptState*, ScriptValue); + // IsReadableStreamErrored. + // This function assumes |IsReadableStream(stream)|. + static base::Optional<bool> IsErrored(ScriptState*, ScriptValue stream); + + // IsReadableStreamDefaultReader. + static base::Optional<bool> IsReadableStreamDefaultReader(ScriptState*, + ScriptValue); // ReadableStreamDefaultReaderRead - // This function assumes |isReadableStreamDefaultReader(reader)|. + // This function assumes |IsReadableStreamDefaultReader(reader)|. + // If an exception occurs, returns a rejected promise. static ScriptPromise DefaultReaderRead(ScriptState*, ScriptValue reader); // ReadableStreamTee - // This function assumes |isReadableStream(stream)| and |!isLocked(stream)| + // This function assumes |IsReadableStream(stream)| and |!IsLocked(stream)| + // Returns without setting new_stream1 or new_stream2 if an error occurs. + // Exceptions are caught and rethrown on |exception_state|. static void Tee(ScriptState*, ScriptValue stream, ScriptValue* new_stream1, - ScriptValue* new_stream2); + ScriptValue* new_stream2, + ExceptionState&); }; } // namespace blink
diff --git a/third_party/blink/renderer/core/streams/readable_stream_operations_test.cc b/third_party/blink/renderer/core/streams/readable_stream_operations_test.cc index 278ecf3..c9ae051 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_operations_test.cc +++ b/third_party/blink/renderer/core/streams/readable_stream_operations_test.cc
@@ -120,37 +120,49 @@ V8TestingScope scope; TryCatchScope try_catch_scope(scope.GetIsolate()); EXPECT_FALSE(ReadableStreamOperations::IsReadableStream( - scope.GetScriptState(), - ScriptValue(scope.GetScriptState(), v8::Undefined(scope.GetIsolate())))); + scope.GetScriptState(), + ScriptValue(scope.GetScriptState(), + v8::Undefined(scope.GetIsolate()))) + .value_or(true)); EXPECT_FALSE(ReadableStreamOperations::IsReadableStream( - scope.GetScriptState(), ScriptValue::CreateNull(scope.GetScriptState()))); + scope.GetScriptState(), + ScriptValue::CreateNull(scope.GetScriptState())) + .value_or(true)); EXPECT_FALSE(ReadableStreamOperations::IsReadableStream( - scope.GetScriptState(), - ScriptValue(scope.GetScriptState(), - v8::Object::New(scope.GetIsolate())))); + scope.GetScriptState(), + ScriptValue(scope.GetScriptState(), + v8::Object::New(scope.GetIsolate()))) + .value_or(true)); ScriptValue stream = EvalWithPrintingError(&scope, "new ReadableStream()"); EXPECT_FALSE(stream.IsEmpty()); - EXPECT_TRUE(ReadableStreamOperations::IsReadableStream(scope.GetScriptState(), - stream)); + EXPECT_TRUE( + ReadableStreamOperations::IsReadableStream(scope.GetScriptState(), stream) + .value_or(false)); } TEST(ReadableStreamOperationsTest, IsReadableStreamDefaultReaderInvalid) { V8TestingScope scope; TryCatchScope try_catch_scope(scope.GetIsolate()); EXPECT_FALSE(ReadableStreamOperations::IsReadableStreamDefaultReader( - scope.GetScriptState(), - ScriptValue(scope.GetScriptState(), v8::Undefined(scope.GetIsolate())))); + scope.GetScriptState(), + ScriptValue(scope.GetScriptState(), + v8::Undefined(scope.GetIsolate()))) + .value_or(true)); EXPECT_FALSE(ReadableStreamOperations::IsReadableStreamDefaultReader( - scope.GetScriptState(), ScriptValue::CreateNull(scope.GetScriptState()))); + scope.GetScriptState(), + ScriptValue::CreateNull(scope.GetScriptState())) + .value_or(true)); EXPECT_FALSE(ReadableStreamOperations::IsReadableStreamDefaultReader( - scope.GetScriptState(), - ScriptValue(scope.GetScriptState(), - v8::Object::New(scope.GetIsolate())))); + scope.GetScriptState(), + ScriptValue(scope.GetScriptState(), + v8::Object::New(scope.GetIsolate()))) + .value_or(true)); ScriptValue stream = EvalWithPrintingError(&scope, "new ReadableStream()"); - EXPECT_FALSE(stream.IsEmpty()); + ASSERT_FALSE(stream.IsEmpty()); EXPECT_FALSE(ReadableStreamOperations::IsReadableStreamDefaultReader( - scope.GetScriptState(), stream)); + scope.GetScriptState(), stream) + .value_or(true)); } TEST(ReadableStreamOperationsTest, GetReader) { @@ -160,31 +172,24 @@ EXPECT_FALSE(stream.IsEmpty()); EXPECT_FALSE( - ReadableStreamOperations::IsLocked(scope.GetScriptState(), stream)); + ReadableStreamOperations::IsLocked(scope.GetScriptState(), stream) + .value_or(true)); ScriptValue reader; - { - DummyExceptionStateForTesting es; - reader = - ReadableStreamOperations::GetReader(scope.GetScriptState(), stream, es); - ASSERT_FALSE(es.HadException()); - } - EXPECT_TRUE( - ReadableStreamOperations::IsLocked(scope.GetScriptState(), stream)); + reader = ReadableStreamOperations::GetReader(scope.GetScriptState(), stream); + EXPECT_TRUE(ReadableStreamOperations::IsLocked(scope.GetScriptState(), stream) + .value_or(false)); ASSERT_FALSE(reader.IsEmpty()); - EXPECT_FALSE(ReadableStreamOperations::IsReadableStream( - scope.GetScriptState(), reader)); + EXPECT_FALSE( + ReadableStreamOperations::IsReadableStream(scope.GetScriptState(), reader) + .value_or(true)); EXPECT_TRUE(ReadableStreamOperations::IsReadableStreamDefaultReader( - scope.GetScriptState(), reader)); + scope.GetScriptState(), reader) + .value_or(false)); // Already locked! - { - DummyExceptionStateForTesting es; - reader = - ReadableStreamOperations::GetReader(scope.GetScriptState(), stream, es); - ASSERT_TRUE(es.HadException()); - } - ASSERT_TRUE(reader.IsEmpty()); + reader = ReadableStreamOperations::GetReader(scope.GetScriptState(), stream); + EXPECT_TRUE(reader.IsEmpty()); } TEST(ReadableStreamOperationsTest, IsDisturbed) { @@ -195,12 +200,14 @@ EXPECT_FALSE(stream.IsEmpty()); EXPECT_FALSE( - ReadableStreamOperations::IsDisturbed(scope.GetScriptState(), stream)); + ReadableStreamOperations::IsDisturbed(scope.GetScriptState(), stream) + .value_or(true)); ASSERT_FALSE(EvalWithPrintingError(&scope, "stream.cancel()").IsEmpty()); EXPECT_TRUE( - ReadableStreamOperations::IsDisturbed(scope.GetScriptState(), stream)); + ReadableStreamOperations::IsDisturbed(scope.GetScriptState(), stream) + .value_or(false)); } TEST(ReadableStreamOperationsTest, Read) { @@ -213,7 +220,8 @@ "new ReadableStream({start}).getReader()"); EXPECT_FALSE(reader.IsEmpty()); ASSERT_TRUE(ReadableStreamOperations::IsReadableStreamDefaultReader( - scope.GetScriptState(), reader)); + scope.GetScriptState(), reader) + .value_or(false)); Iteration* it1 = new Iteration(); Iteration* it2 = new Iteration(); @@ -273,12 +281,7 @@ EXPECT_EQ(8, underlying_source->DesiredSize()); ScriptValue reader; - { - DummyExceptionStateForTesting es; - reader = - ReadableStreamOperations::GetReader(scope.GetScriptState(), stream, es); - ASSERT_FALSE(es.HadException()); - } + reader = ReadableStreamOperations::GetReader(scope.GetScriptState(), stream); ASSERT_FALSE(reader.IsEmpty()); Iteration* it1 = new Iteration(); @@ -368,11 +371,14 @@ ASSERT_FALSE(errored.IsEmpty()); EXPECT_TRUE( - ReadableStreamOperations::IsReadable(scope.GetScriptState(), readable)); + ReadableStreamOperations::IsReadable(scope.GetScriptState(), readable) + .value_or(false)); EXPECT_FALSE( - ReadableStreamOperations::IsReadable(scope.GetScriptState(), closed)); + ReadableStreamOperations::IsReadable(scope.GetScriptState(), closed) + .value_or(true)); EXPECT_FALSE( - ReadableStreamOperations::IsReadable(scope.GetScriptState(), errored)); + ReadableStreamOperations::IsReadable(scope.GetScriptState(), errored) + .value_or(true)); } TEST(ReadableStreamOperationsTest, IsClosed) { @@ -388,11 +394,13 @@ ASSERT_FALSE(errored.IsEmpty()); EXPECT_FALSE( - ReadableStreamOperations::IsClosed(scope.GetScriptState(), readable)); - EXPECT_TRUE( - ReadableStreamOperations::IsClosed(scope.GetScriptState(), closed)); + ReadableStreamOperations::IsClosed(scope.GetScriptState(), readable) + .value_or(true)); + EXPECT_TRUE(ReadableStreamOperations::IsClosed(scope.GetScriptState(), closed) + .value_or(false)); EXPECT_FALSE( - ReadableStreamOperations::IsClosed(scope.GetScriptState(), errored)); + ReadableStreamOperations::IsClosed(scope.GetScriptState(), errored) + .value_or(true)); } TEST(ReadableStreamOperationsTest, IsErrored) { @@ -408,29 +416,39 @@ ASSERT_FALSE(errored.IsEmpty()); EXPECT_FALSE( - ReadableStreamOperations::IsErrored(scope.GetScriptState(), readable)); + ReadableStreamOperations::IsErrored(scope.GetScriptState(), readable) + .value_or(true)); EXPECT_FALSE( - ReadableStreamOperations::IsErrored(scope.GetScriptState(), closed)); + ReadableStreamOperations::IsErrored(scope.GetScriptState(), closed) + .value_or(true)); EXPECT_TRUE( - ReadableStreamOperations::IsErrored(scope.GetScriptState(), errored)); + ReadableStreamOperations::IsErrored(scope.GetScriptState(), errored) + .value_or(false)); } TEST(ReadableStreamOperationsTest, Tee) { V8TestingScope scope; TryCatchScope try_catch_scope(scope.GetIsolate()); + NonThrowableExceptionState exception_state; ScriptValue original = EvalWithPrintingError(&scope, "var controller;" "new ReadableStream({start: c => controller = c})"); ASSERT_FALSE(original.IsEmpty()); ScriptValue new1, new2; - ReadableStreamOperations::Tee(scope.GetScriptState(), original, &new1, &new2); + ReadableStreamOperations::Tee(scope.GetScriptState(), original, &new1, &new2, + exception_state); - NonThrowableExceptionState ec; + ASSERT_FALSE(new1.IsEmpty()); + ASSERT_FALSE(new2.IsEmpty()); + ScriptValue reader1 = - ReadableStreamOperations::GetReader(scope.GetScriptState(), new1, ec); + ReadableStreamOperations::GetReader(scope.GetScriptState(), new1); ScriptValue reader2 = - ReadableStreamOperations::GetReader(scope.GetScriptState(), new2, ec); + ReadableStreamOperations::GetReader(scope.GetScriptState(), new2); + + ASSERT_FALSE(reader1.IsEmpty()); + ASSERT_FALSE(reader2.IsEmpty()); Iteration* it1 = new Iteration(); Iteration* it2 = new Iteration();
diff --git a/third_party/blink/renderer/core/svg/svg_style_element.cc b/third_party/blink/renderer/core/svg/svg_style_element.cc index ec0c3cd..df0dd356 100644 --- a/third_party/blink/renderer/core/svg/svg_style_element.cc +++ b/third_party/blink/renderer/core/svg/svg_style_element.cc
@@ -105,14 +105,14 @@ Node::InsertionNotificationRequest SVGStyleElement::InsertedInto( ContainerNode* insertion_point) { SVGElement::InsertedInto(insertion_point); - return kInsertionShouldCallDidNotifySubtreeInsertions; -} - -void SVGStyleElement::DidNotifySubtreeInsertionsToDocument() { - if (StyleElement::ProcessStyleSheet(GetDocument(), *this) == - StyleElement::kProcessingFatalError) - NotifyLoadedSheetAndAllCriticalSubresources( - kErrorOccurredLoadingSubresource); + if (isConnected()) { + if (StyleElement::ProcessStyleSheet(GetDocument(), *this) == + StyleElement::kProcessingFatalError) { + NotifyLoadedSheetAndAllCriticalSubresources( + kErrorOccurredLoadingSubresource); + } + } + return kInsertionDone; } void SVGStyleElement::RemovedFrom(ContainerNode* insertion_point) {
diff --git a/third_party/blink/renderer/core/svg/svg_style_element.h b/third_party/blink/renderer/core/svg/svg_style_element.h index c76d74901..477c720 100644 --- a/third_party/blink/renderer/core/svg/svg_style_element.h +++ b/third_party/blink/renderer/core/svg/svg_style_element.h
@@ -58,7 +58,6 @@ void ParseAttribute(const AttributeModificationParams&) override; InsertionNotificationRequest InsertedInto(ContainerNode*) override; - void DidNotifySubtreeInsertionsToDocument() override; void RemovedFrom(ContainerNode*) override; void ChildrenChanged(const ChildrenChange&) override;
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc index 7dd093d..2390caa 100644 --- a/third_party/blink/renderer/core/testing/internals.cc +++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -1918,7 +1918,7 @@ document->GetPage()->GetScrollingCoordinator()) { FrameView* view = document->GetPage()->MainFrame()->View(); if (view->IsLocalFrameView()) { - scrolling_coordinator->UpdateAfterPrePaint( + scrolling_coordinator->UpdateAfterPaint( static_cast<LocalFrameView*>(view)); } else { NOTREACHED(); @@ -2267,7 +2267,7 @@ if (!page) return nullptr; - return page->NonFastScrollableRects(document->GetFrame()); + return page->NonFastScrollableRectsForTesting(document->GetFrame()); } void Internals::evictAllResources() const {
diff --git a/third_party/blink/renderer/modules/battery/navigator_battery.idl b/third_party/blink/renderer/modules/battery/navigator_battery.idl index 4cdc46ed..579ee18 100644 --- a/third_party/blink/renderer/modules/battery/navigator_battery.idl +++ b/third_party/blink/renderer/modules/battery/navigator_battery.idl
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// https://w3c.github.io/battery/#the-navigator-interface [ ImplementedAs=NavigatorBattery ] partial interface Navigator {
diff --git a/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc b/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc index c1aa232..d401c15 100644 --- a/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc +++ b/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc
@@ -101,6 +101,7 @@ MessageEvent* event = MessageEvent::Create( nullptr, std::move(message.message), GetExecutionContext()->GetSecurityOrigin()->ToString()); + event->SetTarget(this); bool success = event_queue_->EnqueueEvent(FROM_HERE, event); DCHECK(success); ALLOW_UNUSED_LOCAL(success); @@ -114,7 +115,8 @@ const String& name) : ContextLifecycleObserver(execution_context), origin_(execution_context->GetSecurityOrigin()), - event_queue_(EventQueueImpl::Create(this, TaskType::kInternalMedia)), + event_queue_( + EventQueueImpl::Create(execution_context, TaskType::kInternalMedia)), name_(name), binding_(this) { mojom::blink::BroadcastChannelProviderPtr& provider =
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc index de0113cf..14dc658 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
@@ -1176,10 +1176,10 @@ if (!DrawingCanvas()) return; - double start_time = 0; + TimeTicks start_time; base::Optional<CustomCountHistogram> timer; if (!IsPaint2D()) { - start_time = WTF::CurrentTimeTicksInSeconds(); + start_time = WTF::CurrentTimeTicks(); if (CanCreateCanvas2dResourceProvider() && IsAccelerated()) { if (image_source->IsVideoElement()) { DEFINE_THREAD_SAFE_STATIC_LOCAL( @@ -1352,9 +1352,8 @@ ValidateStateStack(); if (!IsPaint2D()) { - DCHECK(start_time); - timer->Count((WTF::CurrentTimeTicksInSeconds() - start_time) * - WTF::Time::kMicrosecondsPerSecond); + DCHECK(!start_time.is_null()); + timer->Count((WTF::CurrentTimeTicks() - start_time).InMicroseconds()); } }
diff --git a/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor.cc b/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor.cc index f78d539d..a7843510 100644 --- a/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor.cc +++ b/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor.cc
@@ -295,9 +295,9 @@ WebPagePtr page = WebPage::New(); // Traverse the DOM tree and extract the metadata. - double start_time = CurrentTimeTicksInSeconds(); + TimeTicks start_time = CurrentTimeTicks(); ExtractionStatus status = extractMetadata(*html, page->entities); - double elapsed_time = CurrentTimeTicksInSeconds() - start_time; + TimeDelta elapsed_time = CurrentTimeTicks() - start_time; DEFINE_STATIC_LOCAL(EnumerationHistogram, status_histogram, ("CopylessPaste.ExtractionStatus", kCount)); @@ -307,12 +307,12 @@ DEFINE_STATIC_LOCAL( CustomCountHistogram, extractionHistogram, ("CopylessPaste.ExtractionFailedUs", 1, 1000 * 1000, 50)); - extractionHistogram.Count(1e6 * elapsed_time); + extractionHistogram.Count(elapsed_time.InMicroseconds()); return nullptr; } DEFINE_STATIC_LOCAL(CustomCountHistogram, extractionHistogram, ("CopylessPaste.ExtractionUs", 1, 1000 * 1000, 50)); - extractionHistogram.Count(1e6 * elapsed_time); + extractionHistogram.Count(elapsed_time.InMicroseconds()); page->url = document.Url(); page->title = document.title();
diff --git a/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc b/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc index 7076d59..abe165da 100644 --- a/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc +++ b/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc
@@ -329,7 +329,7 @@ MediaKeys* media_keys, WebEncryptedMediaSessionType session_type) : ContextLifecycleObserver(ExecutionContext::From(script_state)), - async_event_queue_(MediaElementEventQueue::Create(this)), + async_event_queue_(MediaElementEventQueue::Create(GetExecutionContext())), media_keys_(media_keys), session_type_(session_type), expiration_(std::numeric_limits<double>::quiet_NaN()), @@ -876,6 +876,7 @@ MediaKeyMessageEvent* event = MediaKeyMessageEvent::Create(EventTypeNames::message, init); + event->SetTarget(this); async_event_queue_->EnqueueEvent(FROM_HERE, event); } @@ -960,6 +961,7 @@ // 5. Queue a task to fire a simple event named keystatuseschange // at the session. Event* event = Event::Create(EventTypeNames::keystatuseschange); + event->SetTarget(this); async_event_queue_->EnqueueEvent(FROM_HERE, event); // 6. Queue a task to run the attempt to resume playback if necessary
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_database.cc b/third_party/blink/renderer/modules/indexeddb/idb_database.cc index ffd1095..f9288a0 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_database.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_database.cc
@@ -108,7 +108,8 @@ v8::Isolate* isolate) : ContextLifecycleObserver(context), backend_(std::move(backend)), - event_queue_(EventQueueImpl::Create(this, TaskType::kInternalIndexedDB)), + event_queue_( + EventQueueImpl::Create(context, TaskType::kInternalIndexedDB)), database_callbacks_(callbacks), isolate_(isolate) { database_callbacks_->Connect(this); @@ -499,6 +500,7 @@ void IDBDatabase::EnqueueEvent(Event* event) { DCHECK(GetExecutionContext()); + event->SetTarget(this); event_queue_->EnqueueEvent(FROM_HERE, event); }
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_request.cc b/third_party/blink/renderer/modules/indexeddb/idb_request.cc index 6c368cf..2cb7c02a 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_request.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_request.cc
@@ -138,8 +138,8 @@ isolate_(script_state->GetIsolate()), metrics_(std::move(metrics)), source_(source), - event_queue_(EventQueueImpl::Create(this, TaskType::kInternalIndexedDB)) { -} + event_queue_(EventQueueImpl::Create(ExecutionContext::From(script_state), + TaskType::kInternalIndexedDB)) {} IDBRequest::~IDBRequest() { DCHECK((ready_state_ == DONE && metrics_.IsEmpty()) || @@ -638,8 +638,7 @@ return DispatchEventResult::kCanceledBeforeDispatch; DCHECK_EQ(ready_state_, PENDING); DCHECK(has_pending_activity_); - event->SetTarget(this); - event->SetCurrentTarget(this); + DCHECK_EQ(event->target(), this); if (event->type() != EventTypeNames::blocked) ready_state_ = DONE; @@ -761,6 +760,8 @@ << "When queueing event " << event->type() << ", ready_state_ was " << ready_state_; + event->SetTarget(this); + event_queue_->EnqueueEvent(FROM_HERE, event); }
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_transaction.cc b/third_party/blink/renderer/modules/indexeddb/idb_transaction.cc index cc80e88..1211545 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_transaction.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_transaction.cc
@@ -90,7 +90,8 @@ mode_(kWebIDBTransactionModeReadOnly), scope_(scope), state_(kActive), - event_queue_(EventQueueImpl::Create(this, TaskType::kInternalIndexedDB)) { + event_queue_(EventQueueImpl::Create(execution_context, + TaskType::kInternalIndexedDB)) { DCHECK(database_); DCHECK(!scope_.IsEmpty()) << "Observer transactions must operate " "on a well-defined set of stores"; @@ -107,7 +108,8 @@ database_(db), mode_(mode), scope_(scope), - event_queue_(EventQueueImpl::Create(this, TaskType::kInternalIndexedDB)) { + event_queue_(EventQueueImpl::Create(ExecutionContext::From(script_state), + TaskType::kInternalIndexedDB)) { DCHECK(database_); DCHECK(!scope_.IsEmpty()) << "Non-versionchange transactions must operate " "on a well-defined set of stores"; @@ -135,7 +137,8 @@ mode_(kWebIDBTransactionModeVersionChange), state_(kInactive), old_database_metadata_(old_metadata), - event_queue_(EventQueueImpl::Create(this, TaskType::kInternalIndexedDB)) { + event_queue_(EventQueueImpl::Create(execution_context, + TaskType::kInternalIndexedDB)) { DCHECK(database_); DCHECK(open_db_request_); DCHECK(scope_.IsEmpty()); @@ -523,8 +526,7 @@ DCHECK_NE(state_, kFinished); DCHECK(has_pending_activity_); DCHECK(GetExecutionContext()); - event->SetTarget(this); - event->SetCurrentTarget(this); + DCHECK_EQ(event->target(), this); state_ = kFinished; HeapVector<Member<EventTarget>> targets; @@ -554,6 +556,7 @@ if (!GetExecutionContext()) return; + event->SetTarget(this); event_queue_->EnqueueEvent(FROM_HERE, event); }
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_transaction_test.cc b/third_party/blink/renderer/modules/indexeddb/idb_transaction_test.cc index 5c8b132..732ed6a1 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_transaction_test.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_transaction_test.cc
@@ -186,8 +186,6 @@ // event, so that the transaction can go away. EXPECT_EQ(1U, live_transactions.size()); - // Dispatch all the enqueued events. - base::RunLoop().RunUntilIdle(); ThreadState::Current()->CollectAllGarbage(); EXPECT_EQ(0U, live_transactions.size()); }
diff --git a/third_party/blink/renderer/modules/mediasource/media_source.cc b/third_party/blink/renderer/modules/mediasource/media_source.cc index b2c64f5b..c79d960 100644 --- a/third_party/blink/renderer/modules/mediasource/media_source.cc +++ b/third_party/blink/renderer/modules/mediasource/media_source.cc
@@ -113,7 +113,7 @@ MediaSource::MediaSource(ExecutionContext* context) : ContextLifecycleObserver(context), ready_state_(ClosedKeyword()), - async_event_queue_(MediaElementEventQueue::Create(this)), + async_event_queue_(MediaElementEventQueue::Create(context)), attached_element_(nullptr), source_buffers_(SourceBufferList::Create(GetExecutionContext(), async_event_queue_.Get())), @@ -846,6 +846,8 @@ DCHECK(async_event_queue_); Event* event = Event::Create(event_name); + event->SetTarget(this); + async_event_queue_->EnqueueEvent(FROM_HERE, event); }
diff --git a/third_party/blink/renderer/modules/notifications/notification_image_loader.cc b/third_party/blink/renderer/modules/notifications/notification_image_loader.cc index e1bc73b..84b3c45e 100644 --- a/third_party/blink/renderer/modules/notifications/notification_image_loader.cc +++ b/third_party/blink/renderer/modules/notifications/notification_image_loader.cc
@@ -48,7 +48,7 @@ namespace blink { NotificationImageLoader::NotificationImageLoader(Type type) - : type_(type), stopped_(false), start_time_(0.0) {} + : type_(type), stopped_(false) {} NotificationImageLoader::~NotificationImageLoader() = default; @@ -81,15 +81,16 @@ double scale = std::min(static_cast<double>(max_width_px) / image.width(), static_cast<double>(max_height_px) / image.height()); - double start_time = CurrentTimeTicksInMilliseconds(); + TimeTicks start_time = CurrentTimeTicks(); // TODO(peter): Try using RESIZE_BETTER for large images. SkBitmap scaled_image = skia::ImageOperations::Resize(image, skia::ImageOperations::RESIZE_BEST, std::lround(scale * image.width()), std::lround(scale * image.height())); - NOTIFICATION_HISTOGRAM_COUNTS(LoadScaleDownTime, type, - CurrentTimeTicksInMilliseconds() - start_time, - 1000 * 10 /* 10 seconds max */); + NOTIFICATION_HISTOGRAM_COUNTS( + LoadScaleDownTime, type, + (CurrentTimeTicks() - start_time).InMilliseconds(), + 1000 * 10 /* 10 seconds max */); return scaled_image; } return image; @@ -100,7 +101,7 @@ ImageCallback image_callback) { DCHECK(!stopped_); - start_time_ = CurrentTimeTicksInMilliseconds(); + start_time_ = CurrentTimeTicks(); image_callback_ = std::move(image_callback); ThreadableLoaderOptions threadable_loader_options; @@ -147,9 +148,10 @@ if (stopped_) return; - NOTIFICATION_HISTOGRAM_COUNTS(LoadFinishTime, type_, - CurrentTimeTicksInMilliseconds() - start_time_, - 1000 * 60 * 60 /* 1 hour max */); + NOTIFICATION_HISTOGRAM_COUNTS( + LoadFinishTime, type_, + (CurrentTimeTicks() - start_time_).InMilliseconds(), + 1000 * 60 * 60 /* 1 hour max */); if (data_) { NOTIFICATION_HISTOGRAM_COUNTS(LoadFileSize, type_, data_->size(), @@ -171,9 +173,9 @@ } void NotificationImageLoader::DidFail(const ResourceError& error) { - NOTIFICATION_HISTOGRAM_COUNTS(LoadFailTime, type_, - CurrentTimeTicksInMilliseconds() - start_time_, - 1000 * 60 * 60 /* 1 hour max */); + NOTIFICATION_HISTOGRAM_COUNTS( + LoadFailTime, type_, (CurrentTimeTicks() - start_time_).InMilliseconds(), + 1000 * 60 * 60 /* 1 hour max */); RunCallbackWithEmptyBitmap(); }
diff --git a/third_party/blink/renderer/modules/notifications/notification_image_loader.h b/third_party/blink/renderer/modules/notifications/notification_image_loader.h index 7fbc78ce..7b40f7d 100644 --- a/third_party/blink/renderer/modules/notifications/notification_image_loader.h +++ b/third_party/blink/renderer/modules/notifications/notification_image_loader.h
@@ -13,6 +13,7 @@ #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/shared_buffer.h" #include "third_party/blink/renderer/platform/wtf/functional.h" +#include "third_party/blink/renderer/platform/wtf/time.h" #include "third_party/skia/include/core/SkBitmap.h" namespace blink { @@ -65,7 +66,7 @@ Type type_; bool stopped_; - double start_time_; + TimeTicks start_time_; scoped_refptr<SharedBuffer> data_; ImageCallback image_callback_; Member<ThreadableLoader> threadable_loader_;
diff --git a/third_party/blink/renderer/modules/webdatabase/database.cc b/third_party/blink/renderer/modules/webdatabase/database.cc index 137ed1d1..47da36b 100644 --- a/third_party/blink/renderer/modules/webdatabase/database.cc +++ b/third_party/blink/renderer/modules/webdatabase/database.cc
@@ -55,7 +55,6 @@ #include "third_party/blink/renderer/platform/waitable_event.h" #include "third_party/blink/renderer/platform/web_task_runner.h" #include "third_party/blink/renderer/platform/wtf/atomics.h" -#include "third_party/blink/renderer/platform/wtf/time.h" // Registering "opened" databases with the DatabaseTracker // ======================================================= @@ -464,7 +463,7 @@ bool Database::PerformOpenAndVerify(bool should_set_version_in_new_database, DatabaseError& error, String& error_message) { - double call_start_time = WTF::CurrentTimeTicksInSeconds(); + TimeTicks call_start_time = WTF::CurrentTimeTicks(); DoneCreatingDatabaseOnExitCaller on_exit_caller(this); DCHECK(error_message.IsEmpty()); DCHECK_EQ(error, @@ -475,9 +474,9 @@ const int kMaxSqliteBusyWaitTime = 30000; if (!sqlite_database_.Open(filename_)) { - ReportOpenDatabaseResult( - 1, DOMExceptionCode::kInvalidStateError, sqlite_database_.LastError(), - WTF::CurrentTimeTicksInSeconds() - call_start_time); + ReportOpenDatabaseResult(1, DOMExceptionCode::kInvalidStateError, + sqlite_database_.LastError(), + WTF::CurrentTimeTicks() - call_start_time); error_message = FormatErrorMessage("unable to open database", sqlite_database_.LastError(), sqlite_database_.LastErrorMsg()); @@ -521,10 +520,9 @@ SQLiteTransaction transaction(sqlite_database_); transaction.begin(); if (!transaction.InProgress()) { - ReportOpenDatabaseResult( - 2, DOMExceptionCode::kInvalidStateError, - sqlite_database_.LastError(), - WTF::CurrentTimeTicksInSeconds() - call_start_time); + ReportOpenDatabaseResult(2, DOMExceptionCode::kInvalidStateError, + sqlite_database_.LastError(), + WTF::CurrentTimeTicks() - call_start_time); error_message = FormatErrorMessage( "unable to open database, failed to start transaction", sqlite_database_.LastError(), sqlite_database_.LastErrorMsg()); @@ -540,10 +538,9 @@ "CREATE TABLE " + table_name + " (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT " "REPLACE,value TEXT NOT NULL ON CONFLICT FAIL);")) { - ReportOpenDatabaseResult( - 3, DOMExceptionCode::kInvalidStateError, - sqlite_database_.LastError(), - WTF::CurrentTimeTicksInSeconds() - call_start_time); + ReportOpenDatabaseResult(3, DOMExceptionCode::kInvalidStateError, + sqlite_database_.LastError(), + WTF::CurrentTimeTicks() - call_start_time); error_message = FormatErrorMessage( "unable to open database, failed to create 'info' table", sqlite_database_.LastError(), sqlite_database_.LastErrorMsg()); @@ -552,10 +549,9 @@ return false; } } else if (!GetVersionFromDatabase(current_version, false)) { - ReportOpenDatabaseResult( - 4, DOMExceptionCode::kInvalidStateError, - sqlite_database_.LastError(), - WTF::CurrentTimeTicksInSeconds() - call_start_time); + ReportOpenDatabaseResult(4, DOMExceptionCode::kInvalidStateError, + sqlite_database_.LastError(), + WTF::CurrentTimeTicks() - call_start_time); error_message = FormatErrorMessage( "unable to open database, failed to read current version", sqlite_database_.LastError(), sqlite_database_.LastErrorMsg()); @@ -572,10 +568,9 @@ << " in database " << DatabaseDebugName() << " that was just created"; if (!SetVersionInDatabase(expected_version_, false)) { - ReportOpenDatabaseResult( - 5, DOMExceptionCode::kInvalidStateError, - sqlite_database_.LastError(), - WTF::CurrentTimeTicksInSeconds() - call_start_time); + ReportOpenDatabaseResult(5, DOMExceptionCode::kInvalidStateError, + sqlite_database_.LastError(), + WTF::CurrentTimeTicks() - call_start_time); error_message = FormatErrorMessage( "unable to open database, failed to write current version", sqlite_database_.LastError(), sqlite_database_.LastErrorMsg()); @@ -603,9 +598,8 @@ // whatever version of the database we have. if ((!new_ || should_set_version_in_new_database) && expected_version_.length() && expected_version_ != current_version) { - ReportOpenDatabaseResult( - 6, DOMExceptionCode::kInvalidStateError, 0, - WTF::CurrentTimeTicksInSeconds() - call_start_time); + ReportOpenDatabaseResult(6, DOMExceptionCode::kInvalidStateError, 0, + WTF::CurrentTimeTicks() - call_start_time); error_message = "unable to open database, version mismatch, '" + expected_version_ + "' does not match the currentVersion of '" + current_version + "'"; @@ -630,8 +624,8 @@ expected_version_ = ""; } - ReportOpenDatabaseResult( - 0, -1, 0, WTF::CurrentTimeTicksInSeconds() - call_start_time); // OK + ReportOpenDatabaseResult(0, -1, 0, + WTF::CurrentTimeTicks() - call_start_time); // OK if (GetDatabaseContext()->GetDatabaseThread()) GetDatabaseContext()->GetDatabaseThread()->RecordDatabaseOpen(this); @@ -787,7 +781,7 @@ void Database::ReportOpenDatabaseResult(int error_site, int web_sql_error_code, int sqlite_error_code, - double duration) { + TimeDelta duration) { if (Platform::Current()->DatabaseObserver()) { Platform::Current()->DatabaseObserver()->ReportOpenDatabaseResult( WebSecurityOrigin(GetSecurityOrigin()), StringIdentifier(), error_site,
diff --git a/third_party/blink/renderer/modules/webdatabase/database.h b/third_party/blink/renderer/modules/webdatabase/database.h index 456406c..028fca47 100644 --- a/third_party/blink/renderer/modules/webdatabase/database.h +++ b/third_party/blink/renderer/modules/webdatabase/database.h
@@ -38,6 +38,7 @@ #include "third_party/blink/renderer/platform/weborigin/security_origin.h" #include "third_party/blink/renderer/platform/wtf/deque.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "third_party/blink/renderer/platform/wtf/time.h" namespace blink { @@ -160,7 +161,7 @@ void ReportOpenDatabaseResult(int error_site, int web_sql_error_code, int sqlite_error_code, - double duration); + TimeDelta duration); void ReportChangeVersionResult(int error_site, int web_sql_error_code, int sqlite_error_code);
diff --git a/third_party/blink/renderer/platform/DEPS b/third_party/blink/renderer/platform/DEPS index 5488f86..c7b21e5 100644 --- a/third_party/blink/renderer/platform/DEPS +++ b/third_party/blink/renderer/platform/DEPS
@@ -43,6 +43,7 @@ "+base/time", "+base/timer", "+base/trace_event", + "+base/unguessable_token.h", "+base/values.h", "+base/lazy_instance.h", "+net/base/escape.h",
diff --git a/third_party/blink/renderer/platform/exported/web_prerendering_support.cc b/third_party/blink/renderer/platform/exported/web_prerendering_support.cc index c05a368..edc12ec 100644 --- a/third_party/blink/renderer/platform/exported/web_prerendering_support.cc +++ b/third_party/blink/renderer/platform/exported/web_prerendering_support.cc
@@ -34,14 +34,17 @@ WebPrerenderingSupport* WebPrerenderingSupport::platform_ = nullptr; +// static void WebPrerenderingSupport::Initialize(WebPrerenderingSupport* platform) { platform_ = platform; } +// static void WebPrerenderingSupport::Shutdown() { platform_ = nullptr; } +// static WebPrerenderingSupport* WebPrerenderingSupport::Current() { return platform_; }
diff --git a/third_party/blink/renderer/platform/exported/web_url_request.cc b/third_party/blink/renderer/platform/exported/web_url_request.cc index cde8e93e..09b885ea 100644 --- a/third_party/blink/renderer/platform/exported/web_url_request.cc +++ b/third_party/blink/renderer/platform/exported/web_url_request.cc
@@ -429,6 +429,11 @@ return resource_request_->AllowsStaleResponse(); } +const base::Optional<base::UnguessableToken>& WebURLRequest::GetDevToolsToken() + const { + return resource_request_->GetDevToolsToken(); +} + const ResourceRequest& WebURLRequest::ToResourceRequest() const { DCHECK(resource_request_); return *resource_request_;
diff --git a/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc b/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc index 5421d20..9d5aaf8 100644 --- a/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc +++ b/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc
@@ -337,8 +337,7 @@ DEFINE_STATIC_LOCAL( HashSet<AtomicString>, headers, ({"Cache-Control", "If-Modified-Since", "If-None-Match", "Origin", - "Pragma", "Purpose", "Referer", "User-Agent", - HTTPNames::X_DevTools_Emulate_Network_Conditions_Client_Id})); + "Pragma", "Purpose", "Referer", "User-Agent"})); return headers.Contains(header_name); }
diff --git a/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc b/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc index 906e8cb..44799f2 100644 --- a/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc +++ b/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc
@@ -214,17 +214,4 @@ EXPECT_FALSE(raw->IsAlive()); } -TEST_F(RawResourceTest, - CanReuseDevToolsEmulateNetworkConditionsClientIdHeader) { - scoped_refptr<const SecurityOrigin> source_origin = - SecurityOrigin::CreateUniqueOpaque(); - ResourceRequest request("data:text/html,"); - request.SetHTTPHeaderField( - HTTPNames::X_DevTools_Emulate_Network_Conditions_Client_Id, "Foo"); - Resource* raw = RawResource::CreateForTest(request, Resource::kRaw); - raw->SetSourceOrigin(source_origin); - EXPECT_TRUE(raw->CanReuse(FetchParameters(ResourceRequest("data:text/html,")), - source_origin)); -} - } // namespace blink
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 b4a5c44..d5874643 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
@@ -18,8 +18,8 @@ namespace { -// Field trial name. -const char kResourceLoadSchedulerTrial[] = "ResourceLoadScheduler"; +// Field trial name for throttling. +const char kResourceLoadThrottlingTrial[] = "ResourceLoadScheduler"; // Field trial parameter names. // Note: bg_limit is supported on m61+, but bg_sub_limit is only on m63+. @@ -95,7 +95,7 @@ return ResourceLoadScheduler::kOutstandingUnlimited; uint32_t main_frame_limit = GetFieldTrialUint32Param( - kResourceLoadSchedulerTrial, kOutstandingLimitForBackgroundMainFrameName, + kResourceLoadThrottlingTrial, kOutstandingLimitForBackgroundMainFrameName, kOutstandingLimitForBackgroundFrameDefault); if (context->IsMainFrame()) return main_frame_limit; @@ -103,7 +103,7 @@ // We do not have a fixed default limit for sub-frames, but use the limit for // the main frame so that it works as how previous versions that haven't // consider sub-frames' specific limit work. - return GetFieldTrialUint32Param(kResourceLoadSchedulerTrial, + return GetFieldTrialUint32Param(kResourceLoadThrottlingTrial, kOutstandingLimitForBackgroundSubFrameName, main_frame_limit); } @@ -114,6 +114,10 @@ return kilobytes; } +bool IsResourceLoadThrottlingEnabled() { + return RuntimeEnabledFeatures::ResourceLoadSchedulerEnabled(); +} + } // namespace // A class to gather throttling and traffic information to report histograms. @@ -574,18 +578,25 @@ bool ResourceLoadScheduler::IsThrottablePriority( ResourceLoadPriority priority) const { - if (RuntimeEnabledFeatures::ResourceLoadSchedulerEnabled()) { - // If this scheduler is throttled by the associated FrameScheduler, - // consider every prioritiy as throttlable. - const auto state = frame_scheduler_lifecycle_state_; - if (state == scheduler::SchedulingLifecycleState::kHidden || - state == scheduler::SchedulingLifecycleState::kThrottled || - state == scheduler::SchedulingLifecycleState::kStopped) { + const bool throttable = priority < ResourceLoadPriority::kHigh; + + // Also takes the lifecycle state of the associated FrameScheduler + // into account to determine if the request should be throttled + // regardless of the priority. + switch (frame_scheduler_lifecycle_state_) { + case scheduler::SchedulingLifecycleState::kNotThrottled: + return throttable; + case scheduler::SchedulingLifecycleState::kHidden: + case scheduler::SchedulingLifecycleState::kThrottled: + if (IsResourceLoadThrottlingEnabled()) + return true; + return throttable; + case scheduler::SchedulingLifecycleState::kStopped: return true; - } } - return priority < ResourceLoadPriority::kHigh; + NOTREACHED() << static_cast<int>(frame_scheduler_lifecycle_state_); + return throttable; } void ResourceLoadScheduler::OnLifecycleStateChanged( @@ -671,8 +682,7 @@ case scheduler::SchedulingLifecycleState::kNotThrottled: break; case scheduler::SchedulingLifecycleState::kStopped: - if (RuntimeEnabledFeatures::ResourceLoadSchedulerEnabled()) - limit = 0; + limit = 0; break; }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request.cc b/third_party/blink/renderer/platform/loader/fetch/resource_request.cc index 36d7cd7..a75502d 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_request.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.cc
@@ -28,6 +28,7 @@ #include <memory> +#include "base/unguessable_token.h" #include "third_party/blink/public/platform/web_url_request.h" #include "third_party/blink/renderer/platform/network/http_names.h" #include "third_party/blink/renderer/platform/network/network_utils.h" @@ -127,6 +128,7 @@ is_ad_resource_ = data->is_ad_resource_; SetInitiatorCSP(data->navigation_csp_); upgrade_if_insecure_ = data->upgrade_if_insecure_; + devtools_token_ = data->devtools_token_; } ResourceRequest::ResourceRequest(const ResourceRequest&) = default; @@ -224,6 +226,7 @@ data->navigation_csp_ = initiator_csp_; data->upgrade_if_insecure_ = upgrade_if_insecure_; + data->devtools_token_ = devtools_token_; return data; }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request.h b/third_party/blink/renderer/platform/loader/fetch/resource_request.h index 0ee028a..f358fd5 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_request.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.h
@@ -31,6 +31,7 @@ #include <memory> #include "base/optional.h" #include "base/time/time.h" +#include "base/unguessable_token.h" #include "services/network/public/mojom/cors.mojom-blink.h" #include "services/network/public/mojom/fetch_api.mojom-blink.h" #include "services/network/public/mojom/request_context_frame_type.mojom-shared.h" @@ -379,6 +380,14 @@ void SetAllowStaleResponse(bool value) { allow_stale_response_ = value; } bool AllowsStaleResponse() const { return allow_stale_response_; } + const base::Optional<base::UnguessableToken>& GetDevToolsToken() const { + return devtools_token_; + } + void SetDevToolsToken( + const base::Optional<base::UnguessableToken>& devtools_token) { + devtools_token_ = devtools_token; + } + private: using SharableExtraData = base::RefCountedData<std::unique_ptr<WebURLRequest::ExtraData>>; @@ -448,6 +457,8 @@ WebContentSecurityPolicyList initiator_csp_; bool upgrade_if_insecure_ = false; + + base::Optional<base::UnguessableToken> devtools_token_; }; // This class is needed to copy a ResourceRequest across threads, because it @@ -507,6 +518,7 @@ bool is_ad_resource_; WebContentSecurityPolicyList navigation_csp_; bool upgrade_if_insecure_; + base::Optional<base::UnguessableToken> devtools_token_; }; } // namespace blink
diff --git a/third_party/blink/renderer/platform/network/http_names.json5 b/third_party/blink/renderer/platform/network/http_names.json5 index 2ef7f762..c50743e 100644 --- a/third_party/blink/renderer/platform/network/http_names.json5 +++ b/third_party/blink/renderer/platform/network/http_names.json5
@@ -65,7 +65,6 @@ "Vary", "X-Content-Type-Options", "X-DNS-Prefetch-Control", - "X-DevTools-Emulate-Network-Conditions-Client-Id", "X-Frame-Options", "X-SourceMap", "X-XSS-Protection",
diff --git a/third_party/fontconfig/BUILD.gn b/third_party/fontconfig/BUILD.gn index 3175758..8ff1984 100644 --- a/third_party/fontconfig/BUILD.gn +++ b/third_party/fontconfig/BUILD.gn
@@ -15,6 +15,7 @@ sources = [ "src/src/fcarch.h", "src/src/fcatomic.c", + "src/src/fcblanks.c", "src/src/fccache.c", "src/src/fccfg.c", "src/src/fccharset.c", @@ -25,7 +26,6 @@ "src/src/fcformat.c", "src/src/fcfreetype.c", "src/src/fcfs.c", - "src/src/fchash.c", "src/src/fcinit.c", "src/src/fclang.c", "src/src/fclist.c", @@ -34,7 +34,6 @@ "src/src/fcname.c", "src/src/fcobjs.c", "src/src/fcpat.c", - "src/src/fcptrlist.c", "src/src/fcrange.c", "src/src/fcserialize.c", "src/src/fcstat.c", @@ -53,17 +52,14 @@ defines = [ "HAVE_CONFIG_H", "FC_CACHEDIR=\"/var/cache/fontconfig\"", - "FC_TEMPLATEDIR=\"/usr/share/fontconfig/conf.avail\"", "FONTCONFIG_PATH=\"/etc/fonts\"", ] - # Fontconfig symbols should not be exported from chrome, nacl_helper, or - # anything else. + # This is a hack to remove visibility("default") annotations. Fontconfig + # symbols should not be exported from chrome, nacl_helper, or anything + # else. if (!is_component_build) { - defines += [ - "FC_ATTRIBUTE_VISIBILITY_HIDDEN=__attribute((visibility(\"hidden\")))", - "FC_ATTRIBUTE_VISIBILITY_EXPORT=__attribute((visibility(\"hidden\")))", - ] + defines += [ "visibility(x)=" ] } deps = [ @@ -86,10 +82,6 @@ "-Wno-pointer-bool-conversion", ] } - - if (!is_win) { - libs = [ "uuid" ] - } } } else { config("fontconfig_config") {
diff --git a/third_party/fontconfig/OWNERS b/third_party/fontconfig/OWNERS index 17f42ca..82160d5 100644 --- a/third_party/fontconfig/OWNERS +++ b/third_party/fontconfig/OWNERS
@@ -1,3 +1,2 @@ spang@chromium.org dnicoara@chromium.org -thomasanderson@chromium.org
diff --git a/third_party/fontconfig/README.chromium b/third_party/fontconfig/README.chromium index 09a0862..5a7a10c 100644 --- a/third_party/fontconfig/README.chromium +++ b/third_party/fontconfig/README.chromium
@@ -1,6 +1,6 @@ Name: fontconfig URL: http://www.freedesktop.org/wiki/Software/fontconfig/ -Version: 6cc99d6a82ad67d2f5eac887b28bca13c0dfddde +Version: 2.12.6 License: MIT License File: src/COPYING Security Critical: yes @@ -12,11 +12,9 @@ - None To import a new snapshot of fontconfig: -- Checkout the latest revision: - git fetch origin master - git checkout origin/master +- Checkout the latest release tag: git checkout 2.12.6 - Change the DEPS entry to the newly checked out commit. - Update generated files: - ./autogen.sh --enable-libxml2 --disable-docs && make + ./autogen.sh --enable-libxml2 && make rsync -R $(git ls-files --others '*.h' '*/*.h') ../include - Update this README to reflect the new version number.
diff --git a/third_party/fontconfig/include/config.h b/third_party/fontconfig/include/config.h index 3742680..82b0e658 100644 --- a/third_party/fontconfig/include/config.h +++ b/third_party/fontconfig/include/config.h
@@ -13,10 +13,6 @@ /* Use libxml2 instead of Expat */ #define ENABLE_LIBXML2 1 -/* Define to 1 if translation of program messages to the user's native - language is requested. */ -#define ENABLE_NLS 1 - /* Additional font directories */ #define FC_ADD_FONTS "yes" @@ -27,7 +23,7 @@ #define FC_DEFAULT_FONTS "/usr/share/fonts" /* The type of len parameter of the gperf hash/lookup function */ -#define FC_GPERF_SIZE_T size_t +#define FC_GPERF_SIZE_T unsigned int /* Define to nothing if C supports flexible array members, and to 1 if it does not. That way, with a declaration like `struct s { int n; double @@ -38,21 +34,6 @@ MSVC and with C++ compilers. */ #define FLEXIBLE_ARRAY_MEMBER /**/ -/* Gettext package */ -#define GETTEXT_PACKAGE "fontconfig" - -/* Define to 1 if you have the Mac OS X function CFLocaleCopyCurrent in the - CoreFoundation framework. */ -/* #undef HAVE_CFLOCALECOPYCURRENT */ - -/* Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in - the CoreFoundation framework. */ -/* #undef HAVE_CFPREFERENCESCOPYAPPVALUE */ - -/* Define if the GNU dcgettext() function is already present or preinstalled. - */ -#define HAVE_DCGETTEXT 1 - /* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'. */ #define HAVE_DIRENT_H 1 @@ -72,12 +53,15 @@ /* Define to 1 if you have the `fstatvfs' function. */ #define HAVE_FSTATVFS 1 -/* Define to 1 if you have the `FT_Done_MM_Var' function. */ -/* #undef HAVE_FT_DONE_MM_VAR */ +/* FT_Bitmap_Size structure includes y_ppem field */ +#define HAVE_FT_BITMAP_SIZE_Y_PPEM 1 /* Define to 1 if you have the `FT_Get_BDF_Property' function. */ #define HAVE_FT_GET_BDF_PROPERTY 1 +/* Define to 1 if you have the `FT_Get_Next_Char' function. */ +#define HAVE_FT_GET_NEXT_CHAR 1 + /* Define to 1 if you have the `FT_Get_PS_Font_Info' function. */ #define HAVE_FT_GET_PS_FONT_INFO 1 @@ -87,6 +71,9 @@ /* Define to 1 if you have the `FT_Has_PS_Glyph_Names' function. */ #define HAVE_FT_HAS_PS_GLYPH_NAMES 1 +/* Define to 1 if you have the `FT_Select_Size' function. */ +#define HAVE_FT_SELECT_SIZE 1 + /* Define to 1 if you have the `getexecname' function. */ /* #undef HAVE_GETEXECNAME */ @@ -102,12 +89,6 @@ /* Define to 1 if you have the `getprogname' function. */ /* #undef HAVE_GETPROGNAME */ -/* Define if the GNU gettext() function is already present or preinstalled. */ -#define HAVE_GETTEXT 1 - -/* Define if you have the iconv() function and it works. */ -/* #undef HAVE_ICONV */ - /* Have Intel __sync_* atomic primitives */ #define HAVE_INTEL_ATOMIC_PRIMITIVES 1 @@ -180,12 +161,6 @@ /* Define to 1 if you have the <stdlib.h> header file. */ #define HAVE_STDLIB_H 1 -/* Define to 1 if you have the `strerror' function. */ -#define HAVE_STRERROR 1 - -/* Define to 1 if you have the `strerror_r' function. */ -#define HAVE_STRERROR_R 1 - /* Define to 1 if you have the <strings.h> header file. */ #define HAVE_STRINGS_H 1 @@ -239,6 +214,12 @@ /* Define to 1 if you have the <sys/vfs.h> header file. */ #define HAVE_SYS_VFS_H 1 +/* Define to 1 if `usLowerOpticalPointSize' is a member of `TT_OS2'. */ +#define HAVE_TT_OS2_USLOWEROPTICALPOINTSIZE 1 + +/* Define to 1 if `usUpperOpticalPointSize' is a member of `TT_OS2'. */ +#define HAVE_TT_OS2_USUPPEROPTICALPOINTSIZE 1 + /* Define to 1 if you have the <unistd.h> header file. */ #define HAVE_UNISTD_H 1 @@ -270,7 +251,7 @@ #define PACKAGE_NAME "fontconfig" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "fontconfig 2.13.0" +#define PACKAGE_STRING "fontconfig 2.12.6" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "fontconfig" @@ -279,7 +260,7 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "2.13.0" +#define PACKAGE_VERSION "2.12.6" /* Define to necessary symbol if this constant uses a non-standard name on your system. */ @@ -332,7 +313,7 @@ /* Version number of package */ -#define VERSION "2.13.0" +#define VERSION "2.12.6" /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */
diff --git a/third_party/fontconfig/include/fc-case/fccase.h b/third_party/fontconfig/include/fc-case/fccase.h index 9cc0b9f..5be716d 100644 --- a/third_party/fontconfig/include/fc-case/fccase.h +++ b/third_party/fontconfig/include/fc-case/fccase.h
@@ -22,7 +22,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#define FC_NUM_CASE_FOLD 291 +#define FC_NUM_CASE_FOLD 288 #define FC_NUM_CASE_FOLD_CHARS 471 #define FC_MAX_CASE_FOLD_CHARS 6 #define FC_MAX_CASE_FOLD_EXPAND 4 @@ -146,8 +146,6 @@ { 0x00001c86, FC_CASE_FOLD_RANGE, 0x0001, -6204 }, { 0x00001c87, FC_CASE_FOLD_RANGE, 0x0001, -6180 }, { 0x00001c88, FC_CASE_FOLD_RANGE, 0x0001, -30269 }, - { 0x00001c90, FC_CASE_FOLD_RANGE, 0x002b, -3008 }, - { 0x00001cbd, FC_CASE_FOLD_RANGE, 0x0003, -3008 }, { 0x00001e00, FC_CASE_FOLD_EVEN_ODD, 0x0095, 1 }, { 0x00001e96, FC_CASE_FOLD_FULL, 0x0003, 27 }, { 0x00001e97, FC_CASE_FOLD_FULL, 0x0003, 30 }, @@ -300,7 +298,7 @@ { 0x0000a7b1, FC_CASE_FOLD_RANGE, 0x0001, 23254 }, { 0x0000a7b2, FC_CASE_FOLD_RANGE, 0x0001, 23275 }, { 0x0000a7b3, FC_CASE_FOLD_RANGE, 0x0001, 928 }, - { 0x0000a7b4, FC_CASE_FOLD_EVEN_ODD, 0x0005, 1 }, + { 0x0000a7b4, FC_CASE_FOLD_EVEN_ODD, 0x0003, 1 }, { 0x0000ab70, FC_CASE_FOLD_RANGE, 0x0050, 26672 }, { 0x0000fb00, FC_CASE_FOLD_FULL, 0x0002, 435 }, { 0x0000fb01, FC_CASE_FOLD_FULL, 0x0002, 437 }, @@ -319,7 +317,6 @@ { 0x000104b0, FC_CASE_FOLD_RANGE, 0x0024, 40 }, { 0x00010c80, FC_CASE_FOLD_RANGE, 0x0033, 64 }, { 0x000118a0, FC_CASE_FOLD_RANGE, 0x0020, 32 }, - { 0x00016e40, FC_CASE_FOLD_RANGE, 0x0020, 32 }, { 0x0001e900, FC_CASE_FOLD_RANGE, 0x0022, 34 }, };
diff --git a/third_party/fontconfig/include/src/fcalias.h b/third_party/fontconfig/include/src/fcalias.h index da5f5f1..1539158 100644 --- a/third_party/fontconfig/include/src/fcalias.h +++ b/third_party/fontconfig/include/src/fcalias.h
@@ -1,448 +1,414 @@ -extern __typeof (FcBlanksCreate) IA__FcBlanksCreate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcBlanksCreate) IA__FcBlanksCreate __attribute((visibility("hidden"))); #define FcBlanksCreate IA__FcBlanksCreate -extern __typeof (FcBlanksDestroy) IA__FcBlanksDestroy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcBlanksDestroy) IA__FcBlanksDestroy __attribute((visibility("hidden"))); #define FcBlanksDestroy IA__FcBlanksDestroy -extern __typeof (FcBlanksAdd) IA__FcBlanksAdd FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcBlanksAdd) IA__FcBlanksAdd __attribute((visibility("hidden"))); #define FcBlanksAdd IA__FcBlanksAdd -extern __typeof (FcBlanksIsMember) IA__FcBlanksIsMember FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcBlanksIsMember) IA__FcBlanksIsMember __attribute((visibility("hidden"))); #define FcBlanksIsMember IA__FcBlanksIsMember -extern __typeof (FcCacheCopySet) IA__FcCacheCopySet FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcCacheCopySet) IA__FcCacheCopySet __attribute((visibility("hidden"))); #define FcCacheCopySet IA__FcCacheCopySet -extern __typeof (FcCacheNumSubdir) IA__FcCacheNumSubdir FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcCacheNumSubdir) IA__FcCacheNumSubdir __attribute((visibility("hidden"))); #define FcCacheNumSubdir IA__FcCacheNumSubdir -extern __typeof (FcCacheNumFont) IA__FcCacheNumFont FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcCacheNumFont) IA__FcCacheNumFont __attribute((visibility("hidden"))); #define FcCacheNumFont IA__FcCacheNumFont -extern __typeof (FcDirCacheUnlink) IA__FcDirCacheUnlink FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcDirCacheUnlink) IA__FcDirCacheUnlink __attribute((visibility("hidden"))); #define FcDirCacheUnlink IA__FcDirCacheUnlink -extern __typeof (FcDirCacheValid) IA__FcDirCacheValid FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcDirCacheValid) IA__FcDirCacheValid __attribute((visibility("hidden"))); #define FcDirCacheValid IA__FcDirCacheValid -extern __typeof (FcDirCacheClean) IA__FcDirCacheClean FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcDirCacheClean) IA__FcDirCacheClean __attribute((visibility("hidden"))); #define FcDirCacheClean IA__FcDirCacheClean -extern __typeof (FcCacheCreateTagFile) IA__FcCacheCreateTagFile FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcCacheCreateTagFile) IA__FcCacheCreateTagFile __attribute((visibility("hidden"))); #define FcCacheCreateTagFile IA__FcCacheCreateTagFile -extern __typeof (FcDirCacheCreateUUID) IA__FcDirCacheCreateUUID FC_ATTRIBUTE_VISIBILITY_HIDDEN; -#define FcDirCacheCreateUUID IA__FcDirCacheCreateUUID -extern __typeof (FcDirCacheDeleteUUID) IA__FcDirCacheDeleteUUID FC_ATTRIBUTE_VISIBILITY_HIDDEN; -#define FcDirCacheDeleteUUID IA__FcDirCacheDeleteUUID -extern __typeof (FcConfigHome) IA__FcConfigHome FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigHome) IA__FcConfigHome __attribute((visibility("hidden"))); #define FcConfigHome IA__FcConfigHome -extern __typeof (FcConfigEnableHome) IA__FcConfigEnableHome FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigEnableHome) IA__FcConfigEnableHome __attribute((visibility("hidden"))); #define FcConfigEnableHome IA__FcConfigEnableHome -extern __typeof (FcConfigFilename) IA__FcConfigFilename FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigFilename) IA__FcConfigFilename __attribute((visibility("hidden"))); #define FcConfigFilename IA__FcConfigFilename -extern __typeof (FcConfigCreate) IA__FcConfigCreate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigCreate) IA__FcConfigCreate __attribute((visibility("hidden"))); #define FcConfigCreate IA__FcConfigCreate -extern __typeof (FcConfigReference) IA__FcConfigReference FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigReference) IA__FcConfigReference __attribute((visibility("hidden"))); #define FcConfigReference IA__FcConfigReference -extern __typeof (FcConfigDestroy) IA__FcConfigDestroy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigDestroy) IA__FcConfigDestroy __attribute((visibility("hidden"))); #define FcConfigDestroy IA__FcConfigDestroy -extern __typeof (FcConfigSetCurrent) IA__FcConfigSetCurrent FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigSetCurrent) IA__FcConfigSetCurrent __attribute((visibility("hidden"))); #define FcConfigSetCurrent IA__FcConfigSetCurrent -extern __typeof (FcConfigGetCurrent) IA__FcConfigGetCurrent FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigGetCurrent) IA__FcConfigGetCurrent __attribute((visibility("hidden"))); #define FcConfigGetCurrent IA__FcConfigGetCurrent -extern __typeof (FcConfigUptoDate) IA__FcConfigUptoDate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigUptoDate) IA__FcConfigUptoDate __attribute((visibility("hidden"))); #define FcConfigUptoDate IA__FcConfigUptoDate -extern __typeof (FcConfigBuildFonts) IA__FcConfigBuildFonts FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigBuildFonts) IA__FcConfigBuildFonts __attribute((visibility("hidden"))); #define FcConfigBuildFonts IA__FcConfigBuildFonts -extern __typeof (FcConfigGetFontDirs) IA__FcConfigGetFontDirs FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigGetFontDirs) IA__FcConfigGetFontDirs __attribute((visibility("hidden"))); #define FcConfigGetFontDirs IA__FcConfigGetFontDirs -extern __typeof (FcConfigGetConfigDirs) IA__FcConfigGetConfigDirs FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigGetConfigDirs) IA__FcConfigGetConfigDirs __attribute((visibility("hidden"))); #define FcConfigGetConfigDirs IA__FcConfigGetConfigDirs -extern __typeof (FcConfigGetConfigFiles) IA__FcConfigGetConfigFiles FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigGetConfigFiles) IA__FcConfigGetConfigFiles __attribute((visibility("hidden"))); #define FcConfigGetConfigFiles IA__FcConfigGetConfigFiles -extern __typeof (FcConfigGetCache) IA__FcConfigGetCache FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigGetCache) IA__FcConfigGetCache __attribute((visibility("hidden"))); #define FcConfigGetCache IA__FcConfigGetCache -extern __typeof (FcConfigGetBlanks) IA__FcConfigGetBlanks FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigGetBlanks) IA__FcConfigGetBlanks __attribute((visibility("hidden"))); #define FcConfigGetBlanks IA__FcConfigGetBlanks -extern __typeof (FcConfigGetCacheDirs) IA__FcConfigGetCacheDirs FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigGetCacheDirs) IA__FcConfigGetCacheDirs __attribute((visibility("hidden"))); #define FcConfigGetCacheDirs IA__FcConfigGetCacheDirs -extern __typeof (FcConfigGetRescanInterval) IA__FcConfigGetRescanInterval FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigGetRescanInterval) IA__FcConfigGetRescanInterval __attribute((visibility("hidden"))); #define FcConfigGetRescanInterval IA__FcConfigGetRescanInterval -extern __typeof (FcConfigSetRescanInterval) IA__FcConfigSetRescanInterval FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigSetRescanInterval) IA__FcConfigSetRescanInterval __attribute((visibility("hidden"))); #define FcConfigSetRescanInterval IA__FcConfigSetRescanInterval -extern __typeof (FcConfigGetFonts) IA__FcConfigGetFonts FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigGetFonts) IA__FcConfigGetFonts __attribute((visibility("hidden"))); #define FcConfigGetFonts IA__FcConfigGetFonts -extern __typeof (FcConfigAppFontAddFile) IA__FcConfigAppFontAddFile FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigAppFontAddFile) IA__FcConfigAppFontAddFile __attribute((visibility("hidden"))); #define FcConfigAppFontAddFile IA__FcConfigAppFontAddFile -extern __typeof (FcConfigAppFontAddDir) IA__FcConfigAppFontAddDir FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigAppFontAddDir) IA__FcConfigAppFontAddDir __attribute((visibility("hidden"))); #define FcConfigAppFontAddDir IA__FcConfigAppFontAddDir -extern __typeof (FcConfigAppFontClear) IA__FcConfigAppFontClear FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigAppFontClear) IA__FcConfigAppFontClear __attribute((visibility("hidden"))); #define FcConfigAppFontClear IA__FcConfigAppFontClear -extern __typeof (FcConfigSubstituteWithPat) IA__FcConfigSubstituteWithPat FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigSubstituteWithPat) IA__FcConfigSubstituteWithPat __attribute((visibility("hidden"))); #define FcConfigSubstituteWithPat IA__FcConfigSubstituteWithPat -extern __typeof (FcConfigSubstitute) IA__FcConfigSubstitute FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigSubstitute) IA__FcConfigSubstitute __attribute((visibility("hidden"))); #define FcConfigSubstitute IA__FcConfigSubstitute -extern __typeof (FcConfigGetSysRoot) IA__FcConfigGetSysRoot FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigGetSysRoot) IA__FcConfigGetSysRoot __attribute((visibility("hidden"))); #define FcConfigGetSysRoot IA__FcConfigGetSysRoot -extern __typeof (FcConfigSetSysRoot) IA__FcConfigSetSysRoot FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigSetSysRoot) IA__FcConfigSetSysRoot __attribute((visibility("hidden"))); #define FcConfigSetSysRoot IA__FcConfigSetSysRoot -extern __typeof (FcConfigFileInfoIterInit) IA__FcConfigFileInfoIterInit FC_ATTRIBUTE_VISIBILITY_HIDDEN; -#define FcConfigFileInfoIterInit IA__FcConfigFileInfoIterInit -extern __typeof (FcConfigFileInfoIterNext) IA__FcConfigFileInfoIterNext FC_ATTRIBUTE_VISIBILITY_HIDDEN; -#define FcConfigFileInfoIterNext IA__FcConfigFileInfoIterNext -extern __typeof (FcConfigFileInfoIterGet) IA__FcConfigFileInfoIterGet FC_ATTRIBUTE_VISIBILITY_HIDDEN; -#define FcConfigFileInfoIterGet IA__FcConfigFileInfoIterGet -extern __typeof (FcCharSetCreate) IA__FcCharSetCreate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcCharSetCreate) IA__FcCharSetCreate __attribute((visibility("hidden"))); #define FcCharSetCreate IA__FcCharSetCreate -extern __typeof (FcCharSetNew) IA__FcCharSetNew FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcCharSetNew) IA__FcCharSetNew __attribute((visibility("hidden"))); #define FcCharSetNew IA__FcCharSetNew -extern __typeof (FcCharSetDestroy) IA__FcCharSetDestroy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcCharSetDestroy) IA__FcCharSetDestroy __attribute((visibility("hidden"))); #define FcCharSetDestroy IA__FcCharSetDestroy -extern __typeof (FcCharSetAddChar) IA__FcCharSetAddChar FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcCharSetAddChar) IA__FcCharSetAddChar __attribute((visibility("hidden"))); #define FcCharSetAddChar IA__FcCharSetAddChar -extern __typeof (FcCharSetDelChar) IA__FcCharSetDelChar FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcCharSetDelChar) IA__FcCharSetDelChar __attribute((visibility("hidden"))); #define FcCharSetDelChar IA__FcCharSetDelChar -extern __typeof (FcCharSetCopy) IA__FcCharSetCopy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcCharSetCopy) IA__FcCharSetCopy __attribute((visibility("hidden"))); #define FcCharSetCopy IA__FcCharSetCopy -extern __typeof (FcCharSetEqual) IA__FcCharSetEqual FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcCharSetEqual) IA__FcCharSetEqual __attribute((visibility("hidden"))); #define FcCharSetEqual IA__FcCharSetEqual -extern __typeof (FcCharSetIntersect) IA__FcCharSetIntersect FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcCharSetIntersect) IA__FcCharSetIntersect __attribute((visibility("hidden"))); #define FcCharSetIntersect IA__FcCharSetIntersect -extern __typeof (FcCharSetUnion) IA__FcCharSetUnion FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcCharSetUnion) IA__FcCharSetUnion __attribute((visibility("hidden"))); #define FcCharSetUnion IA__FcCharSetUnion -extern __typeof (FcCharSetSubtract) IA__FcCharSetSubtract FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcCharSetSubtract) IA__FcCharSetSubtract __attribute((visibility("hidden"))); #define FcCharSetSubtract IA__FcCharSetSubtract -extern __typeof (FcCharSetMerge) IA__FcCharSetMerge FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcCharSetMerge) IA__FcCharSetMerge __attribute((visibility("hidden"))); #define FcCharSetMerge IA__FcCharSetMerge -extern __typeof (FcCharSetHasChar) IA__FcCharSetHasChar FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcCharSetHasChar) IA__FcCharSetHasChar __attribute((visibility("hidden"))); #define FcCharSetHasChar IA__FcCharSetHasChar -extern __typeof (FcCharSetCount) IA__FcCharSetCount FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcCharSetCount) IA__FcCharSetCount __attribute((visibility("hidden"))); #define FcCharSetCount IA__FcCharSetCount -extern __typeof (FcCharSetIntersectCount) IA__FcCharSetIntersectCount FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcCharSetIntersectCount) IA__FcCharSetIntersectCount __attribute((visibility("hidden"))); #define FcCharSetIntersectCount IA__FcCharSetIntersectCount -extern __typeof (FcCharSetSubtractCount) IA__FcCharSetSubtractCount FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcCharSetSubtractCount) IA__FcCharSetSubtractCount __attribute((visibility("hidden"))); #define FcCharSetSubtractCount IA__FcCharSetSubtractCount -extern __typeof (FcCharSetIsSubset) IA__FcCharSetIsSubset FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcCharSetIsSubset) IA__FcCharSetIsSubset __attribute((visibility("hidden"))); #define FcCharSetIsSubset IA__FcCharSetIsSubset -extern __typeof (FcCharSetFirstPage) IA__FcCharSetFirstPage FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcCharSetFirstPage) IA__FcCharSetFirstPage __attribute((visibility("hidden"))); #define FcCharSetFirstPage IA__FcCharSetFirstPage -extern __typeof (FcCharSetNextPage) IA__FcCharSetNextPage FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcCharSetNextPage) IA__FcCharSetNextPage __attribute((visibility("hidden"))); #define FcCharSetNextPage IA__FcCharSetNextPage -extern __typeof (FcCharSetCoverage) IA__FcCharSetCoverage FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcCharSetCoverage) IA__FcCharSetCoverage __attribute((visibility("hidden"))); #define FcCharSetCoverage IA__FcCharSetCoverage -extern __typeof (FcValuePrint) IA__FcValuePrint FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcValuePrint) IA__FcValuePrint __attribute((visibility("hidden"))); #define FcValuePrint IA__FcValuePrint -extern __typeof (FcPatternPrint) IA__FcPatternPrint FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternPrint) IA__FcPatternPrint __attribute((visibility("hidden"))); #define FcPatternPrint IA__FcPatternPrint -extern __typeof (FcFontSetPrint) IA__FcFontSetPrint FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcFontSetPrint) IA__FcFontSetPrint __attribute((visibility("hidden"))); #define FcFontSetPrint IA__FcFontSetPrint -extern __typeof (FcGetDefaultLangs) IA__FcGetDefaultLangs FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcGetDefaultLangs) IA__FcGetDefaultLangs __attribute((visibility("hidden"))); #define FcGetDefaultLangs IA__FcGetDefaultLangs -extern __typeof (FcDefaultSubstitute) IA__FcDefaultSubstitute FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcDefaultSubstitute) IA__FcDefaultSubstitute __attribute((visibility("hidden"))); #define FcDefaultSubstitute IA__FcDefaultSubstitute -extern __typeof (FcFileIsDir) IA__FcFileIsDir FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcFileIsDir) IA__FcFileIsDir __attribute((visibility("hidden"))); #define FcFileIsDir IA__FcFileIsDir -extern __typeof (FcFileScan) IA__FcFileScan FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcFileScan) IA__FcFileScan __attribute((visibility("hidden"))); #define FcFileScan IA__FcFileScan -extern __typeof (FcDirScan) IA__FcDirScan FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcDirScan) IA__FcDirScan __attribute((visibility("hidden"))); #define FcDirScan IA__FcDirScan -extern __typeof (FcDirSave) IA__FcDirSave FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcDirSave) IA__FcDirSave __attribute((visibility("hidden"))); #define FcDirSave IA__FcDirSave -extern __typeof (FcDirCacheLoad) IA__FcDirCacheLoad FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcDirCacheLoad) IA__FcDirCacheLoad __attribute((visibility("hidden"))); #define FcDirCacheLoad IA__FcDirCacheLoad -extern __typeof (FcDirCacheRescan) IA__FcDirCacheRescan FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcDirCacheRescan) IA__FcDirCacheRescan __attribute((visibility("hidden"))); #define FcDirCacheRescan IA__FcDirCacheRescan -extern __typeof (FcDirCacheRead) IA__FcDirCacheRead FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcDirCacheRead) IA__FcDirCacheRead __attribute((visibility("hidden"))); #define FcDirCacheRead IA__FcDirCacheRead -extern __typeof (FcDirCacheLoadFile) IA__FcDirCacheLoadFile FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcDirCacheLoadFile) IA__FcDirCacheLoadFile __attribute((visibility("hidden"))); #define FcDirCacheLoadFile IA__FcDirCacheLoadFile -extern __typeof (FcDirCacheUnload) IA__FcDirCacheUnload FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcDirCacheUnload) IA__FcDirCacheUnload __attribute((visibility("hidden"))); #define FcDirCacheUnload IA__FcDirCacheUnload -extern __typeof (FcFreeTypeQuery) IA__FcFreeTypeQuery FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcFreeTypeQuery) IA__FcFreeTypeQuery __attribute((visibility("hidden"))); #define FcFreeTypeQuery IA__FcFreeTypeQuery -extern __typeof (FcFreeTypeQueryAll) IA__FcFreeTypeQueryAll FC_ATTRIBUTE_VISIBILITY_HIDDEN; -#define FcFreeTypeQueryAll IA__FcFreeTypeQueryAll -extern __typeof (FcFontSetCreate) IA__FcFontSetCreate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcFontSetCreate) IA__FcFontSetCreate __attribute((visibility("hidden"))); #define FcFontSetCreate IA__FcFontSetCreate -extern __typeof (FcFontSetDestroy) IA__FcFontSetDestroy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcFontSetDestroy) IA__FcFontSetDestroy __attribute((visibility("hidden"))); #define FcFontSetDestroy IA__FcFontSetDestroy -extern __typeof (FcFontSetAdd) IA__FcFontSetAdd FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcFontSetAdd) IA__FcFontSetAdd __attribute((visibility("hidden"))); #define FcFontSetAdd IA__FcFontSetAdd -extern __typeof (FcInitLoadConfig) IA__FcInitLoadConfig FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcInitLoadConfig) IA__FcInitLoadConfig __attribute((visibility("hidden"))); #define FcInitLoadConfig IA__FcInitLoadConfig -extern __typeof (FcInitLoadConfigAndFonts) IA__FcInitLoadConfigAndFonts FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcInitLoadConfigAndFonts) IA__FcInitLoadConfigAndFonts __attribute((visibility("hidden"))); #define FcInitLoadConfigAndFonts IA__FcInitLoadConfigAndFonts -extern __typeof (FcInit) IA__FcInit FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcInit) IA__FcInit __attribute((visibility("hidden"))); #define FcInit IA__FcInit -extern __typeof (FcFini) IA__FcFini FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcFini) IA__FcFini __attribute((visibility("hidden"))); #define FcFini IA__FcFini -extern __typeof (FcGetVersion) IA__FcGetVersion FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcGetVersion) IA__FcGetVersion __attribute((visibility("hidden"))); #define FcGetVersion IA__FcGetVersion -extern __typeof (FcInitReinitialize) IA__FcInitReinitialize FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcInitReinitialize) IA__FcInitReinitialize __attribute((visibility("hidden"))); #define FcInitReinitialize IA__FcInitReinitialize -extern __typeof (FcInitBringUptoDate) IA__FcInitBringUptoDate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcInitBringUptoDate) IA__FcInitBringUptoDate __attribute((visibility("hidden"))); #define FcInitBringUptoDate IA__FcInitBringUptoDate -extern __typeof (FcGetLangs) IA__FcGetLangs FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcGetLangs) IA__FcGetLangs __attribute((visibility("hidden"))); #define FcGetLangs IA__FcGetLangs -extern __typeof (FcLangNormalize) IA__FcLangNormalize FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcLangNormalize) IA__FcLangNormalize __attribute((visibility("hidden"))); #define FcLangNormalize IA__FcLangNormalize -extern __typeof (FcLangGetCharSet) IA__FcLangGetCharSet FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcLangGetCharSet) IA__FcLangGetCharSet __attribute((visibility("hidden"))); #define FcLangGetCharSet IA__FcLangGetCharSet -extern __typeof (FcLangSetCreate) IA__FcLangSetCreate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcLangSetCreate) IA__FcLangSetCreate __attribute((visibility("hidden"))); #define FcLangSetCreate IA__FcLangSetCreate -extern __typeof (FcLangSetDestroy) IA__FcLangSetDestroy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcLangSetDestroy) IA__FcLangSetDestroy __attribute((visibility("hidden"))); #define FcLangSetDestroy IA__FcLangSetDestroy -extern __typeof (FcLangSetCopy) IA__FcLangSetCopy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcLangSetCopy) IA__FcLangSetCopy __attribute((visibility("hidden"))); #define FcLangSetCopy IA__FcLangSetCopy -extern __typeof (FcLangSetAdd) IA__FcLangSetAdd FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcLangSetAdd) IA__FcLangSetAdd __attribute((visibility("hidden"))); #define FcLangSetAdd IA__FcLangSetAdd -extern __typeof (FcLangSetDel) IA__FcLangSetDel FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcLangSetDel) IA__FcLangSetDel __attribute((visibility("hidden"))); #define FcLangSetDel IA__FcLangSetDel -extern __typeof (FcLangSetHasLang) IA__FcLangSetHasLang FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcLangSetHasLang) IA__FcLangSetHasLang __attribute((visibility("hidden"))); #define FcLangSetHasLang IA__FcLangSetHasLang -extern __typeof (FcLangSetCompare) IA__FcLangSetCompare FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcLangSetCompare) IA__FcLangSetCompare __attribute((visibility("hidden"))); #define FcLangSetCompare IA__FcLangSetCompare -extern __typeof (FcLangSetContains) IA__FcLangSetContains FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcLangSetContains) IA__FcLangSetContains __attribute((visibility("hidden"))); #define FcLangSetContains IA__FcLangSetContains -extern __typeof (FcLangSetEqual) IA__FcLangSetEqual FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcLangSetEqual) IA__FcLangSetEqual __attribute((visibility("hidden"))); #define FcLangSetEqual IA__FcLangSetEqual -extern __typeof (FcLangSetHash) IA__FcLangSetHash FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcLangSetHash) IA__FcLangSetHash __attribute((visibility("hidden"))); #define FcLangSetHash IA__FcLangSetHash -extern __typeof (FcLangSetGetLangs) IA__FcLangSetGetLangs FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcLangSetGetLangs) IA__FcLangSetGetLangs __attribute((visibility("hidden"))); #define FcLangSetGetLangs IA__FcLangSetGetLangs -extern __typeof (FcLangSetUnion) IA__FcLangSetUnion FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcLangSetUnion) IA__FcLangSetUnion __attribute((visibility("hidden"))); #define FcLangSetUnion IA__FcLangSetUnion -extern __typeof (FcLangSetSubtract) IA__FcLangSetSubtract FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcLangSetSubtract) IA__FcLangSetSubtract __attribute((visibility("hidden"))); #define FcLangSetSubtract IA__FcLangSetSubtract -extern __typeof (FcObjectSetCreate) IA__FcObjectSetCreate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcObjectSetCreate) IA__FcObjectSetCreate __attribute((visibility("hidden"))); #define FcObjectSetCreate IA__FcObjectSetCreate -extern __typeof (FcObjectSetAdd) IA__FcObjectSetAdd FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcObjectSetAdd) IA__FcObjectSetAdd __attribute((visibility("hidden"))); #define FcObjectSetAdd IA__FcObjectSetAdd -extern __typeof (FcObjectSetDestroy) IA__FcObjectSetDestroy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcObjectSetDestroy) IA__FcObjectSetDestroy __attribute((visibility("hidden"))); #define FcObjectSetDestroy IA__FcObjectSetDestroy -extern __typeof (FcObjectSetVaBuild) IA__FcObjectSetVaBuild FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcObjectSetVaBuild) IA__FcObjectSetVaBuild __attribute((visibility("hidden"))); #define FcObjectSetVaBuild IA__FcObjectSetVaBuild -extern __typeof (FcObjectSetBuild) IA__FcObjectSetBuild FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcObjectSetBuild) IA__FcObjectSetBuild __attribute((visibility("hidden"))); #define FcObjectSetBuild IA__FcObjectSetBuild -extern __typeof (FcFontSetList) IA__FcFontSetList FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcFontSetList) IA__FcFontSetList __attribute((visibility("hidden"))); #define FcFontSetList IA__FcFontSetList -extern __typeof (FcFontList) IA__FcFontList FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcFontList) IA__FcFontList __attribute((visibility("hidden"))); #define FcFontList IA__FcFontList -extern __typeof (FcAtomicCreate) IA__FcAtomicCreate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcAtomicCreate) IA__FcAtomicCreate __attribute((visibility("hidden"))); #define FcAtomicCreate IA__FcAtomicCreate -extern __typeof (FcAtomicLock) IA__FcAtomicLock FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcAtomicLock) IA__FcAtomicLock __attribute((visibility("hidden"))); #define FcAtomicLock IA__FcAtomicLock -extern __typeof (FcAtomicNewFile) IA__FcAtomicNewFile FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcAtomicNewFile) IA__FcAtomicNewFile __attribute((visibility("hidden"))); #define FcAtomicNewFile IA__FcAtomicNewFile -extern __typeof (FcAtomicOrigFile) IA__FcAtomicOrigFile FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcAtomicOrigFile) IA__FcAtomicOrigFile __attribute((visibility("hidden"))); #define FcAtomicOrigFile IA__FcAtomicOrigFile -extern __typeof (FcAtomicReplaceOrig) IA__FcAtomicReplaceOrig FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcAtomicReplaceOrig) IA__FcAtomicReplaceOrig __attribute((visibility("hidden"))); #define FcAtomicReplaceOrig IA__FcAtomicReplaceOrig -extern __typeof (FcAtomicDeleteNew) IA__FcAtomicDeleteNew FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcAtomicDeleteNew) IA__FcAtomicDeleteNew __attribute((visibility("hidden"))); #define FcAtomicDeleteNew IA__FcAtomicDeleteNew -extern __typeof (FcAtomicUnlock) IA__FcAtomicUnlock FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcAtomicUnlock) IA__FcAtomicUnlock __attribute((visibility("hidden"))); #define FcAtomicUnlock IA__FcAtomicUnlock -extern __typeof (FcAtomicDestroy) IA__FcAtomicDestroy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcAtomicDestroy) IA__FcAtomicDestroy __attribute((visibility("hidden"))); #define FcAtomicDestroy IA__FcAtomicDestroy -extern __typeof (FcFontSetMatch) IA__FcFontSetMatch FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcFontSetMatch) IA__FcFontSetMatch __attribute((visibility("hidden"))); #define FcFontSetMatch IA__FcFontSetMatch -extern __typeof (FcFontMatch) IA__FcFontMatch FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcFontMatch) IA__FcFontMatch __attribute((visibility("hidden"))); #define FcFontMatch IA__FcFontMatch -extern __typeof (FcFontRenderPrepare) IA__FcFontRenderPrepare FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcFontRenderPrepare) IA__FcFontRenderPrepare __attribute((visibility("hidden"))); #define FcFontRenderPrepare IA__FcFontRenderPrepare -extern __typeof (FcFontSetSort) IA__FcFontSetSort FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcFontSetSort) IA__FcFontSetSort __attribute((visibility("hidden"))); #define FcFontSetSort IA__FcFontSetSort -extern __typeof (FcFontSort) IA__FcFontSort FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcFontSort) IA__FcFontSort __attribute((visibility("hidden"))); #define FcFontSort IA__FcFontSort -extern __typeof (FcFontSetSortDestroy) IA__FcFontSetSortDestroy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcFontSetSortDestroy) IA__FcFontSetSortDestroy __attribute((visibility("hidden"))); #define FcFontSetSortDestroy IA__FcFontSetSortDestroy -extern __typeof (FcMatrixCopy) IA__FcMatrixCopy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcMatrixCopy) IA__FcMatrixCopy __attribute((visibility("hidden"))); #define FcMatrixCopy IA__FcMatrixCopy -extern __typeof (FcMatrixEqual) IA__FcMatrixEqual FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcMatrixEqual) IA__FcMatrixEqual __attribute((visibility("hidden"))); #define FcMatrixEqual IA__FcMatrixEqual -extern __typeof (FcMatrixMultiply) IA__FcMatrixMultiply FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcMatrixMultiply) IA__FcMatrixMultiply __attribute((visibility("hidden"))); #define FcMatrixMultiply IA__FcMatrixMultiply -extern __typeof (FcMatrixRotate) IA__FcMatrixRotate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcMatrixRotate) IA__FcMatrixRotate __attribute((visibility("hidden"))); #define FcMatrixRotate IA__FcMatrixRotate -extern __typeof (FcMatrixScale) IA__FcMatrixScale FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcMatrixScale) IA__FcMatrixScale __attribute((visibility("hidden"))); #define FcMatrixScale IA__FcMatrixScale -extern __typeof (FcMatrixShear) IA__FcMatrixShear FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcMatrixShear) IA__FcMatrixShear __attribute((visibility("hidden"))); #define FcMatrixShear IA__FcMatrixShear -extern __typeof (FcNameRegisterObjectTypes) IA__FcNameRegisterObjectTypes FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcNameRegisterObjectTypes) IA__FcNameRegisterObjectTypes __attribute((visibility("hidden"))); #define FcNameRegisterObjectTypes IA__FcNameRegisterObjectTypes -extern __typeof (FcNameUnregisterObjectTypes) IA__FcNameUnregisterObjectTypes FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcNameUnregisterObjectTypes) IA__FcNameUnregisterObjectTypes __attribute((visibility("hidden"))); #define FcNameUnregisterObjectTypes IA__FcNameUnregisterObjectTypes -extern __typeof (FcNameGetObjectType) IA__FcNameGetObjectType FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcNameGetObjectType) IA__FcNameGetObjectType __attribute((visibility("hidden"))); #define FcNameGetObjectType IA__FcNameGetObjectType -extern __typeof (FcNameRegisterConstants) IA__FcNameRegisterConstants FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcNameRegisterConstants) IA__FcNameRegisterConstants __attribute((visibility("hidden"))); #define FcNameRegisterConstants IA__FcNameRegisterConstants -extern __typeof (FcNameUnregisterConstants) IA__FcNameUnregisterConstants FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcNameUnregisterConstants) IA__FcNameUnregisterConstants __attribute((visibility("hidden"))); #define FcNameUnregisterConstants IA__FcNameUnregisterConstants -extern __typeof (FcNameGetConstant) IA__FcNameGetConstant FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcNameGetConstant) IA__FcNameGetConstant __attribute((visibility("hidden"))); #define FcNameGetConstant IA__FcNameGetConstant -extern __typeof (FcNameConstant) IA__FcNameConstant FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcNameConstant) IA__FcNameConstant __attribute((visibility("hidden"))); #define FcNameConstant IA__FcNameConstant -extern __typeof (FcNameParse) IA__FcNameParse FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcNameParse) IA__FcNameParse __attribute((visibility("hidden"))); #define FcNameParse IA__FcNameParse -extern __typeof (FcNameUnparse) IA__FcNameUnparse FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcNameUnparse) IA__FcNameUnparse __attribute((visibility("hidden"))); #define FcNameUnparse IA__FcNameUnparse -extern __typeof (FcPatternCreate) IA__FcPatternCreate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternCreate) IA__FcPatternCreate __attribute((visibility("hidden"))); #define FcPatternCreate IA__FcPatternCreate -extern __typeof (FcPatternDuplicate) IA__FcPatternDuplicate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternDuplicate) IA__FcPatternDuplicate __attribute((visibility("hidden"))); #define FcPatternDuplicate IA__FcPatternDuplicate -extern __typeof (FcPatternReference) IA__FcPatternReference FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternReference) IA__FcPatternReference __attribute((visibility("hidden"))); #define FcPatternReference IA__FcPatternReference -extern __typeof (FcPatternFilter) IA__FcPatternFilter FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternFilter) IA__FcPatternFilter __attribute((visibility("hidden"))); #define FcPatternFilter IA__FcPatternFilter -extern __typeof (FcValueDestroy) IA__FcValueDestroy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcValueDestroy) IA__FcValueDestroy __attribute((visibility("hidden"))); #define FcValueDestroy IA__FcValueDestroy -extern __typeof (FcValueEqual) IA__FcValueEqual FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcValueEqual) IA__FcValueEqual __attribute((visibility("hidden"))); #define FcValueEqual IA__FcValueEqual -extern __typeof (FcValueSave) IA__FcValueSave FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcValueSave) IA__FcValueSave __attribute((visibility("hidden"))); #define FcValueSave IA__FcValueSave -extern __typeof (FcPatternDestroy) IA__FcPatternDestroy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternDestroy) IA__FcPatternDestroy __attribute((visibility("hidden"))); #define FcPatternDestroy IA__FcPatternDestroy -extern __typeof (FcPatternObjectCount) IA__FcPatternObjectCount FC_ATTRIBUTE_VISIBILITY_HIDDEN; -#define FcPatternObjectCount IA__FcPatternObjectCount -extern __typeof (FcPatternEqual) IA__FcPatternEqual FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternEqual) IA__FcPatternEqual __attribute((visibility("hidden"))); #define FcPatternEqual IA__FcPatternEqual -extern __typeof (FcPatternEqualSubset) IA__FcPatternEqualSubset FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternEqualSubset) IA__FcPatternEqualSubset __attribute((visibility("hidden"))); #define FcPatternEqualSubset IA__FcPatternEqualSubset -extern __typeof (FcPatternHash) IA__FcPatternHash FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternHash) IA__FcPatternHash __attribute((visibility("hidden"))); #define FcPatternHash IA__FcPatternHash -extern __typeof (FcPatternAdd) IA__FcPatternAdd FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternAdd) IA__FcPatternAdd __attribute((visibility("hidden"))); #define FcPatternAdd IA__FcPatternAdd -extern __typeof (FcPatternAddWeak) IA__FcPatternAddWeak FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternAddWeak) IA__FcPatternAddWeak __attribute((visibility("hidden"))); #define FcPatternAddWeak IA__FcPatternAddWeak -extern __typeof (FcPatternGet) IA__FcPatternGet FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternGet) IA__FcPatternGet __attribute((visibility("hidden"))); #define FcPatternGet IA__FcPatternGet -extern __typeof (FcPatternGetWithBinding) IA__FcPatternGetWithBinding FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternGetWithBinding) IA__FcPatternGetWithBinding __attribute((visibility("hidden"))); #define FcPatternGetWithBinding IA__FcPatternGetWithBinding -extern __typeof (FcPatternDel) IA__FcPatternDel FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternDel) IA__FcPatternDel __attribute((visibility("hidden"))); #define FcPatternDel IA__FcPatternDel -extern __typeof (FcPatternRemove) IA__FcPatternRemove FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternRemove) IA__FcPatternRemove __attribute((visibility("hidden"))); #define FcPatternRemove IA__FcPatternRemove -extern __typeof (FcPatternAddInteger) IA__FcPatternAddInteger FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternAddInteger) IA__FcPatternAddInteger __attribute((visibility("hidden"))); #define FcPatternAddInteger IA__FcPatternAddInteger -extern __typeof (FcPatternAddDouble) IA__FcPatternAddDouble FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternAddDouble) IA__FcPatternAddDouble __attribute((visibility("hidden"))); #define FcPatternAddDouble IA__FcPatternAddDouble -extern __typeof (FcPatternAddString) IA__FcPatternAddString FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternAddString) IA__FcPatternAddString __attribute((visibility("hidden"))); #define FcPatternAddString IA__FcPatternAddString -extern __typeof (FcPatternAddMatrix) IA__FcPatternAddMatrix FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternAddMatrix) IA__FcPatternAddMatrix __attribute((visibility("hidden"))); #define FcPatternAddMatrix IA__FcPatternAddMatrix -extern __typeof (FcPatternAddCharSet) IA__FcPatternAddCharSet FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternAddCharSet) IA__FcPatternAddCharSet __attribute((visibility("hidden"))); #define FcPatternAddCharSet IA__FcPatternAddCharSet -extern __typeof (FcPatternAddBool) IA__FcPatternAddBool FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternAddBool) IA__FcPatternAddBool __attribute((visibility("hidden"))); #define FcPatternAddBool IA__FcPatternAddBool -extern __typeof (FcPatternAddLangSet) IA__FcPatternAddLangSet FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternAddLangSet) IA__FcPatternAddLangSet __attribute((visibility("hidden"))); #define FcPatternAddLangSet IA__FcPatternAddLangSet -extern __typeof (FcPatternAddRange) IA__FcPatternAddRange FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternAddRange) IA__FcPatternAddRange __attribute((visibility("hidden"))); #define FcPatternAddRange IA__FcPatternAddRange -extern __typeof (FcPatternGetInteger) IA__FcPatternGetInteger FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternGetInteger) IA__FcPatternGetInteger __attribute((visibility("hidden"))); #define FcPatternGetInteger IA__FcPatternGetInteger -extern __typeof (FcPatternGetDouble) IA__FcPatternGetDouble FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternGetDouble) IA__FcPatternGetDouble __attribute((visibility("hidden"))); #define FcPatternGetDouble IA__FcPatternGetDouble -extern __typeof (FcPatternGetString) IA__FcPatternGetString FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternGetString) IA__FcPatternGetString __attribute((visibility("hidden"))); #define FcPatternGetString IA__FcPatternGetString -extern __typeof (FcPatternGetMatrix) IA__FcPatternGetMatrix FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternGetMatrix) IA__FcPatternGetMatrix __attribute((visibility("hidden"))); #define FcPatternGetMatrix IA__FcPatternGetMatrix -extern __typeof (FcPatternGetCharSet) IA__FcPatternGetCharSet FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternGetCharSet) IA__FcPatternGetCharSet __attribute((visibility("hidden"))); #define FcPatternGetCharSet IA__FcPatternGetCharSet -extern __typeof (FcPatternGetBool) IA__FcPatternGetBool FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternGetBool) IA__FcPatternGetBool __attribute((visibility("hidden"))); #define FcPatternGetBool IA__FcPatternGetBool -extern __typeof (FcPatternGetLangSet) IA__FcPatternGetLangSet FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternGetLangSet) IA__FcPatternGetLangSet __attribute((visibility("hidden"))); #define FcPatternGetLangSet IA__FcPatternGetLangSet -extern __typeof (FcPatternGetRange) IA__FcPatternGetRange FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternGetRange) IA__FcPatternGetRange __attribute((visibility("hidden"))); #define FcPatternGetRange IA__FcPatternGetRange -extern __typeof (FcPatternVaBuild) IA__FcPatternVaBuild FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternVaBuild) IA__FcPatternVaBuild __attribute((visibility("hidden"))); #define FcPatternVaBuild IA__FcPatternVaBuild -extern __typeof (FcPatternBuild) IA__FcPatternBuild FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternBuild) IA__FcPatternBuild __attribute((visibility("hidden"))); #define FcPatternBuild IA__FcPatternBuild -extern __typeof (FcPatternFormat) IA__FcPatternFormat FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternFormat) IA__FcPatternFormat __attribute((visibility("hidden"))); #define FcPatternFormat IA__FcPatternFormat -extern __typeof (FcRangeCreateDouble) IA__FcRangeCreateDouble FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcRangeCreateDouble) IA__FcRangeCreateDouble __attribute((visibility("hidden"))); #define FcRangeCreateDouble IA__FcRangeCreateDouble -extern __typeof (FcRangeCreateInteger) IA__FcRangeCreateInteger FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcRangeCreateInteger) IA__FcRangeCreateInteger __attribute((visibility("hidden"))); #define FcRangeCreateInteger IA__FcRangeCreateInteger -extern __typeof (FcRangeDestroy) IA__FcRangeDestroy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcRangeDestroy) IA__FcRangeDestroy __attribute((visibility("hidden"))); #define FcRangeDestroy IA__FcRangeDestroy -extern __typeof (FcRangeCopy) IA__FcRangeCopy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcRangeCopy) IA__FcRangeCopy __attribute((visibility("hidden"))); #define FcRangeCopy IA__FcRangeCopy -extern __typeof (FcRangeGetDouble) IA__FcRangeGetDouble FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcRangeGetDouble) IA__FcRangeGetDouble __attribute((visibility("hidden"))); #define FcRangeGetDouble IA__FcRangeGetDouble -extern __typeof (FcPatternIterStart) IA__FcPatternIterStart FC_ATTRIBUTE_VISIBILITY_HIDDEN; -#define FcPatternIterStart IA__FcPatternIterStart -extern __typeof (FcPatternIterNext) IA__FcPatternIterNext FC_ATTRIBUTE_VISIBILITY_HIDDEN; -#define FcPatternIterNext IA__FcPatternIterNext -extern __typeof (FcPatternIterEqual) IA__FcPatternIterEqual FC_ATTRIBUTE_VISIBILITY_HIDDEN; -#define FcPatternIterEqual IA__FcPatternIterEqual -extern __typeof (FcPatternFindIter) IA__FcPatternFindIter FC_ATTRIBUTE_VISIBILITY_HIDDEN; -#define FcPatternFindIter IA__FcPatternFindIter -extern __typeof (FcPatternIterIsValid) IA__FcPatternIterIsValid FC_ATTRIBUTE_VISIBILITY_HIDDEN; -#define FcPatternIterIsValid IA__FcPatternIterIsValid -extern __typeof (FcPatternIterGetObject) IA__FcPatternIterGetObject FC_ATTRIBUTE_VISIBILITY_HIDDEN; -#define FcPatternIterGetObject IA__FcPatternIterGetObject -extern __typeof (FcPatternIterValueCount) IA__FcPatternIterValueCount FC_ATTRIBUTE_VISIBILITY_HIDDEN; -#define FcPatternIterValueCount IA__FcPatternIterValueCount -extern __typeof (FcPatternIterGetValue) IA__FcPatternIterGetValue FC_ATTRIBUTE_VISIBILITY_HIDDEN; -#define FcPatternIterGetValue IA__FcPatternIterGetValue -extern __typeof (FcWeightFromOpenType) IA__FcWeightFromOpenType FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcWeightFromOpenType) IA__FcWeightFromOpenType __attribute((visibility("hidden"))); #define FcWeightFromOpenType IA__FcWeightFromOpenType -extern __typeof (FcWeightFromOpenTypeDouble) IA__FcWeightFromOpenTypeDouble FC_ATTRIBUTE_VISIBILITY_HIDDEN; -#define FcWeightFromOpenTypeDouble IA__FcWeightFromOpenTypeDouble -extern __typeof (FcWeightToOpenType) IA__FcWeightToOpenType FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcWeightToOpenType) IA__FcWeightToOpenType __attribute((visibility("hidden"))); #define FcWeightToOpenType IA__FcWeightToOpenType -extern __typeof (FcWeightToOpenTypeDouble) IA__FcWeightToOpenTypeDouble FC_ATTRIBUTE_VISIBILITY_HIDDEN; -#define FcWeightToOpenTypeDouble IA__FcWeightToOpenTypeDouble -extern __typeof (FcStrCopy) IA__FcStrCopy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcStrCopy) IA__FcStrCopy __attribute((visibility("hidden"))); #define FcStrCopy IA__FcStrCopy -extern __typeof (FcStrCopyFilename) IA__FcStrCopyFilename FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcStrCopyFilename) IA__FcStrCopyFilename __attribute((visibility("hidden"))); #define FcStrCopyFilename IA__FcStrCopyFilename -extern __typeof (FcStrPlus) IA__FcStrPlus FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcStrPlus) IA__FcStrPlus __attribute((visibility("hidden"))); #define FcStrPlus IA__FcStrPlus -extern __typeof (FcStrFree) IA__FcStrFree FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcStrFree) IA__FcStrFree __attribute((visibility("hidden"))); #define FcStrFree IA__FcStrFree -extern __typeof (FcStrDowncase) IA__FcStrDowncase FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcStrDowncase) IA__FcStrDowncase __attribute((visibility("hidden"))); #define FcStrDowncase IA__FcStrDowncase -extern __typeof (FcStrCmpIgnoreCase) IA__FcStrCmpIgnoreCase FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcStrCmpIgnoreCase) IA__FcStrCmpIgnoreCase __attribute((visibility("hidden"))); #define FcStrCmpIgnoreCase IA__FcStrCmpIgnoreCase -extern __typeof (FcStrCmp) IA__FcStrCmp FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcStrCmp) IA__FcStrCmp __attribute((visibility("hidden"))); #define FcStrCmp IA__FcStrCmp -extern __typeof (FcStrStrIgnoreCase) IA__FcStrStrIgnoreCase FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcStrStrIgnoreCase) IA__FcStrStrIgnoreCase __attribute((visibility("hidden"))); #define FcStrStrIgnoreCase IA__FcStrStrIgnoreCase -extern __typeof (FcStrStr) IA__FcStrStr FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcStrStr) IA__FcStrStr __attribute((visibility("hidden"))); #define FcStrStr IA__FcStrStr -extern __typeof (FcUtf8ToUcs4) IA__FcUtf8ToUcs4 FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcUtf8ToUcs4) IA__FcUtf8ToUcs4 __attribute((visibility("hidden"))); #define FcUtf8ToUcs4 IA__FcUtf8ToUcs4 -extern __typeof (FcUtf8Len) IA__FcUtf8Len FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcUtf8Len) IA__FcUtf8Len __attribute((visibility("hidden"))); #define FcUtf8Len IA__FcUtf8Len -extern __typeof (FcUcs4ToUtf8) IA__FcUcs4ToUtf8 FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcUcs4ToUtf8) IA__FcUcs4ToUtf8 __attribute((visibility("hidden"))); #define FcUcs4ToUtf8 IA__FcUcs4ToUtf8 -extern __typeof (FcUtf16ToUcs4) IA__FcUtf16ToUcs4 FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcUtf16ToUcs4) IA__FcUtf16ToUcs4 __attribute((visibility("hidden"))); #define FcUtf16ToUcs4 IA__FcUtf16ToUcs4 -extern __typeof (FcUtf16Len) IA__FcUtf16Len FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcUtf16Len) IA__FcUtf16Len __attribute((visibility("hidden"))); #define FcUtf16Len IA__FcUtf16Len -extern __typeof (FcStrDirname) IA__FcStrDirname FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcStrDirname) IA__FcStrDirname __attribute((visibility("hidden"))); #define FcStrDirname IA__FcStrDirname -extern __typeof (FcStrBasename) IA__FcStrBasename FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcStrBasename) IA__FcStrBasename __attribute((visibility("hidden"))); #define FcStrBasename IA__FcStrBasename -extern __typeof (FcStrSetCreate) IA__FcStrSetCreate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcStrSetCreate) IA__FcStrSetCreate __attribute((visibility("hidden"))); #define FcStrSetCreate IA__FcStrSetCreate -extern __typeof (FcStrSetMember) IA__FcStrSetMember FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcStrSetMember) IA__FcStrSetMember __attribute((visibility("hidden"))); #define FcStrSetMember IA__FcStrSetMember -extern __typeof (FcStrSetEqual) IA__FcStrSetEqual FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcStrSetEqual) IA__FcStrSetEqual __attribute((visibility("hidden"))); #define FcStrSetEqual IA__FcStrSetEqual -extern __typeof (FcStrSetAdd) IA__FcStrSetAdd FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcStrSetAdd) IA__FcStrSetAdd __attribute((visibility("hidden"))); #define FcStrSetAdd IA__FcStrSetAdd -extern __typeof (FcStrSetAddFilename) IA__FcStrSetAddFilename FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcStrSetAddFilename) IA__FcStrSetAddFilename __attribute((visibility("hidden"))); #define FcStrSetAddFilename IA__FcStrSetAddFilename -extern __typeof (FcStrSetDel) IA__FcStrSetDel FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcStrSetDel) IA__FcStrSetDel __attribute((visibility("hidden"))); #define FcStrSetDel IA__FcStrSetDel -extern __typeof (FcStrSetDestroy) IA__FcStrSetDestroy FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcStrSetDestroy) IA__FcStrSetDestroy __attribute((visibility("hidden"))); #define FcStrSetDestroy IA__FcStrSetDestroy -extern __typeof (FcStrListCreate) IA__FcStrListCreate FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcStrListCreate) IA__FcStrListCreate __attribute((visibility("hidden"))); #define FcStrListCreate IA__FcStrListCreate -extern __typeof (FcStrListFirst) IA__FcStrListFirst FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcStrListFirst) IA__FcStrListFirst __attribute((visibility("hidden"))); #define FcStrListFirst IA__FcStrListFirst -extern __typeof (FcStrListNext) IA__FcStrListNext FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcStrListNext) IA__FcStrListNext __attribute((visibility("hidden"))); #define FcStrListNext IA__FcStrListNext -extern __typeof (FcStrListDone) IA__FcStrListDone FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcStrListDone) IA__FcStrListDone __attribute((visibility("hidden"))); #define FcStrListDone IA__FcStrListDone -extern __typeof (FcConfigParseAndLoad) IA__FcConfigParseAndLoad FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigParseAndLoad) IA__FcConfigParseAndLoad __attribute((visibility("hidden"))); #define FcConfigParseAndLoad IA__FcConfigParseAndLoad -extern __typeof (FcConfigParseAndLoadFromMemory) IA__FcConfigParseAndLoadFromMemory FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigParseAndLoadFromMemory) IA__FcConfigParseAndLoadFromMemory __attribute((visibility("hidden"))); #define FcConfigParseAndLoadFromMemory IA__FcConfigParseAndLoadFromMemory -extern __typeof (FcConfigGetRescanInverval) IA__FcConfigGetRescanInverval FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigGetRescanInverval) IA__FcConfigGetRescanInverval __attribute((visibility("hidden"))); #define FcConfigGetRescanInverval IA__FcConfigGetRescanInverval -extern __typeof (FcConfigSetRescanInverval) IA__FcConfigSetRescanInverval FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcConfigSetRescanInverval) IA__FcConfigSetRescanInverval __attribute((visibility("hidden"))); #define FcConfigSetRescanInverval IA__FcConfigSetRescanInverval
diff --git a/third_party/fontconfig/include/src/fcaliastail.h b/third_party/fontconfig/include/src/fcaliastail.h index 80b3ac6..a46c8d0 100644 --- a/third_party/fontconfig/include/src/fcaliastail.h +++ b/third_party/fontconfig/include/src/fcaliastail.h
@@ -1,504 +1,468 @@ #if HAVE_GNUC_ATTRIBUTE -#ifdef __fccfg__ +#ifdef __fcblanks__ # undef FcBlanksCreate -extern __typeof (FcBlanksCreate) FcBlanksCreate __attribute((alias("IA__FcBlanksCreate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcBlanksCreate) FcBlanksCreate __attribute((alias("IA__FcBlanksCreate"), visibility("default"))); # undef FcBlanksDestroy -extern __typeof (FcBlanksDestroy) FcBlanksDestroy __attribute((alias("IA__FcBlanksDestroy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcBlanksDestroy) FcBlanksDestroy __attribute((alias("IA__FcBlanksDestroy"), visibility("default"))); # undef FcBlanksAdd -extern __typeof (FcBlanksAdd) FcBlanksAdd __attribute((alias("IA__FcBlanksAdd"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcBlanksAdd) FcBlanksAdd __attribute((alias("IA__FcBlanksAdd"), visibility("default"))); # undef FcBlanksIsMember -extern __typeof (FcBlanksIsMember) FcBlanksIsMember __attribute((alias("IA__FcBlanksIsMember"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; -#endif /* __fccfg__ */ +extern __typeof (FcBlanksIsMember) FcBlanksIsMember __attribute((alias("IA__FcBlanksIsMember"), visibility("default"))); +#endif /* __fcblanks__ */ #ifdef __fccache__ # undef FcCacheCopySet -extern __typeof (FcCacheCopySet) FcCacheCopySet __attribute((alias("IA__FcCacheCopySet"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcCacheCopySet) FcCacheCopySet __attribute((alias("IA__FcCacheCopySet"), visibility("default"))); # undef FcCacheNumSubdir -extern __typeof (FcCacheNumSubdir) FcCacheNumSubdir __attribute((alias("IA__FcCacheNumSubdir"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcCacheNumSubdir) FcCacheNumSubdir __attribute((alias("IA__FcCacheNumSubdir"), visibility("default"))); # undef FcCacheNumFont -extern __typeof (FcCacheNumFont) FcCacheNumFont __attribute((alias("IA__FcCacheNumFont"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcCacheNumFont) FcCacheNumFont __attribute((alias("IA__FcCacheNumFont"), visibility("default"))); # undef FcDirCacheUnlink -extern __typeof (FcDirCacheUnlink) FcDirCacheUnlink __attribute((alias("IA__FcDirCacheUnlink"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcDirCacheUnlink) FcDirCacheUnlink __attribute((alias("IA__FcDirCacheUnlink"), visibility("default"))); # undef FcDirCacheValid -extern __typeof (FcDirCacheValid) FcDirCacheValid __attribute((alias("IA__FcDirCacheValid"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcDirCacheValid) FcDirCacheValid __attribute((alias("IA__FcDirCacheValid"), visibility("default"))); # undef FcDirCacheClean -extern __typeof (FcDirCacheClean) FcDirCacheClean __attribute((alias("IA__FcDirCacheClean"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcDirCacheClean) FcDirCacheClean __attribute((alias("IA__FcDirCacheClean"), visibility("default"))); # undef FcCacheCreateTagFile -extern __typeof (FcCacheCreateTagFile) FcCacheCreateTagFile __attribute((alias("IA__FcCacheCreateTagFile"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; -# undef FcDirCacheCreateUUID -extern __typeof (FcDirCacheCreateUUID) FcDirCacheCreateUUID __attribute((alias("IA__FcDirCacheCreateUUID"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; -# undef FcDirCacheDeleteUUID -extern __typeof (FcDirCacheDeleteUUID) FcDirCacheDeleteUUID __attribute((alias("IA__FcDirCacheDeleteUUID"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcCacheCreateTagFile) FcCacheCreateTagFile __attribute((alias("IA__FcCacheCreateTagFile"), visibility("default"))); #endif /* __fccache__ */ #ifdef __fccfg__ # undef FcConfigHome -extern __typeof (FcConfigHome) FcConfigHome __attribute((alias("IA__FcConfigHome"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigHome) FcConfigHome __attribute((alias("IA__FcConfigHome"), visibility("default"))); # undef FcConfigEnableHome -extern __typeof (FcConfigEnableHome) FcConfigEnableHome __attribute((alias("IA__FcConfigEnableHome"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigEnableHome) FcConfigEnableHome __attribute((alias("IA__FcConfigEnableHome"), visibility("default"))); # undef FcConfigFilename -extern __typeof (FcConfigFilename) FcConfigFilename __attribute((alias("IA__FcConfigFilename"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigFilename) FcConfigFilename __attribute((alias("IA__FcConfigFilename"), visibility("default"))); # undef FcConfigCreate -extern __typeof (FcConfigCreate) FcConfigCreate __attribute((alias("IA__FcConfigCreate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigCreate) FcConfigCreate __attribute((alias("IA__FcConfigCreate"), visibility("default"))); # undef FcConfigReference -extern __typeof (FcConfigReference) FcConfigReference __attribute((alias("IA__FcConfigReference"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigReference) FcConfigReference __attribute((alias("IA__FcConfigReference"), visibility("default"))); # undef FcConfigDestroy -extern __typeof (FcConfigDestroy) FcConfigDestroy __attribute((alias("IA__FcConfigDestroy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigDestroy) FcConfigDestroy __attribute((alias("IA__FcConfigDestroy"), visibility("default"))); # undef FcConfigSetCurrent -extern __typeof (FcConfigSetCurrent) FcConfigSetCurrent __attribute((alias("IA__FcConfigSetCurrent"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigSetCurrent) FcConfigSetCurrent __attribute((alias("IA__FcConfigSetCurrent"), visibility("default"))); # undef FcConfigGetCurrent -extern __typeof (FcConfigGetCurrent) FcConfigGetCurrent __attribute((alias("IA__FcConfigGetCurrent"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigGetCurrent) FcConfigGetCurrent __attribute((alias("IA__FcConfigGetCurrent"), visibility("default"))); # undef FcConfigUptoDate -extern __typeof (FcConfigUptoDate) FcConfigUptoDate __attribute((alias("IA__FcConfigUptoDate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigUptoDate) FcConfigUptoDate __attribute((alias("IA__FcConfigUptoDate"), visibility("default"))); # undef FcConfigBuildFonts -extern __typeof (FcConfigBuildFonts) FcConfigBuildFonts __attribute((alias("IA__FcConfigBuildFonts"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigBuildFonts) FcConfigBuildFonts __attribute((alias("IA__FcConfigBuildFonts"), visibility("default"))); # undef FcConfigGetFontDirs -extern __typeof (FcConfigGetFontDirs) FcConfigGetFontDirs __attribute((alias("IA__FcConfigGetFontDirs"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigGetFontDirs) FcConfigGetFontDirs __attribute((alias("IA__FcConfigGetFontDirs"), visibility("default"))); # undef FcConfigGetConfigDirs -extern __typeof (FcConfigGetConfigDirs) FcConfigGetConfigDirs __attribute((alias("IA__FcConfigGetConfigDirs"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigGetConfigDirs) FcConfigGetConfigDirs __attribute((alias("IA__FcConfigGetConfigDirs"), visibility("default"))); # undef FcConfigGetConfigFiles -extern __typeof (FcConfigGetConfigFiles) FcConfigGetConfigFiles __attribute((alias("IA__FcConfigGetConfigFiles"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigGetConfigFiles) FcConfigGetConfigFiles __attribute((alias("IA__FcConfigGetConfigFiles"), visibility("default"))); # undef FcConfigGetCache -extern __typeof (FcConfigGetCache) FcConfigGetCache __attribute((alias("IA__FcConfigGetCache"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigGetCache) FcConfigGetCache __attribute((alias("IA__FcConfigGetCache"), visibility("default"))); # undef FcConfigGetBlanks -extern __typeof (FcConfigGetBlanks) FcConfigGetBlanks __attribute((alias("IA__FcConfigGetBlanks"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigGetBlanks) FcConfigGetBlanks __attribute((alias("IA__FcConfigGetBlanks"), visibility("default"))); # undef FcConfigGetCacheDirs -extern __typeof (FcConfigGetCacheDirs) FcConfigGetCacheDirs __attribute((alias("IA__FcConfigGetCacheDirs"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigGetCacheDirs) FcConfigGetCacheDirs __attribute((alias("IA__FcConfigGetCacheDirs"), visibility("default"))); # undef FcConfigGetRescanInterval -extern __typeof (FcConfigGetRescanInterval) FcConfigGetRescanInterval __attribute((alias("IA__FcConfigGetRescanInterval"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigGetRescanInterval) FcConfigGetRescanInterval __attribute((alias("IA__FcConfigGetRescanInterval"), visibility("default"))); # undef FcConfigSetRescanInterval -extern __typeof (FcConfigSetRescanInterval) FcConfigSetRescanInterval __attribute((alias("IA__FcConfigSetRescanInterval"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigSetRescanInterval) FcConfigSetRescanInterval __attribute((alias("IA__FcConfigSetRescanInterval"), visibility("default"))); # undef FcConfigGetFonts -extern __typeof (FcConfigGetFonts) FcConfigGetFonts __attribute((alias("IA__FcConfigGetFonts"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigGetFonts) FcConfigGetFonts __attribute((alias("IA__FcConfigGetFonts"), visibility("default"))); # undef FcConfigAppFontAddFile -extern __typeof (FcConfigAppFontAddFile) FcConfigAppFontAddFile __attribute((alias("IA__FcConfigAppFontAddFile"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigAppFontAddFile) FcConfigAppFontAddFile __attribute((alias("IA__FcConfigAppFontAddFile"), visibility("default"))); # undef FcConfigAppFontAddDir -extern __typeof (FcConfigAppFontAddDir) FcConfigAppFontAddDir __attribute((alias("IA__FcConfigAppFontAddDir"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigAppFontAddDir) FcConfigAppFontAddDir __attribute((alias("IA__FcConfigAppFontAddDir"), visibility("default"))); # undef FcConfigAppFontClear -extern __typeof (FcConfigAppFontClear) FcConfigAppFontClear __attribute((alias("IA__FcConfigAppFontClear"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigAppFontClear) FcConfigAppFontClear __attribute((alias("IA__FcConfigAppFontClear"), visibility("default"))); # undef FcConfigSubstituteWithPat -extern __typeof (FcConfigSubstituteWithPat) FcConfigSubstituteWithPat __attribute((alias("IA__FcConfigSubstituteWithPat"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigSubstituteWithPat) FcConfigSubstituteWithPat __attribute((alias("IA__FcConfigSubstituteWithPat"), visibility("default"))); # undef FcConfigSubstitute -extern __typeof (FcConfigSubstitute) FcConfigSubstitute __attribute((alias("IA__FcConfigSubstitute"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigSubstitute) FcConfigSubstitute __attribute((alias("IA__FcConfigSubstitute"), visibility("default"))); # undef FcConfigGetSysRoot -extern __typeof (FcConfigGetSysRoot) FcConfigGetSysRoot __attribute((alias("IA__FcConfigGetSysRoot"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigGetSysRoot) FcConfigGetSysRoot __attribute((alias("IA__FcConfigGetSysRoot"), visibility("default"))); # undef FcConfigSetSysRoot -extern __typeof (FcConfigSetSysRoot) FcConfigSetSysRoot __attribute((alias("IA__FcConfigSetSysRoot"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; -# undef FcConfigFileInfoIterInit -extern __typeof (FcConfigFileInfoIterInit) FcConfigFileInfoIterInit __attribute((alias("IA__FcConfigFileInfoIterInit"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; -# undef FcConfigFileInfoIterNext -extern __typeof (FcConfigFileInfoIterNext) FcConfigFileInfoIterNext __attribute((alias("IA__FcConfigFileInfoIterNext"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; -# undef FcConfigFileInfoIterGet -extern __typeof (FcConfigFileInfoIterGet) FcConfigFileInfoIterGet __attribute((alias("IA__FcConfigFileInfoIterGet"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigSetSysRoot) FcConfigSetSysRoot __attribute((alias("IA__FcConfigSetSysRoot"), visibility("default"))); #endif /* __fccfg__ */ #ifdef __fccharset__ # undef FcCharSetCreate -extern __typeof (FcCharSetCreate) FcCharSetCreate __attribute((alias("IA__FcCharSetCreate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcCharSetCreate) FcCharSetCreate __attribute((alias("IA__FcCharSetCreate"), visibility("default"))); # undef FcCharSetNew -extern __typeof (FcCharSetNew) FcCharSetNew __attribute((alias("IA__FcCharSetNew"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcCharSetNew) FcCharSetNew __attribute((alias("IA__FcCharSetNew"), visibility("default"))); # undef FcCharSetDestroy -extern __typeof (FcCharSetDestroy) FcCharSetDestroy __attribute((alias("IA__FcCharSetDestroy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcCharSetDestroy) FcCharSetDestroy __attribute((alias("IA__FcCharSetDestroy"), visibility("default"))); # undef FcCharSetAddChar -extern __typeof (FcCharSetAddChar) FcCharSetAddChar __attribute((alias("IA__FcCharSetAddChar"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcCharSetAddChar) FcCharSetAddChar __attribute((alias("IA__FcCharSetAddChar"), visibility("default"))); # undef FcCharSetDelChar -extern __typeof (FcCharSetDelChar) FcCharSetDelChar __attribute((alias("IA__FcCharSetDelChar"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcCharSetDelChar) FcCharSetDelChar __attribute((alias("IA__FcCharSetDelChar"), visibility("default"))); # undef FcCharSetCopy -extern __typeof (FcCharSetCopy) FcCharSetCopy __attribute((alias("IA__FcCharSetCopy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcCharSetCopy) FcCharSetCopy __attribute((alias("IA__FcCharSetCopy"), visibility("default"))); # undef FcCharSetEqual -extern __typeof (FcCharSetEqual) FcCharSetEqual __attribute((alias("IA__FcCharSetEqual"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcCharSetEqual) FcCharSetEqual __attribute((alias("IA__FcCharSetEqual"), visibility("default"))); # undef FcCharSetIntersect -extern __typeof (FcCharSetIntersect) FcCharSetIntersect __attribute((alias("IA__FcCharSetIntersect"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcCharSetIntersect) FcCharSetIntersect __attribute((alias("IA__FcCharSetIntersect"), visibility("default"))); # undef FcCharSetUnion -extern __typeof (FcCharSetUnion) FcCharSetUnion __attribute((alias("IA__FcCharSetUnion"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcCharSetUnion) FcCharSetUnion __attribute((alias("IA__FcCharSetUnion"), visibility("default"))); # undef FcCharSetSubtract -extern __typeof (FcCharSetSubtract) FcCharSetSubtract __attribute((alias("IA__FcCharSetSubtract"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcCharSetSubtract) FcCharSetSubtract __attribute((alias("IA__FcCharSetSubtract"), visibility("default"))); # undef FcCharSetMerge -extern __typeof (FcCharSetMerge) FcCharSetMerge __attribute((alias("IA__FcCharSetMerge"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcCharSetMerge) FcCharSetMerge __attribute((alias("IA__FcCharSetMerge"), visibility("default"))); # undef FcCharSetHasChar -extern __typeof (FcCharSetHasChar) FcCharSetHasChar __attribute((alias("IA__FcCharSetHasChar"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcCharSetHasChar) FcCharSetHasChar __attribute((alias("IA__FcCharSetHasChar"), visibility("default"))); # undef FcCharSetCount -extern __typeof (FcCharSetCount) FcCharSetCount __attribute((alias("IA__FcCharSetCount"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcCharSetCount) FcCharSetCount __attribute((alias("IA__FcCharSetCount"), visibility("default"))); # undef FcCharSetIntersectCount -extern __typeof (FcCharSetIntersectCount) FcCharSetIntersectCount __attribute((alias("IA__FcCharSetIntersectCount"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcCharSetIntersectCount) FcCharSetIntersectCount __attribute((alias("IA__FcCharSetIntersectCount"), visibility("default"))); # undef FcCharSetSubtractCount -extern __typeof (FcCharSetSubtractCount) FcCharSetSubtractCount __attribute((alias("IA__FcCharSetSubtractCount"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcCharSetSubtractCount) FcCharSetSubtractCount __attribute((alias("IA__FcCharSetSubtractCount"), visibility("default"))); # undef FcCharSetIsSubset -extern __typeof (FcCharSetIsSubset) FcCharSetIsSubset __attribute((alias("IA__FcCharSetIsSubset"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcCharSetIsSubset) FcCharSetIsSubset __attribute((alias("IA__FcCharSetIsSubset"), visibility("default"))); # undef FcCharSetFirstPage -extern __typeof (FcCharSetFirstPage) FcCharSetFirstPage __attribute((alias("IA__FcCharSetFirstPage"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcCharSetFirstPage) FcCharSetFirstPage __attribute((alias("IA__FcCharSetFirstPage"), visibility("default"))); # undef FcCharSetNextPage -extern __typeof (FcCharSetNextPage) FcCharSetNextPage __attribute((alias("IA__FcCharSetNextPage"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcCharSetNextPage) FcCharSetNextPage __attribute((alias("IA__FcCharSetNextPage"), visibility("default"))); # undef FcCharSetCoverage -extern __typeof (FcCharSetCoverage) FcCharSetCoverage __attribute((alias("IA__FcCharSetCoverage"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcCharSetCoverage) FcCharSetCoverage __attribute((alias("IA__FcCharSetCoverage"), visibility("default"))); #endif /* __fccharset__ */ #ifdef __fcdbg__ # undef FcValuePrint -extern __typeof (FcValuePrint) FcValuePrint __attribute((alias("IA__FcValuePrint"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcValuePrint) FcValuePrint __attribute((alias("IA__FcValuePrint"), visibility("default"))); # undef FcPatternPrint -extern __typeof (FcPatternPrint) FcPatternPrint __attribute((alias("IA__FcPatternPrint"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternPrint) FcPatternPrint __attribute((alias("IA__FcPatternPrint"), visibility("default"))); # undef FcFontSetPrint -extern __typeof (FcFontSetPrint) FcFontSetPrint __attribute((alias("IA__FcFontSetPrint"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcFontSetPrint) FcFontSetPrint __attribute((alias("IA__FcFontSetPrint"), visibility("default"))); #endif /* __fcdbg__ */ #ifdef __fcdefault__ # undef FcGetDefaultLangs -extern __typeof (FcGetDefaultLangs) FcGetDefaultLangs __attribute((alias("IA__FcGetDefaultLangs"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcGetDefaultLangs) FcGetDefaultLangs __attribute((alias("IA__FcGetDefaultLangs"), visibility("default"))); # undef FcDefaultSubstitute -extern __typeof (FcDefaultSubstitute) FcDefaultSubstitute __attribute((alias("IA__FcDefaultSubstitute"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcDefaultSubstitute) FcDefaultSubstitute __attribute((alias("IA__FcDefaultSubstitute"), visibility("default"))); #endif /* __fcdefault__ */ #ifdef __fcdir__ # undef FcFileIsDir -extern __typeof (FcFileIsDir) FcFileIsDir __attribute((alias("IA__FcFileIsDir"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcFileIsDir) FcFileIsDir __attribute((alias("IA__FcFileIsDir"), visibility("default"))); # undef FcFileScan -extern __typeof (FcFileScan) FcFileScan __attribute((alias("IA__FcFileScan"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcFileScan) FcFileScan __attribute((alias("IA__FcFileScan"), visibility("default"))); # undef FcDirScan -extern __typeof (FcDirScan) FcDirScan __attribute((alias("IA__FcDirScan"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcDirScan) FcDirScan __attribute((alias("IA__FcDirScan"), visibility("default"))); # undef FcDirSave -extern __typeof (FcDirSave) FcDirSave __attribute((alias("IA__FcDirSave"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcDirSave) FcDirSave __attribute((alias("IA__FcDirSave"), visibility("default"))); #endif /* __fcdir__ */ #ifdef __fccache__ # undef FcDirCacheLoad -extern __typeof (FcDirCacheLoad) FcDirCacheLoad __attribute((alias("IA__FcDirCacheLoad"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcDirCacheLoad) FcDirCacheLoad __attribute((alias("IA__FcDirCacheLoad"), visibility("default"))); #endif /* __fccache__ */ #ifdef __fcdir__ # undef FcDirCacheRescan -extern __typeof (FcDirCacheRescan) FcDirCacheRescan __attribute((alias("IA__FcDirCacheRescan"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcDirCacheRescan) FcDirCacheRescan __attribute((alias("IA__FcDirCacheRescan"), visibility("default"))); # undef FcDirCacheRead -extern __typeof (FcDirCacheRead) FcDirCacheRead __attribute((alias("IA__FcDirCacheRead"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcDirCacheRead) FcDirCacheRead __attribute((alias("IA__FcDirCacheRead"), visibility("default"))); #endif /* __fcdir__ */ #ifdef __fccache__ # undef FcDirCacheLoadFile -extern __typeof (FcDirCacheLoadFile) FcDirCacheLoadFile __attribute((alias("IA__FcDirCacheLoadFile"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcDirCacheLoadFile) FcDirCacheLoadFile __attribute((alias("IA__FcDirCacheLoadFile"), visibility("default"))); # undef FcDirCacheUnload -extern __typeof (FcDirCacheUnload) FcDirCacheUnload __attribute((alias("IA__FcDirCacheUnload"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcDirCacheUnload) FcDirCacheUnload __attribute((alias("IA__FcDirCacheUnload"), visibility("default"))); #endif /* __fccache__ */ #ifdef __fcfreetype__ # undef FcFreeTypeQuery -extern __typeof (FcFreeTypeQuery) FcFreeTypeQuery __attribute((alias("IA__FcFreeTypeQuery"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; -# undef FcFreeTypeQueryAll -extern __typeof (FcFreeTypeQueryAll) FcFreeTypeQueryAll __attribute((alias("IA__FcFreeTypeQueryAll"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcFreeTypeQuery) FcFreeTypeQuery __attribute((alias("IA__FcFreeTypeQuery"), visibility("default"))); #endif /* __fcfreetype__ */ #ifdef __fcfs__ # undef FcFontSetCreate -extern __typeof (FcFontSetCreate) FcFontSetCreate __attribute((alias("IA__FcFontSetCreate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcFontSetCreate) FcFontSetCreate __attribute((alias("IA__FcFontSetCreate"), visibility("default"))); # undef FcFontSetDestroy -extern __typeof (FcFontSetDestroy) FcFontSetDestroy __attribute((alias("IA__FcFontSetDestroy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcFontSetDestroy) FcFontSetDestroy __attribute((alias("IA__FcFontSetDestroy"), visibility("default"))); # undef FcFontSetAdd -extern __typeof (FcFontSetAdd) FcFontSetAdd __attribute((alias("IA__FcFontSetAdd"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcFontSetAdd) FcFontSetAdd __attribute((alias("IA__FcFontSetAdd"), visibility("default"))); #endif /* __fcfs__ */ #ifdef __fcinit__ # undef FcInitLoadConfig -extern __typeof (FcInitLoadConfig) FcInitLoadConfig __attribute((alias("IA__FcInitLoadConfig"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcInitLoadConfig) FcInitLoadConfig __attribute((alias("IA__FcInitLoadConfig"), visibility("default"))); # undef FcInitLoadConfigAndFonts -extern __typeof (FcInitLoadConfigAndFonts) FcInitLoadConfigAndFonts __attribute((alias("IA__FcInitLoadConfigAndFonts"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcInitLoadConfigAndFonts) FcInitLoadConfigAndFonts __attribute((alias("IA__FcInitLoadConfigAndFonts"), visibility("default"))); # undef FcInit -extern __typeof (FcInit) FcInit __attribute((alias("IA__FcInit"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcInit) FcInit __attribute((alias("IA__FcInit"), visibility("default"))); # undef FcFini -extern __typeof (FcFini) FcFini __attribute((alias("IA__FcFini"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcFini) FcFini __attribute((alias("IA__FcFini"), visibility("default"))); # undef FcGetVersion -extern __typeof (FcGetVersion) FcGetVersion __attribute((alias("IA__FcGetVersion"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcGetVersion) FcGetVersion __attribute((alias("IA__FcGetVersion"), visibility("default"))); # undef FcInitReinitialize -extern __typeof (FcInitReinitialize) FcInitReinitialize __attribute((alias("IA__FcInitReinitialize"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcInitReinitialize) FcInitReinitialize __attribute((alias("IA__FcInitReinitialize"), visibility("default"))); # undef FcInitBringUptoDate -extern __typeof (FcInitBringUptoDate) FcInitBringUptoDate __attribute((alias("IA__FcInitBringUptoDate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcInitBringUptoDate) FcInitBringUptoDate __attribute((alias("IA__FcInitBringUptoDate"), visibility("default"))); #endif /* __fcinit__ */ #ifdef __fclang__ # undef FcGetLangs -extern __typeof (FcGetLangs) FcGetLangs __attribute((alias("IA__FcGetLangs"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcGetLangs) FcGetLangs __attribute((alias("IA__FcGetLangs"), visibility("default"))); # undef FcLangNormalize -extern __typeof (FcLangNormalize) FcLangNormalize __attribute((alias("IA__FcLangNormalize"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcLangNormalize) FcLangNormalize __attribute((alias("IA__FcLangNormalize"), visibility("default"))); # undef FcLangGetCharSet -extern __typeof (FcLangGetCharSet) FcLangGetCharSet __attribute((alias("IA__FcLangGetCharSet"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcLangGetCharSet) FcLangGetCharSet __attribute((alias("IA__FcLangGetCharSet"), visibility("default"))); # undef FcLangSetCreate -extern __typeof (FcLangSetCreate) FcLangSetCreate __attribute((alias("IA__FcLangSetCreate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcLangSetCreate) FcLangSetCreate __attribute((alias("IA__FcLangSetCreate"), visibility("default"))); # undef FcLangSetDestroy -extern __typeof (FcLangSetDestroy) FcLangSetDestroy __attribute((alias("IA__FcLangSetDestroy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcLangSetDestroy) FcLangSetDestroy __attribute((alias("IA__FcLangSetDestroy"), visibility("default"))); # undef FcLangSetCopy -extern __typeof (FcLangSetCopy) FcLangSetCopy __attribute((alias("IA__FcLangSetCopy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcLangSetCopy) FcLangSetCopy __attribute((alias("IA__FcLangSetCopy"), visibility("default"))); # undef FcLangSetAdd -extern __typeof (FcLangSetAdd) FcLangSetAdd __attribute((alias("IA__FcLangSetAdd"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcLangSetAdd) FcLangSetAdd __attribute((alias("IA__FcLangSetAdd"), visibility("default"))); # undef FcLangSetDel -extern __typeof (FcLangSetDel) FcLangSetDel __attribute((alias("IA__FcLangSetDel"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcLangSetDel) FcLangSetDel __attribute((alias("IA__FcLangSetDel"), visibility("default"))); # undef FcLangSetHasLang -extern __typeof (FcLangSetHasLang) FcLangSetHasLang __attribute((alias("IA__FcLangSetHasLang"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcLangSetHasLang) FcLangSetHasLang __attribute((alias("IA__FcLangSetHasLang"), visibility("default"))); # undef FcLangSetCompare -extern __typeof (FcLangSetCompare) FcLangSetCompare __attribute((alias("IA__FcLangSetCompare"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcLangSetCompare) FcLangSetCompare __attribute((alias("IA__FcLangSetCompare"), visibility("default"))); # undef FcLangSetContains -extern __typeof (FcLangSetContains) FcLangSetContains __attribute((alias("IA__FcLangSetContains"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcLangSetContains) FcLangSetContains __attribute((alias("IA__FcLangSetContains"), visibility("default"))); # undef FcLangSetEqual -extern __typeof (FcLangSetEqual) FcLangSetEqual __attribute((alias("IA__FcLangSetEqual"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcLangSetEqual) FcLangSetEqual __attribute((alias("IA__FcLangSetEqual"), visibility("default"))); # undef FcLangSetHash -extern __typeof (FcLangSetHash) FcLangSetHash __attribute((alias("IA__FcLangSetHash"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcLangSetHash) FcLangSetHash __attribute((alias("IA__FcLangSetHash"), visibility("default"))); # undef FcLangSetGetLangs -extern __typeof (FcLangSetGetLangs) FcLangSetGetLangs __attribute((alias("IA__FcLangSetGetLangs"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcLangSetGetLangs) FcLangSetGetLangs __attribute((alias("IA__FcLangSetGetLangs"), visibility("default"))); # undef FcLangSetUnion -extern __typeof (FcLangSetUnion) FcLangSetUnion __attribute((alias("IA__FcLangSetUnion"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcLangSetUnion) FcLangSetUnion __attribute((alias("IA__FcLangSetUnion"), visibility("default"))); # undef FcLangSetSubtract -extern __typeof (FcLangSetSubtract) FcLangSetSubtract __attribute((alias("IA__FcLangSetSubtract"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcLangSetSubtract) FcLangSetSubtract __attribute((alias("IA__FcLangSetSubtract"), visibility("default"))); #endif /* __fclang__ */ #ifdef __fclist__ # undef FcObjectSetCreate -extern __typeof (FcObjectSetCreate) FcObjectSetCreate __attribute((alias("IA__FcObjectSetCreate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcObjectSetCreate) FcObjectSetCreate __attribute((alias("IA__FcObjectSetCreate"), visibility("default"))); # undef FcObjectSetAdd -extern __typeof (FcObjectSetAdd) FcObjectSetAdd __attribute((alias("IA__FcObjectSetAdd"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcObjectSetAdd) FcObjectSetAdd __attribute((alias("IA__FcObjectSetAdd"), visibility("default"))); # undef FcObjectSetDestroy -extern __typeof (FcObjectSetDestroy) FcObjectSetDestroy __attribute((alias("IA__FcObjectSetDestroy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcObjectSetDestroy) FcObjectSetDestroy __attribute((alias("IA__FcObjectSetDestroy"), visibility("default"))); # undef FcObjectSetVaBuild -extern __typeof (FcObjectSetVaBuild) FcObjectSetVaBuild __attribute((alias("IA__FcObjectSetVaBuild"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcObjectSetVaBuild) FcObjectSetVaBuild __attribute((alias("IA__FcObjectSetVaBuild"), visibility("default"))); # undef FcObjectSetBuild -extern __typeof (FcObjectSetBuild) FcObjectSetBuild __attribute((alias("IA__FcObjectSetBuild"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcObjectSetBuild) FcObjectSetBuild __attribute((alias("IA__FcObjectSetBuild"), visibility("default"))); # undef FcFontSetList -extern __typeof (FcFontSetList) FcFontSetList __attribute((alias("IA__FcFontSetList"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcFontSetList) FcFontSetList __attribute((alias("IA__FcFontSetList"), visibility("default"))); # undef FcFontList -extern __typeof (FcFontList) FcFontList __attribute((alias("IA__FcFontList"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcFontList) FcFontList __attribute((alias("IA__FcFontList"), visibility("default"))); #endif /* __fclist__ */ #ifdef __fcatomic__ # undef FcAtomicCreate -extern __typeof (FcAtomicCreate) FcAtomicCreate __attribute((alias("IA__FcAtomicCreate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcAtomicCreate) FcAtomicCreate __attribute((alias("IA__FcAtomicCreate"), visibility("default"))); # undef FcAtomicLock -extern __typeof (FcAtomicLock) FcAtomicLock __attribute((alias("IA__FcAtomicLock"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcAtomicLock) FcAtomicLock __attribute((alias("IA__FcAtomicLock"), visibility("default"))); # undef FcAtomicNewFile -extern __typeof (FcAtomicNewFile) FcAtomicNewFile __attribute((alias("IA__FcAtomicNewFile"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcAtomicNewFile) FcAtomicNewFile __attribute((alias("IA__FcAtomicNewFile"), visibility("default"))); # undef FcAtomicOrigFile -extern __typeof (FcAtomicOrigFile) FcAtomicOrigFile __attribute((alias("IA__FcAtomicOrigFile"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcAtomicOrigFile) FcAtomicOrigFile __attribute((alias("IA__FcAtomicOrigFile"), visibility("default"))); # undef FcAtomicReplaceOrig -extern __typeof (FcAtomicReplaceOrig) FcAtomicReplaceOrig __attribute((alias("IA__FcAtomicReplaceOrig"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcAtomicReplaceOrig) FcAtomicReplaceOrig __attribute((alias("IA__FcAtomicReplaceOrig"), visibility("default"))); # undef FcAtomicDeleteNew -extern __typeof (FcAtomicDeleteNew) FcAtomicDeleteNew __attribute((alias("IA__FcAtomicDeleteNew"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcAtomicDeleteNew) FcAtomicDeleteNew __attribute((alias("IA__FcAtomicDeleteNew"), visibility("default"))); # undef FcAtomicUnlock -extern __typeof (FcAtomicUnlock) FcAtomicUnlock __attribute((alias("IA__FcAtomicUnlock"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcAtomicUnlock) FcAtomicUnlock __attribute((alias("IA__FcAtomicUnlock"), visibility("default"))); # undef FcAtomicDestroy -extern __typeof (FcAtomicDestroy) FcAtomicDestroy __attribute((alias("IA__FcAtomicDestroy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcAtomicDestroy) FcAtomicDestroy __attribute((alias("IA__FcAtomicDestroy"), visibility("default"))); #endif /* __fcatomic__ */ #ifdef __fcmatch__ # undef FcFontSetMatch -extern __typeof (FcFontSetMatch) FcFontSetMatch __attribute((alias("IA__FcFontSetMatch"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcFontSetMatch) FcFontSetMatch __attribute((alias("IA__FcFontSetMatch"), visibility("default"))); # undef FcFontMatch -extern __typeof (FcFontMatch) FcFontMatch __attribute((alias("IA__FcFontMatch"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcFontMatch) FcFontMatch __attribute((alias("IA__FcFontMatch"), visibility("default"))); # undef FcFontRenderPrepare -extern __typeof (FcFontRenderPrepare) FcFontRenderPrepare __attribute((alias("IA__FcFontRenderPrepare"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcFontRenderPrepare) FcFontRenderPrepare __attribute((alias("IA__FcFontRenderPrepare"), visibility("default"))); # undef FcFontSetSort -extern __typeof (FcFontSetSort) FcFontSetSort __attribute((alias("IA__FcFontSetSort"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcFontSetSort) FcFontSetSort __attribute((alias("IA__FcFontSetSort"), visibility("default"))); # undef FcFontSort -extern __typeof (FcFontSort) FcFontSort __attribute((alias("IA__FcFontSort"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcFontSort) FcFontSort __attribute((alias("IA__FcFontSort"), visibility("default"))); # undef FcFontSetSortDestroy -extern __typeof (FcFontSetSortDestroy) FcFontSetSortDestroy __attribute((alias("IA__FcFontSetSortDestroy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcFontSetSortDestroy) FcFontSetSortDestroy __attribute((alias("IA__FcFontSetSortDestroy"), visibility("default"))); #endif /* __fcmatch__ */ #ifdef __fcmatrix__ # undef FcMatrixCopy -extern __typeof (FcMatrixCopy) FcMatrixCopy __attribute((alias("IA__FcMatrixCopy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcMatrixCopy) FcMatrixCopy __attribute((alias("IA__FcMatrixCopy"), visibility("default"))); # undef FcMatrixEqual -extern __typeof (FcMatrixEqual) FcMatrixEqual __attribute((alias("IA__FcMatrixEqual"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcMatrixEqual) FcMatrixEqual __attribute((alias("IA__FcMatrixEqual"), visibility("default"))); # undef FcMatrixMultiply -extern __typeof (FcMatrixMultiply) FcMatrixMultiply __attribute((alias("IA__FcMatrixMultiply"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcMatrixMultiply) FcMatrixMultiply __attribute((alias("IA__FcMatrixMultiply"), visibility("default"))); # undef FcMatrixRotate -extern __typeof (FcMatrixRotate) FcMatrixRotate __attribute((alias("IA__FcMatrixRotate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcMatrixRotate) FcMatrixRotate __attribute((alias("IA__FcMatrixRotate"), visibility("default"))); # undef FcMatrixScale -extern __typeof (FcMatrixScale) FcMatrixScale __attribute((alias("IA__FcMatrixScale"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcMatrixScale) FcMatrixScale __attribute((alias("IA__FcMatrixScale"), visibility("default"))); # undef FcMatrixShear -extern __typeof (FcMatrixShear) FcMatrixShear __attribute((alias("IA__FcMatrixShear"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcMatrixShear) FcMatrixShear __attribute((alias("IA__FcMatrixShear"), visibility("default"))); #endif /* __fcmatrix__ */ #ifdef __fcname__ # undef FcNameRegisterObjectTypes -extern __typeof (FcNameRegisterObjectTypes) FcNameRegisterObjectTypes __attribute((alias("IA__FcNameRegisterObjectTypes"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcNameRegisterObjectTypes) FcNameRegisterObjectTypes __attribute((alias("IA__FcNameRegisterObjectTypes"), visibility("default"))); # undef FcNameUnregisterObjectTypes -extern __typeof (FcNameUnregisterObjectTypes) FcNameUnregisterObjectTypes __attribute((alias("IA__FcNameUnregisterObjectTypes"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcNameUnregisterObjectTypes) FcNameUnregisterObjectTypes __attribute((alias("IA__FcNameUnregisterObjectTypes"), visibility("default"))); # undef FcNameGetObjectType -extern __typeof (FcNameGetObjectType) FcNameGetObjectType __attribute((alias("IA__FcNameGetObjectType"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcNameGetObjectType) FcNameGetObjectType __attribute((alias("IA__FcNameGetObjectType"), visibility("default"))); # undef FcNameRegisterConstants -extern __typeof (FcNameRegisterConstants) FcNameRegisterConstants __attribute((alias("IA__FcNameRegisterConstants"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcNameRegisterConstants) FcNameRegisterConstants __attribute((alias("IA__FcNameRegisterConstants"), visibility("default"))); # undef FcNameUnregisterConstants -extern __typeof (FcNameUnregisterConstants) FcNameUnregisterConstants __attribute((alias("IA__FcNameUnregisterConstants"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcNameUnregisterConstants) FcNameUnregisterConstants __attribute((alias("IA__FcNameUnregisterConstants"), visibility("default"))); # undef FcNameGetConstant -extern __typeof (FcNameGetConstant) FcNameGetConstant __attribute((alias("IA__FcNameGetConstant"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcNameGetConstant) FcNameGetConstant __attribute((alias("IA__FcNameGetConstant"), visibility("default"))); # undef FcNameConstant -extern __typeof (FcNameConstant) FcNameConstant __attribute((alias("IA__FcNameConstant"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcNameConstant) FcNameConstant __attribute((alias("IA__FcNameConstant"), visibility("default"))); # undef FcNameParse -extern __typeof (FcNameParse) FcNameParse __attribute((alias("IA__FcNameParse"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcNameParse) FcNameParse __attribute((alias("IA__FcNameParse"), visibility("default"))); # undef FcNameUnparse -extern __typeof (FcNameUnparse) FcNameUnparse __attribute((alias("IA__FcNameUnparse"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcNameUnparse) FcNameUnparse __attribute((alias("IA__FcNameUnparse"), visibility("default"))); #endif /* __fcname__ */ #ifdef __fcpat__ # undef FcPatternCreate -extern __typeof (FcPatternCreate) FcPatternCreate __attribute((alias("IA__FcPatternCreate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternCreate) FcPatternCreate __attribute((alias("IA__FcPatternCreate"), visibility("default"))); # undef FcPatternDuplicate -extern __typeof (FcPatternDuplicate) FcPatternDuplicate __attribute((alias("IA__FcPatternDuplicate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternDuplicate) FcPatternDuplicate __attribute((alias("IA__FcPatternDuplicate"), visibility("default"))); # undef FcPatternReference -extern __typeof (FcPatternReference) FcPatternReference __attribute((alias("IA__FcPatternReference"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternReference) FcPatternReference __attribute((alias("IA__FcPatternReference"), visibility("default"))); # undef FcPatternFilter -extern __typeof (FcPatternFilter) FcPatternFilter __attribute((alias("IA__FcPatternFilter"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternFilter) FcPatternFilter __attribute((alias("IA__FcPatternFilter"), visibility("default"))); # undef FcValueDestroy -extern __typeof (FcValueDestroy) FcValueDestroy __attribute((alias("IA__FcValueDestroy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcValueDestroy) FcValueDestroy __attribute((alias("IA__FcValueDestroy"), visibility("default"))); # undef FcValueEqual -extern __typeof (FcValueEqual) FcValueEqual __attribute((alias("IA__FcValueEqual"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcValueEqual) FcValueEqual __attribute((alias("IA__FcValueEqual"), visibility("default"))); # undef FcValueSave -extern __typeof (FcValueSave) FcValueSave __attribute((alias("IA__FcValueSave"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcValueSave) FcValueSave __attribute((alias("IA__FcValueSave"), visibility("default"))); # undef FcPatternDestroy -extern __typeof (FcPatternDestroy) FcPatternDestroy __attribute((alias("IA__FcPatternDestroy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; -# undef FcPatternObjectCount -extern __typeof (FcPatternObjectCount) FcPatternObjectCount __attribute((alias("IA__FcPatternObjectCount"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternDestroy) FcPatternDestroy __attribute((alias("IA__FcPatternDestroy"), visibility("default"))); # undef FcPatternEqual -extern __typeof (FcPatternEqual) FcPatternEqual __attribute((alias("IA__FcPatternEqual"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternEqual) FcPatternEqual __attribute((alias("IA__FcPatternEqual"), visibility("default"))); # undef FcPatternEqualSubset -extern __typeof (FcPatternEqualSubset) FcPatternEqualSubset __attribute((alias("IA__FcPatternEqualSubset"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternEqualSubset) FcPatternEqualSubset __attribute((alias("IA__FcPatternEqualSubset"), visibility("default"))); # undef FcPatternHash -extern __typeof (FcPatternHash) FcPatternHash __attribute((alias("IA__FcPatternHash"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternHash) FcPatternHash __attribute((alias("IA__FcPatternHash"), visibility("default"))); # undef FcPatternAdd -extern __typeof (FcPatternAdd) FcPatternAdd __attribute((alias("IA__FcPatternAdd"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternAdd) FcPatternAdd __attribute((alias("IA__FcPatternAdd"), visibility("default"))); # undef FcPatternAddWeak -extern __typeof (FcPatternAddWeak) FcPatternAddWeak __attribute((alias("IA__FcPatternAddWeak"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternAddWeak) FcPatternAddWeak __attribute((alias("IA__FcPatternAddWeak"), visibility("default"))); # undef FcPatternGet -extern __typeof (FcPatternGet) FcPatternGet __attribute((alias("IA__FcPatternGet"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternGet) FcPatternGet __attribute((alias("IA__FcPatternGet"), visibility("default"))); # undef FcPatternGetWithBinding -extern __typeof (FcPatternGetWithBinding) FcPatternGetWithBinding __attribute((alias("IA__FcPatternGetWithBinding"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternGetWithBinding) FcPatternGetWithBinding __attribute((alias("IA__FcPatternGetWithBinding"), visibility("default"))); # undef FcPatternDel -extern __typeof (FcPatternDel) FcPatternDel __attribute((alias("IA__FcPatternDel"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternDel) FcPatternDel __attribute((alias("IA__FcPatternDel"), visibility("default"))); # undef FcPatternRemove -extern __typeof (FcPatternRemove) FcPatternRemove __attribute((alias("IA__FcPatternRemove"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternRemove) FcPatternRemove __attribute((alias("IA__FcPatternRemove"), visibility("default"))); # undef FcPatternAddInteger -extern __typeof (FcPatternAddInteger) FcPatternAddInteger __attribute((alias("IA__FcPatternAddInteger"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternAddInteger) FcPatternAddInteger __attribute((alias("IA__FcPatternAddInteger"), visibility("default"))); # undef FcPatternAddDouble -extern __typeof (FcPatternAddDouble) FcPatternAddDouble __attribute((alias("IA__FcPatternAddDouble"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternAddDouble) FcPatternAddDouble __attribute((alias("IA__FcPatternAddDouble"), visibility("default"))); # undef FcPatternAddString -extern __typeof (FcPatternAddString) FcPatternAddString __attribute((alias("IA__FcPatternAddString"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternAddString) FcPatternAddString __attribute((alias("IA__FcPatternAddString"), visibility("default"))); # undef FcPatternAddMatrix -extern __typeof (FcPatternAddMatrix) FcPatternAddMatrix __attribute((alias("IA__FcPatternAddMatrix"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternAddMatrix) FcPatternAddMatrix __attribute((alias("IA__FcPatternAddMatrix"), visibility("default"))); # undef FcPatternAddCharSet -extern __typeof (FcPatternAddCharSet) FcPatternAddCharSet __attribute((alias("IA__FcPatternAddCharSet"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternAddCharSet) FcPatternAddCharSet __attribute((alias("IA__FcPatternAddCharSet"), visibility("default"))); # undef FcPatternAddBool -extern __typeof (FcPatternAddBool) FcPatternAddBool __attribute((alias("IA__FcPatternAddBool"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternAddBool) FcPatternAddBool __attribute((alias("IA__FcPatternAddBool"), visibility("default"))); # undef FcPatternAddLangSet -extern __typeof (FcPatternAddLangSet) FcPatternAddLangSet __attribute((alias("IA__FcPatternAddLangSet"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternAddLangSet) FcPatternAddLangSet __attribute((alias("IA__FcPatternAddLangSet"), visibility("default"))); # undef FcPatternAddRange -extern __typeof (FcPatternAddRange) FcPatternAddRange __attribute((alias("IA__FcPatternAddRange"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternAddRange) FcPatternAddRange __attribute((alias("IA__FcPatternAddRange"), visibility("default"))); # undef FcPatternGetInteger -extern __typeof (FcPatternGetInteger) FcPatternGetInteger __attribute((alias("IA__FcPatternGetInteger"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternGetInteger) FcPatternGetInteger __attribute((alias("IA__FcPatternGetInteger"), visibility("default"))); # undef FcPatternGetDouble -extern __typeof (FcPatternGetDouble) FcPatternGetDouble __attribute((alias("IA__FcPatternGetDouble"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternGetDouble) FcPatternGetDouble __attribute((alias("IA__FcPatternGetDouble"), visibility("default"))); # undef FcPatternGetString -extern __typeof (FcPatternGetString) FcPatternGetString __attribute((alias("IA__FcPatternGetString"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternGetString) FcPatternGetString __attribute((alias("IA__FcPatternGetString"), visibility("default"))); # undef FcPatternGetMatrix -extern __typeof (FcPatternGetMatrix) FcPatternGetMatrix __attribute((alias("IA__FcPatternGetMatrix"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternGetMatrix) FcPatternGetMatrix __attribute((alias("IA__FcPatternGetMatrix"), visibility("default"))); # undef FcPatternGetCharSet -extern __typeof (FcPatternGetCharSet) FcPatternGetCharSet __attribute((alias("IA__FcPatternGetCharSet"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternGetCharSet) FcPatternGetCharSet __attribute((alias("IA__FcPatternGetCharSet"), visibility("default"))); # undef FcPatternGetBool -extern __typeof (FcPatternGetBool) FcPatternGetBool __attribute((alias("IA__FcPatternGetBool"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternGetBool) FcPatternGetBool __attribute((alias("IA__FcPatternGetBool"), visibility("default"))); # undef FcPatternGetLangSet -extern __typeof (FcPatternGetLangSet) FcPatternGetLangSet __attribute((alias("IA__FcPatternGetLangSet"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternGetLangSet) FcPatternGetLangSet __attribute((alias("IA__FcPatternGetLangSet"), visibility("default"))); # undef FcPatternGetRange -extern __typeof (FcPatternGetRange) FcPatternGetRange __attribute((alias("IA__FcPatternGetRange"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternGetRange) FcPatternGetRange __attribute((alias("IA__FcPatternGetRange"), visibility("default"))); # undef FcPatternVaBuild -extern __typeof (FcPatternVaBuild) FcPatternVaBuild __attribute((alias("IA__FcPatternVaBuild"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternVaBuild) FcPatternVaBuild __attribute((alias("IA__FcPatternVaBuild"), visibility("default"))); # undef FcPatternBuild -extern __typeof (FcPatternBuild) FcPatternBuild __attribute((alias("IA__FcPatternBuild"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternBuild) FcPatternBuild __attribute((alias("IA__FcPatternBuild"), visibility("default"))); #endif /* __fcpat__ */ #ifdef __fcformat__ # undef FcPatternFormat -extern __typeof (FcPatternFormat) FcPatternFormat __attribute((alias("IA__FcPatternFormat"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternFormat) FcPatternFormat __attribute((alias("IA__FcPatternFormat"), visibility("default"))); #endif /* __fcformat__ */ #ifdef __fcrange__ # undef FcRangeCreateDouble -extern __typeof (FcRangeCreateDouble) FcRangeCreateDouble __attribute((alias("IA__FcRangeCreateDouble"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcRangeCreateDouble) FcRangeCreateDouble __attribute((alias("IA__FcRangeCreateDouble"), visibility("default"))); # undef FcRangeCreateInteger -extern __typeof (FcRangeCreateInteger) FcRangeCreateInteger __attribute((alias("IA__FcRangeCreateInteger"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcRangeCreateInteger) FcRangeCreateInteger __attribute((alias("IA__FcRangeCreateInteger"), visibility("default"))); # undef FcRangeDestroy -extern __typeof (FcRangeDestroy) FcRangeDestroy __attribute((alias("IA__FcRangeDestroy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcRangeDestroy) FcRangeDestroy __attribute((alias("IA__FcRangeDestroy"), visibility("default"))); # undef FcRangeCopy -extern __typeof (FcRangeCopy) FcRangeCopy __attribute((alias("IA__FcRangeCopy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcRangeCopy) FcRangeCopy __attribute((alias("IA__FcRangeCopy"), visibility("default"))); # undef FcRangeGetDouble -extern __typeof (FcRangeGetDouble) FcRangeGetDouble __attribute((alias("IA__FcRangeGetDouble"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcRangeGetDouble) FcRangeGetDouble __attribute((alias("IA__FcRangeGetDouble"), visibility("default"))); #endif /* __fcrange__ */ -#ifdef __fcpat__ -# undef FcPatternIterStart -extern __typeof (FcPatternIterStart) FcPatternIterStart __attribute((alias("IA__FcPatternIterStart"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; -# undef FcPatternIterNext -extern __typeof (FcPatternIterNext) FcPatternIterNext __attribute((alias("IA__FcPatternIterNext"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; -# undef FcPatternIterEqual -extern __typeof (FcPatternIterEqual) FcPatternIterEqual __attribute((alias("IA__FcPatternIterEqual"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; -# undef FcPatternFindIter -extern __typeof (FcPatternFindIter) FcPatternFindIter __attribute((alias("IA__FcPatternFindIter"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; -# undef FcPatternIterIsValid -extern __typeof (FcPatternIterIsValid) FcPatternIterIsValid __attribute((alias("IA__FcPatternIterIsValid"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; -# undef FcPatternIterGetObject -extern __typeof (FcPatternIterGetObject) FcPatternIterGetObject __attribute((alias("IA__FcPatternIterGetObject"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; -# undef FcPatternIterValueCount -extern __typeof (FcPatternIterValueCount) FcPatternIterValueCount __attribute((alias("IA__FcPatternIterValueCount"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; -# undef FcPatternIterGetValue -extern __typeof (FcPatternIterGetValue) FcPatternIterGetValue __attribute((alias("IA__FcPatternIterGetValue"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; -#endif /* __fcpat__ */ #ifdef __fcweight__ # undef FcWeightFromOpenType -extern __typeof (FcWeightFromOpenType) FcWeightFromOpenType __attribute((alias("IA__FcWeightFromOpenType"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; -# undef FcWeightFromOpenTypeDouble -extern __typeof (FcWeightFromOpenTypeDouble) FcWeightFromOpenTypeDouble __attribute((alias("IA__FcWeightFromOpenTypeDouble"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcWeightFromOpenType) FcWeightFromOpenType __attribute((alias("IA__FcWeightFromOpenType"), visibility("default"))); # undef FcWeightToOpenType -extern __typeof (FcWeightToOpenType) FcWeightToOpenType __attribute((alias("IA__FcWeightToOpenType"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; -# undef FcWeightToOpenTypeDouble -extern __typeof (FcWeightToOpenTypeDouble) FcWeightToOpenTypeDouble __attribute((alias("IA__FcWeightToOpenTypeDouble"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcWeightToOpenType) FcWeightToOpenType __attribute((alias("IA__FcWeightToOpenType"), visibility("default"))); #endif /* __fcweight__ */ #ifdef __fcstr__ # undef FcStrCopy -extern __typeof (FcStrCopy) FcStrCopy __attribute((alias("IA__FcStrCopy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcStrCopy) FcStrCopy __attribute((alias("IA__FcStrCopy"), visibility("default"))); # undef FcStrCopyFilename -extern __typeof (FcStrCopyFilename) FcStrCopyFilename __attribute((alias("IA__FcStrCopyFilename"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcStrCopyFilename) FcStrCopyFilename __attribute((alias("IA__FcStrCopyFilename"), visibility("default"))); # undef FcStrPlus -extern __typeof (FcStrPlus) FcStrPlus __attribute((alias("IA__FcStrPlus"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcStrPlus) FcStrPlus __attribute((alias("IA__FcStrPlus"), visibility("default"))); # undef FcStrFree -extern __typeof (FcStrFree) FcStrFree __attribute((alias("IA__FcStrFree"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcStrFree) FcStrFree __attribute((alias("IA__FcStrFree"), visibility("default"))); # undef FcStrDowncase -extern __typeof (FcStrDowncase) FcStrDowncase __attribute((alias("IA__FcStrDowncase"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcStrDowncase) FcStrDowncase __attribute((alias("IA__FcStrDowncase"), visibility("default"))); # undef FcStrCmpIgnoreCase -extern __typeof (FcStrCmpIgnoreCase) FcStrCmpIgnoreCase __attribute((alias("IA__FcStrCmpIgnoreCase"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcStrCmpIgnoreCase) FcStrCmpIgnoreCase __attribute((alias("IA__FcStrCmpIgnoreCase"), visibility("default"))); # undef FcStrCmp -extern __typeof (FcStrCmp) FcStrCmp __attribute((alias("IA__FcStrCmp"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcStrCmp) FcStrCmp __attribute((alias("IA__FcStrCmp"), visibility("default"))); # undef FcStrStrIgnoreCase -extern __typeof (FcStrStrIgnoreCase) FcStrStrIgnoreCase __attribute((alias("IA__FcStrStrIgnoreCase"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcStrStrIgnoreCase) FcStrStrIgnoreCase __attribute((alias("IA__FcStrStrIgnoreCase"), visibility("default"))); # undef FcStrStr -extern __typeof (FcStrStr) FcStrStr __attribute((alias("IA__FcStrStr"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcStrStr) FcStrStr __attribute((alias("IA__FcStrStr"), visibility("default"))); # undef FcUtf8ToUcs4 -extern __typeof (FcUtf8ToUcs4) FcUtf8ToUcs4 __attribute((alias("IA__FcUtf8ToUcs4"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcUtf8ToUcs4) FcUtf8ToUcs4 __attribute((alias("IA__FcUtf8ToUcs4"), visibility("default"))); # undef FcUtf8Len -extern __typeof (FcUtf8Len) FcUtf8Len __attribute((alias("IA__FcUtf8Len"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcUtf8Len) FcUtf8Len __attribute((alias("IA__FcUtf8Len"), visibility("default"))); # undef FcUcs4ToUtf8 -extern __typeof (FcUcs4ToUtf8) FcUcs4ToUtf8 __attribute((alias("IA__FcUcs4ToUtf8"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcUcs4ToUtf8) FcUcs4ToUtf8 __attribute((alias("IA__FcUcs4ToUtf8"), visibility("default"))); # undef FcUtf16ToUcs4 -extern __typeof (FcUtf16ToUcs4) FcUtf16ToUcs4 __attribute((alias("IA__FcUtf16ToUcs4"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcUtf16ToUcs4) FcUtf16ToUcs4 __attribute((alias("IA__FcUtf16ToUcs4"), visibility("default"))); # undef FcUtf16Len -extern __typeof (FcUtf16Len) FcUtf16Len __attribute((alias("IA__FcUtf16Len"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcUtf16Len) FcUtf16Len __attribute((alias("IA__FcUtf16Len"), visibility("default"))); # undef FcStrDirname -extern __typeof (FcStrDirname) FcStrDirname __attribute((alias("IA__FcStrDirname"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcStrDirname) FcStrDirname __attribute((alias("IA__FcStrDirname"), visibility("default"))); # undef FcStrBasename -extern __typeof (FcStrBasename) FcStrBasename __attribute((alias("IA__FcStrBasename"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcStrBasename) FcStrBasename __attribute((alias("IA__FcStrBasename"), visibility("default"))); # undef FcStrSetCreate -extern __typeof (FcStrSetCreate) FcStrSetCreate __attribute((alias("IA__FcStrSetCreate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcStrSetCreate) FcStrSetCreate __attribute((alias("IA__FcStrSetCreate"), visibility("default"))); # undef FcStrSetMember -extern __typeof (FcStrSetMember) FcStrSetMember __attribute((alias("IA__FcStrSetMember"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcStrSetMember) FcStrSetMember __attribute((alias("IA__FcStrSetMember"), visibility("default"))); # undef FcStrSetEqual -extern __typeof (FcStrSetEqual) FcStrSetEqual __attribute((alias("IA__FcStrSetEqual"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcStrSetEqual) FcStrSetEqual __attribute((alias("IA__FcStrSetEqual"), visibility("default"))); # undef FcStrSetAdd -extern __typeof (FcStrSetAdd) FcStrSetAdd __attribute((alias("IA__FcStrSetAdd"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcStrSetAdd) FcStrSetAdd __attribute((alias("IA__FcStrSetAdd"), visibility("default"))); # undef FcStrSetAddFilename -extern __typeof (FcStrSetAddFilename) FcStrSetAddFilename __attribute((alias("IA__FcStrSetAddFilename"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcStrSetAddFilename) FcStrSetAddFilename __attribute((alias("IA__FcStrSetAddFilename"), visibility("default"))); # undef FcStrSetDel -extern __typeof (FcStrSetDel) FcStrSetDel __attribute((alias("IA__FcStrSetDel"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcStrSetDel) FcStrSetDel __attribute((alias("IA__FcStrSetDel"), visibility("default"))); # undef FcStrSetDestroy -extern __typeof (FcStrSetDestroy) FcStrSetDestroy __attribute((alias("IA__FcStrSetDestroy"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcStrSetDestroy) FcStrSetDestroy __attribute((alias("IA__FcStrSetDestroy"), visibility("default"))); # undef FcStrListCreate -extern __typeof (FcStrListCreate) FcStrListCreate __attribute((alias("IA__FcStrListCreate"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcStrListCreate) FcStrListCreate __attribute((alias("IA__FcStrListCreate"), visibility("default"))); # undef FcStrListFirst -extern __typeof (FcStrListFirst) FcStrListFirst __attribute((alias("IA__FcStrListFirst"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcStrListFirst) FcStrListFirst __attribute((alias("IA__FcStrListFirst"), visibility("default"))); # undef FcStrListNext -extern __typeof (FcStrListNext) FcStrListNext __attribute((alias("IA__FcStrListNext"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcStrListNext) FcStrListNext __attribute((alias("IA__FcStrListNext"), visibility("default"))); # undef FcStrListDone -extern __typeof (FcStrListDone) FcStrListDone __attribute((alias("IA__FcStrListDone"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcStrListDone) FcStrListDone __attribute((alias("IA__FcStrListDone"), visibility("default"))); #endif /* __fcstr__ */ #ifdef __fcxml__ # undef FcConfigParseAndLoad -extern __typeof (FcConfigParseAndLoad) FcConfigParseAndLoad __attribute((alias("IA__FcConfigParseAndLoad"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigParseAndLoad) FcConfigParseAndLoad __attribute((alias("IA__FcConfigParseAndLoad"), visibility("default"))); # undef FcConfigParseAndLoadFromMemory -extern __typeof (FcConfigParseAndLoadFromMemory) FcConfigParseAndLoadFromMemory __attribute((alias("IA__FcConfigParseAndLoadFromMemory"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigParseAndLoadFromMemory) FcConfigParseAndLoadFromMemory __attribute((alias("IA__FcConfigParseAndLoadFromMemory"), visibility("default"))); #endif /* __fcxml__ */ #ifdef __fccfg__ # undef FcConfigGetRescanInverval -extern __typeof (FcConfigGetRescanInverval) FcConfigGetRescanInverval __attribute((alias("IA__FcConfigGetRescanInverval"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigGetRescanInverval) FcConfigGetRescanInverval __attribute((alias("IA__FcConfigGetRescanInverval"), visibility("default"))); # undef FcConfigSetRescanInverval -extern __typeof (FcConfigSetRescanInverval) FcConfigSetRescanInverval __attribute((alias("IA__FcConfigSetRescanInverval"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcConfigSetRescanInverval) FcConfigSetRescanInverval __attribute((alias("IA__FcConfigSetRescanInverval"), visibility("default"))); #endif /* */ #endif /* HAVE_GNUC_ATTRIBUTE */
diff --git a/third_party/fontconfig/include/src/fcftalias.h b/third_party/fontconfig/include/src/fcftalias.h index 593e9977..884eb4b 100644 --- a/third_party/fontconfig/include/src/fcftalias.h +++ b/third_party/fontconfig/include/src/fcftalias.h
@@ -1,12 +1,12 @@ -extern __typeof (FcFreeTypeCharIndex) IA__FcFreeTypeCharIndex FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcFreeTypeCharIndex) IA__FcFreeTypeCharIndex __attribute((visibility("hidden"))); #define FcFreeTypeCharIndex IA__FcFreeTypeCharIndex -extern __typeof (FcFreeTypeCharSetAndSpacing) IA__FcFreeTypeCharSetAndSpacing FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcFreeTypeCharSetAndSpacing) IA__FcFreeTypeCharSetAndSpacing __attribute((visibility("hidden"))); #define FcFreeTypeCharSetAndSpacing IA__FcFreeTypeCharSetAndSpacing -extern __typeof (FcFreeTypeCharSet) IA__FcFreeTypeCharSet FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcFreeTypeCharSet) IA__FcFreeTypeCharSet __attribute((visibility("hidden"))); #define FcFreeTypeCharSet IA__FcFreeTypeCharSet -extern __typeof (FcPatternGetFTFace) IA__FcPatternGetFTFace FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternGetFTFace) IA__FcPatternGetFTFace __attribute((visibility("hidden"))); #define FcPatternGetFTFace IA__FcPatternGetFTFace -extern __typeof (FcPatternAddFTFace) IA__FcPatternAddFTFace FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcPatternAddFTFace) IA__FcPatternAddFTFace __attribute((visibility("hidden"))); #define FcPatternAddFTFace IA__FcPatternAddFTFace -extern __typeof (FcFreeTypeQueryFace) IA__FcFreeTypeQueryFace FC_ATTRIBUTE_VISIBILITY_HIDDEN; +extern __typeof (FcFreeTypeQueryFace) IA__FcFreeTypeQueryFace __attribute((visibility("hidden"))); #define FcFreeTypeQueryFace IA__FcFreeTypeQueryFace
diff --git a/third_party/fontconfig/include/src/fcftaliastail.h b/third_party/fontconfig/include/src/fcftaliastail.h index e3eecbe..f5a537d 100644 --- a/third_party/fontconfig/include/src/fcftaliastail.h +++ b/third_party/fontconfig/include/src/fcftaliastail.h
@@ -1,20 +1,20 @@ #if HAVE_GNUC_ATTRIBUTE #ifdef __fcfreetype__ # undef FcFreeTypeCharIndex -extern __typeof (FcFreeTypeCharIndex) FcFreeTypeCharIndex __attribute((alias("IA__FcFreeTypeCharIndex"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcFreeTypeCharIndex) FcFreeTypeCharIndex __attribute((alias("IA__FcFreeTypeCharIndex"), visibility("default"))); # undef FcFreeTypeCharSetAndSpacing -extern __typeof (FcFreeTypeCharSetAndSpacing) FcFreeTypeCharSetAndSpacing __attribute((alias("IA__FcFreeTypeCharSetAndSpacing"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcFreeTypeCharSetAndSpacing) FcFreeTypeCharSetAndSpacing __attribute((alias("IA__FcFreeTypeCharSetAndSpacing"), visibility("default"))); # undef FcFreeTypeCharSet -extern __typeof (FcFreeTypeCharSet) FcFreeTypeCharSet __attribute((alias("IA__FcFreeTypeCharSet"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcFreeTypeCharSet) FcFreeTypeCharSet __attribute((alias("IA__FcFreeTypeCharSet"), visibility("default"))); #endif /* __fcfreetype__ */ #ifdef __fcpat__ # undef FcPatternGetFTFace -extern __typeof (FcPatternGetFTFace) FcPatternGetFTFace __attribute((alias("IA__FcPatternGetFTFace"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternGetFTFace) FcPatternGetFTFace __attribute((alias("IA__FcPatternGetFTFace"), visibility("default"))); # undef FcPatternAddFTFace -extern __typeof (FcPatternAddFTFace) FcPatternAddFTFace __attribute((alias("IA__FcPatternAddFTFace"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcPatternAddFTFace) FcPatternAddFTFace __attribute((alias("IA__FcPatternAddFTFace"), visibility("default"))); #endif /* __fcpat__ */ #ifdef __fcfreetype__ # undef FcFreeTypeQueryFace -extern __typeof (FcFreeTypeQueryFace) FcFreeTypeQueryFace __attribute((alias("IA__FcFreeTypeQueryFace"))) FC_ATTRIBUTE_VISIBILITY_EXPORT; +extern __typeof (FcFreeTypeQueryFace) FcFreeTypeQueryFace __attribute((alias("IA__FcFreeTypeQueryFace"), visibility("default"))); #endif /* */ #endif /* HAVE_GNUC_ATTRIBUTE */
diff --git a/third_party/fontconfig/include/src/fcobjshash.h b/third_party/fontconfig/include/src/fcobjshash.h index 867a369..7ca40966 100644 --- a/third_party/fontconfig/include/src/fcobjshash.h +++ b/third_party/fontconfig/include/src/fcobjshash.h
@@ -1,4 +1,4 @@ -/* ANSI-C code produced by gperf version 3.1 */ +/* ANSI-C code produced by gperf version 3.0.4 */ /* Command-line: gperf --pic -m 100 fcobjshash.gperf */ /* Computed positions: -k'2-3' */ @@ -26,7 +26,7 @@ && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) /* The character set is not based on ISO-646. */ -#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gperf@gnu.org>." +#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>." #endif #line 1 "fcobjshash.gperf" @@ -37,7 +37,7 @@ int id; }; #include <string.h> -/* maximum key range = 65, duplicates = 0 */ +/* maximum key range = 56, duplicates = 0 */ #ifdef __GNUC__ __inline @@ -47,36 +47,36 @@ #endif #endif static unsigned int -FcObjectTypeHash (register const char *str, register size_t len) +FcObjectTypeHash (register const char *str, register unsigned int len) { static const unsigned char asso_values[] = { - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 9, 21, 18, - 33, 21, 69, 6, 36, 0, 69, 69, 0, 24, - 9, 0, 21, 69, 33, 15, 18, 0, 69, 69, - 0, 21, 6, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69 + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 21, 30, 3, + 36, 45, 60, 3, 15, 0, 60, 60, 0, 9, + 9, 0, 21, 60, 0, 0, 15, 0, 60, 60, + 0, 15, 24, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60 }; return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[1]]; } @@ -88,51 +88,49 @@ char FcObjectTypeNamePool_str7[sizeof("foundry")]; char FcObjectTypeNamePool_str8[sizeof("fullname")]; char FcObjectTypeNamePool_str9[sizeof("pixelsize")]; - char FcObjectTypeNamePool_str10[sizeof("size")]; + char FcObjectTypeNamePool_str10[sizeof("prgname")]; char FcObjectTypeNamePool_str12[sizeof("fullnamelang")]; char FcObjectTypeNamePool_str13[sizeof("globaladvance")]; - char FcObjectTypeNamePool_str14[sizeof("slant")]; + char FcObjectTypeNamePool_str14[sizeof("postscriptname")]; char FcObjectTypeNamePool_str16[sizeof("hinting")]; char FcObjectTypeNamePool_str17[sizeof("minspace")]; char FcObjectTypeNamePool_str18[sizeof("hintstyle")]; char FcObjectTypeNamePool_str19[sizeof("fontformat")]; char FcObjectTypeNamePool_str20[sizeof("fontversion")]; char FcObjectTypeNamePool_str21[sizeof("fontfeatures")]; - char FcObjectTypeNamePool_str22[sizeof("lang")]; - char FcObjectTypeNamePool_str23[sizeof("fontvariations")]; + char FcObjectTypeNamePool_str22[sizeof("outline")]; + char FcObjectTypeNamePool_str23[sizeof("autohint")]; char FcObjectTypeNamePool_str24[sizeof("dpi")]; - char FcObjectTypeNamePool_str25[sizeof("outline")]; - char FcObjectTypeNamePool_str26[sizeof("autohint")]; - char FcObjectTypeNamePool_str27[sizeof("weight")]; - char FcObjectTypeNamePool_str28[sizeof("hash")]; - char FcObjectTypeNamePool_str29[sizeof("postscriptname")]; - char FcObjectTypeNamePool_str31[sizeof("rgba")]; - char FcObjectTypeNamePool_str32[sizeof("scale")]; - char FcObjectTypeNamePool_str33[sizeof("matrix")]; - char FcObjectTypeNamePool_str34[sizeof("rasterizer")]; - char FcObjectTypeNamePool_str35[sizeof("scalable")]; - char FcObjectTypeNamePool_str36[sizeof("antialias")]; - char FcObjectTypeNamePool_str37[sizeof("spacing")]; - char FcObjectTypeNamePool_str38[sizeof("width")]; - char FcObjectTypeNamePool_str39[sizeof("family")]; - char FcObjectTypeNamePool_str40[sizeof("capability")]; - char FcObjectTypeNamePool_str41[sizeof("namelang")]; - char FcObjectTypeNamePool_str42[sizeof("aspect")]; - char FcObjectTypeNamePool_str43[sizeof("familylang")]; - char FcObjectTypeNamePool_str44[sizeof("style")]; - char FcObjectTypeNamePool_str46[sizeof("prgname")]; - char FcObjectTypeNamePool_str47[sizeof("index")]; - char FcObjectTypeNamePool_str48[sizeof("stylelang")]; - char FcObjectTypeNamePool_str49[sizeof("decorative")]; - char FcObjectTypeNamePool_str50[sizeof("variable")]; - char FcObjectTypeNamePool_str51[sizeof("symbol")]; - char FcObjectTypeNamePool_str52[sizeof("charset")]; - char FcObjectTypeNamePool_str53[sizeof("embolden")]; - char FcObjectTypeNamePool_str54[sizeof("charwidth")]; - char FcObjectTypeNamePool_str55[sizeof("charheight")]; - char FcObjectTypeNamePool_str59[sizeof("embeddedbitmap")]; - char FcObjectTypeNamePool_str60[sizeof("lcdfilter")]; - char FcObjectTypeNamePool_str68[sizeof("verticallayout")]; + char FcObjectTypeNamePool_str25[sizeof("hash")]; + char FcObjectTypeNamePool_str26[sizeof("slant")]; + char FcObjectTypeNamePool_str27[sizeof("aspect")]; + char FcObjectTypeNamePool_str28[sizeof("size")]; + char FcObjectTypeNamePool_str29[sizeof("scale")]; + char FcObjectTypeNamePool_str30[sizeof("symbol")]; + char FcObjectTypeNamePool_str31[sizeof("rasterizer")]; + char FcObjectTypeNamePool_str32[sizeof("scalable")]; + char FcObjectTypeNamePool_str33[sizeof("antialias")]; + char FcObjectTypeNamePool_str34[sizeof("lang")]; + char FcObjectTypeNamePool_str35[sizeof("style")]; + char FcObjectTypeNamePool_str36[sizeof("family")]; + char FcObjectTypeNamePool_str37[sizeof("rgba")]; + char FcObjectTypeNamePool_str38[sizeof("namelang")]; + char FcObjectTypeNamePool_str39[sizeof("stylelang")]; + char FcObjectTypeNamePool_str40[sizeof("familylang")]; + char FcObjectTypeNamePool_str41[sizeof("width")]; + char FcObjectTypeNamePool_str42[sizeof("matrix")]; + char FcObjectTypeNamePool_str43[sizeof("charset")]; + char FcObjectTypeNamePool_str45[sizeof("charwidth")]; + char FcObjectTypeNamePool_str46[sizeof("charheight")]; + char FcObjectTypeNamePool_str47[sizeof("embolden")]; + char FcObjectTypeNamePool_str48[sizeof("lcdfilter")]; + char FcObjectTypeNamePool_str49[sizeof("spacing")]; + char FcObjectTypeNamePool_str50[sizeof("index")]; + char FcObjectTypeNamePool_str51[sizeof("weight")]; + char FcObjectTypeNamePool_str52[sizeof("capability")]; + char FcObjectTypeNamePool_str53[sizeof("embeddedbitmap")]; + char FcObjectTypeNamePool_str58[sizeof("decorative")]; + char FcObjectTypeNamePool_str59[sizeof("verticallayout")]; }; static const struct FcObjectTypeNamePool_t FcObjectTypeNamePool_contents = { @@ -141,182 +139,180 @@ "foundry", "fullname", "pixelsize", - "size", + "prgname", "fullnamelang", "globaladvance", - "slant", + "postscriptname", "hinting", "minspace", "hintstyle", "fontformat", "fontversion", "fontfeatures", - "lang", - "fontvariations", - "dpi", "outline", "autohint", - "weight", + "dpi", "hash", - "postscriptname", - "rgba", + "slant", + "aspect", + "size", "scale", - "matrix", + "symbol", "rasterizer", "scalable", "antialias", - "spacing", - "width", - "family", - "capability", - "namelang", - "aspect", - "familylang", + "lang", "style", - "prgname", - "index", + "family", + "rgba", + "namelang", "stylelang", - "decorative", - "variable", - "symbol", + "familylang", + "width", + "matrix", "charset", - "embolden", "charwidth", "charheight", - "embeddedbitmap", + "embolden", "lcdfilter", + "spacing", + "index", + "weight", + "capability", + "embeddedbitmap", + "decorative", "verticallayout" }; #define FcObjectTypeNamePool ((const char *) &FcObjectTypeNamePool_contents) +#ifdef __GNUC__ +__inline +#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif +#endif const struct FcObjectTypeInfo * -FcObjectTypeLookup (register const char *str, register size_t len) +FcObjectTypeLookup (register const char *str, register unsigned int len) { enum { - TOTAL_KEYWORDS = 50, + TOTAL_KEYWORDS = 48, MIN_WORD_LENGTH = 3, MAX_WORD_LENGTH = 14, MIN_HASH_VALUE = 4, - MAX_HASH_VALUE = 68 + MAX_HASH_VALUE = 59 }; static const struct FcObjectTypeInfo wordlist[] = { {-1}, {-1}, {-1}, {-1}, #line 38 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str4,FC_FILE_OBJECT}, + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str4,FC_FILE_OBJECT}, #line 64 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str5,FC_COLOR_OBJECT}, + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str5,FC_COLOR_OBJECT}, {-1}, #line 31 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str7,FC_FOUNDRY_OBJECT}, + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str7,FC_FOUNDRY_OBJECT}, #line 22 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str8,FC_FULLNAME_OBJECT}, + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str8,FC_FULLNAME_OBJECT}, #line 29 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str9,FC_PIXEL_SIZE_OBJECT}, -#line 27 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str10,FC_SIZE_OBJECT}, + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str9,FC_PIXEL_SIZE_OBJECT}, +#line 61 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str10,FC_PRGNAME_OBJECT}, {-1}, #line 23 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str12,FC_FULLNAMELANG_OBJECT}, + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str12,FC_FULLNAMELANG_OBJECT}, #line 37 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str13,FC_GLOBAL_ADVANCE_OBJECT}, -#line 24 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str14,FC_SLANT_OBJECT}, + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str13,FC_GLOBAL_ADVANCE_OBJECT}, +#line 63 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str14,FC_POSTSCRIPT_NAME_OBJECT}, {-1}, #line 34 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str16,FC_HINTING_OBJECT}, + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str16,FC_HINTING_OBJECT}, #line 46 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str17,FC_MINSPACE_OBJECT}, + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str17,FC_MINSPACE_OBJECT}, #line 33 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str18,FC_HINT_STYLE_OBJECT}, + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str18,FC_HINT_STYLE_OBJECT}, #line 54 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str19,FC_FONTFORMAT_OBJECT}, + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str19,FC_FONTFORMAT_OBJECT}, #line 52 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str20,FC_FONTVERSION_OBJECT}, + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str20,FC_FONTVERSION_OBJECT}, #line 60 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str21,FC_FONT_FEATURES_OBJECT}, -#line 51 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str22,FC_LANG_OBJECT}, -#line 66 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str23,FC_FONT_VARIATIONS_OBJECT}, -#line 43 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str24,FC_DPI_OBJECT}, + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str21,FC_FONT_FEATURES_OBJECT}, #line 41 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str25,FC_OUTLINE_OBJECT}, + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str22,FC_OUTLINE_OBJECT}, #line 36 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str26,FC_AUTOHINT_OBJECT}, -#line 25 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str27,FC_WEIGHT_OBJECT}, + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str23,FC_AUTOHINT_OBJECT}, +#line 43 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str24,FC_DPI_OBJECT}, #line 62 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str28,FC_HASH_OBJECT}, -#line 63 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str29,FC_POSTSCRIPT_NAME_OBJECT}, - {-1}, -#line 44 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str31,FC_RGBA_OBJECT}, -#line 45 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str32,FC_SCALE_OBJECT}, -#line 49 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str33,FC_MATRIX_OBJECT}, -#line 40 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str34,FC_RASTERIZER_OBJECT}, -#line 42 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str35,FC_SCALABLE_OBJECT}, -#line 32 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str36,FC_ANTIALIAS_OBJECT}, -#line 30 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str37,FC_SPACING_OBJECT}, -#line 26 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str38,FC_WIDTH_OBJECT}, -#line 18 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str39,FC_FAMILY_OBJECT}, -#line 53 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str40,FC_CAPABILITY_OBJECT}, -#line 59 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str41,FC_NAMELANG_OBJECT}, + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str25,FC_HASH_OBJECT}, +#line 24 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str26,FC_SLANT_OBJECT}, #line 28 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str42,FC_ASPECT_OBJECT}, -#line 19 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str43,FC_FAMILYLANG_OBJECT}, -#line 20 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str44,FC_STYLE_OBJECT}, - {-1}, -#line 61 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str46,FC_PRGNAME_OBJECT}, -#line 39 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str47,FC_INDEX_OBJECT}, -#line 21 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str48,FC_STYLELANG_OBJECT}, -#line 57 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str49,FC_DECORATIVE_OBJECT}, -#line 67 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str50,FC_VARIABLE_OBJECT}, + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str27,FC_ASPECT_OBJECT}, +#line 27 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str28,FC_SIZE_OBJECT}, +#line 45 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str29,FC_SCALE_OBJECT}, #line 65 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str51,FC_SYMBOL_OBJECT}, + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str30,FC_SYMBOL_OBJECT}, +#line 40 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str31,FC_RASTERIZER_OBJECT}, +#line 42 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str32,FC_SCALABLE_OBJECT}, +#line 32 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str33,FC_ANTIALIAS_OBJECT}, +#line 51 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str34,FC_LANG_OBJECT}, +#line 20 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str35,FC_STYLE_OBJECT}, +#line 18 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str36,FC_FAMILY_OBJECT}, +#line 44 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str37,FC_RGBA_OBJECT}, +#line 59 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str38,FC_NAMELANG_OBJECT}, +#line 21 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str39,FC_STYLELANG_OBJECT}, +#line 19 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str40,FC_FAMILYLANG_OBJECT}, +#line 26 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str41,FC_WIDTH_OBJECT}, +#line 49 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str42,FC_MATRIX_OBJECT}, #line 50 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str52,FC_CHARSET_OBJECT}, -#line 55 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str53,FC_EMBOLDEN_OBJECT}, + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str43,FC_CHARSET_OBJECT}, + {-1}, #line 47 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str54,FC_CHARWIDTH_OBJECT}, + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str45,FC_CHARWIDTH_OBJECT}, #line 48 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str55,FC_CHAR_HEIGHT_OBJECT}, - {-1}, {-1}, {-1}, -#line 56 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str59,FC_EMBEDDED_BITMAP_OBJECT}, + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str46,FC_CHAR_HEIGHT_OBJECT}, +#line 55 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str47,FC_EMBOLDEN_OBJECT}, #line 58 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str60,FC_LCD_FILTER_OBJECT}, - {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str48,FC_LCD_FILTER_OBJECT}, +#line 30 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str49,FC_SPACING_OBJECT}, +#line 39 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str50,FC_INDEX_OBJECT}, +#line 25 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str51,FC_WEIGHT_OBJECT}, +#line 53 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str52,FC_CAPABILITY_OBJECT}, +#line 56 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str53,FC_EMBEDDED_BITMAP_OBJECT}, + {-1}, {-1}, {-1}, {-1}, +#line 57 "fcobjshash.gperf" + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str58,FC_DECORATIVE_OBJECT}, #line 35 "fcobjshash.gperf" - {(int)(size_t)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str68,FC_VERTICAL_LAYOUT_OBJECT} + {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str59,FC_VERTICAL_LAYOUT_OBJECT} }; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) { - register unsigned int key = FcObjectTypeHash (str, len); + register int key = FcObjectTypeHash (str, len); - if (key <= MAX_HASH_VALUE) + if (key <= MAX_HASH_VALUE && key >= 0) { register int o = wordlist[key].name; if (o >= 0)
diff --git a/third_party/fontconfig/include/src/fcstdint.h b/third_party/fontconfig/include/src/fcstdint.h index 05a93d5..e2ded13c 100644 --- a/third_party/fontconfig/include/src/fcstdint.h +++ b/third_party/fontconfig/include/src/fcstdint.h
@@ -1,8 +1,8 @@ #ifndef _FONTCONFIG_SRC_FCSTDINT_H #define _FONTCONFIG_SRC_FCSTDINT_H 1 #ifndef _GENERATED_STDINT_H -#define _GENERATED_STDINT_H "fontconfig 2.13.0" -/* generated using gnu compiler gcc (Debian 7.3.0-21) 7.3.0 */ +#define _GENERATED_STDINT_H "fontconfig 2.12.6" +/* generated using gnu compiler gcc (Debian 6.3.0-18) 6.3.0 20170516 */ #define _STDINT_HAVE_STDINT_H 1 #include <stdint.h> #endif
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 834aea8..c3533689 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -27155,6 +27155,7 @@ <int value="-1467332609" label="tab-management-experiment-type-anise"/> <int value="-1466990325" label="CrosCompUpdates:enabled"/> <int value="-1466759286" label="TabModalJsDialog:disabled"/> + <int value="-1465172796" label="CCTModule:disabled"/> <int value="-1463489219" label="OfflinePagesCTSuppressNotifications:enabled"/> <int value="-1463410070" label="IPH_DemoMode:enabled"/> <int value="-1461261930" label="OutOfBlinkCORS:disabled"/> @@ -27717,6 +27718,7 @@ label="NonValidatingReloadOnRefreshContentV2:disabled"/> <int value="-231922000" label="enable-renderer-mojo-channel"/> <int value="-230824955" label="NTPMostLikelyFaviconsFromServer:enabled"/> + <int value="-225505731" label="CCTModule:enabled"/> <int value="-220599034" label="UsePdfCompositorServiceForPrint:enabled"/> <int value="-216219963" label="ash-shelf-color-scheme"/> <int value="-215534141" label="NativeWindowNavButtons:enabled"/>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index d37473c..34a9de9 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -2046,6 +2046,11 @@ Measure of memory consumed by V8. </summary> </metric> + <metric name="V8.AllocatedObjects"> + <summary> + Measure of memory consumed by live objects in V8. + </summary> + </metric> <metric name="WebCache"> <summary> Measure of memory consumed by all resources in Blink Web Cache.
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn index 6fa37d6..679bdd7 100644 --- a/ui/android/BUILD.gn +++ b/ui/android/BUILD.gn
@@ -228,6 +228,7 @@ "java/src/org/chromium/ui/display/DisplayUtil.java", "java/src/org/chromium/ui/display/PhysicalDisplayAndroid.java", "java/src/org/chromium/ui/display/VirtualDisplayAndroid.java", + "java/src/org/chromium/ui/drawable/StateListDrawableBuilder.java", "java/src/org/chromium/ui/events/devices/InputDeviceObserver.java", "java/src/org/chromium/ui/gfx/BitmapHelper.java", "java/src/org/chromium/ui/gfx/ViewConfigurationHelper.java", @@ -295,7 +296,11 @@ java_files = [ "junit/src/org/chromium/ui/base/ClipboardTest.java", "junit/src/org/chromium/ui/base/SelectFileDialogTest.java", + "junit/src/org/chromium/ui/drawable/StateListDrawableBuilderTest.java", "junit/src/org/chromium/ui/text/SpanApplierTest.java", + "junit/src/org/chromium/ui/shadows/ShadowAppCompatResources.java", + "junit/src/org/chromium/ui/shadows/ShadowAppCompatResourcesTest.java", + "junit/src/org/chromium/ui/shadows/ShadowAnimatedStateListDrawable.java", "junit/src/org/chromium/ui/widget/AnchoredPopupWindowTest.java", ] deps = [
diff --git a/ui/android/java/src/org/chromium/ui/drawable/StateListDrawableBuilder.java b/ui/android/java/src/org/chromium/ui/drawable/StateListDrawableBuilder.java new file mode 100644 index 0000000..eb51fd0 --- /dev/null +++ b/ui/android/java/src/org/chromium/ui/drawable/StateListDrawableBuilder.java
@@ -0,0 +1,174 @@ +// Copyright 2018 The Chromium 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.ui.drawable; + +import android.annotation.TargetApi; +import android.content.Context; +import android.graphics.drawable.Animatable; +import android.graphics.drawable.AnimatedStateListDrawable; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.StateListDrawable; +import android.os.Build; +import android.support.annotation.DrawableRes; +import android.support.v7.content.res.AppCompatResources; + +import java.util.ArrayList; +import java.util.List; + +/** + * Helper that simplifies StateListDrawable and AnimatedStateListDrawable creation. Stateful + * drawables have to be created in Java for now, as drawables specified in XML can't reference + * vector drawables on platform versions where VectorDrawableCompat is used (API level 23 and + * below). + * + * {@link #build()} will instantiate AnimatedStateListDrawable on platforms where it is supported + * (API level 21+). On older APIs, transition animations will be ignored and StateListDrawable will + * be instantiated instead. + * + * Usage: + * StateListDrawableBuilder builder = new StateListDrawableBuilder(context); + * StateListDrawableBuilder.State checked = + * builder.addState(R.drawable.checked, android.R.attr.state_checked); + * StateListDrawableBuilder.State unchecked = builder.addState(R.drawable.unchecked); + * builder.addTransition(checked, unchecked, R.drawable.transition_checked_unchecked); + * builder.addTransition(unchecked, checked, R.drawable.transition_unchecked_checked); + * StateListDrawable drawable = builder.build(); + */ +public class StateListDrawableBuilder { + /** Identifies single state of the drawable. Used by {@link #addTransition}. */ + public static class State { + private final @DrawableRes int mDrawable; + private final int[] mStateSet; + private final int mStateId; + + private State(@DrawableRes int drawable, int[] stateSet, int stateId) { + mDrawable = drawable; + mStateSet = stateSet; + mStateId = stateId; + } + + private @DrawableRes int getDrawable() { + return mDrawable; + } + + private int[] getStateSet() { + return mStateSet; + } + + private int getStateId() { + return mStateId; + } + } + + private static class Transition { + private final @DrawableRes int mDrawable; + private final int mFromStateId; + private final int mToStateId; + + private Transition(@DrawableRes int drawable, int fromStateId, int toStateId) { + mDrawable = drawable; + mFromStateId = fromStateId; + mToStateId = toStateId; + } + + private @DrawableRes int getDrawable() { + return mDrawable; + } + + private int getFromId() { + return mFromStateId; + } + + private int getToId() { + return mToStateId; + } + } + + private final Context mContext; + private final List<State> mStates = new ArrayList<>(); + private final List<Transition> mTransitions = new ArrayList<>(); + + public StateListDrawableBuilder(Context context) { + mContext = context; + } + + /** + * Add state to the drawable. Please note that order of calls to this method is important, as + * StateListDrawable will pick the first state which stateSet matches View state. + * @param drawable Id of the drawable for the added state. May refer to a vector drawable. + * @param stateSet Array of state ids that specify the state. See {@link android.R.attr} + * for the list of state ids provided by the platform. + */ + public State addState(@DrawableRes int drawable, int... stateSet) { + int nextStateId = mStates.size() + 1; // State ids should be greater than 1. + State state = new State(drawable, stateSet, nextStateId); + mStates.add(state); + return state; + } + + /** + * Add transition animation to the stateful drawable. + * @param from The state of the stateful drawable before the transition. + * @param to The state of the stateful drawable after the transition. + * @param drawable Id of the animated drawable for the transition. Must refer to animated vector + * drawable. + */ + public void addTransition(State from, State to, @DrawableRes int drawable) { + assert mStates.contains(from) && mStates.contains(to) : "State from a different builder!"; + Transition transition = new Transition(drawable, from.getStateId(), to.getStateId()); + mTransitions.add(transition); + } + + /** + * Build drawable from added states and transitions. + * @return AnimatedStateListDrawable if platform supports it, StateListDrawable otherwise. + */ + public StateListDrawable build() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + return buildPostL(); + } else { + return buildPreL(); + } + } + + private StateListDrawable buildPreL() { + // Create StateListDrawable on API levels where AnimatedStateListDrawable is not available. + StateListDrawable result = new StateListDrawable(); + int size = mStates.size(); + for (int i = 0; i < size; ++i) { + State state = mStates.get(i); + Drawable drawable = AppCompatResources.getDrawable(mContext, state.getDrawable()); + assert drawable != null; + result.addState(state.getStateSet(), drawable); + } + return result; + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + private StateListDrawable buildPostL() { + AnimatedStateListDrawable result = new AnimatedStateListDrawable(); + int statesSize = mStates.size(); + for (int i = 0; i < statesSize; ++i) { + State state = mStates.get(i); + Drawable drawable = AppCompatResources.getDrawable(mContext, state.getDrawable()); + assert drawable != null; + result.addState(state.getStateSet(), drawable, state.getStateId()); + } + int transitionsSize = mTransitions.size(); + for (int i = 0; i < transitionsSize; ++i) { + Transition transition = mTransitions.get(i); + Drawable drawable = AppCompatResources.getDrawable(mContext, transition.getDrawable()); + result.addTransition(transition.getFromId(), transition.getToId(), + castToAnimatableDrawable(drawable), false); + } + return result; + } + + @SuppressWarnings("unchecked") // Need Java 8 to cast to intersection types + private static <T> T castToAnimatableDrawable(Drawable drawable) { + if (!(drawable instanceof Animatable)) throw new IllegalArgumentException("drawable"); + return (T) drawable; + } +}
diff --git a/ui/android/junit/src/org/chromium/ui/drawable/StateListDrawableBuilderTest.java b/ui/android/junit/src/org/chromium/ui/drawable/StateListDrawableBuilderTest.java new file mode 100644 index 0000000..48911eb --- /dev/null +++ b/ui/android/junit/src/org/chromium/ui/drawable/StateListDrawableBuilderTest.java
@@ -0,0 +1,62 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.ui.drawable; + +import static org.junit.Assert.assertEquals; +import static org.robolectric.Shadows.shadowOf; + +import android.graphics.drawable.AnimatedStateListDrawable; +import android.graphics.drawable.StateListDrawable; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; +import org.robolectric.shadows.ShadowStateListDrawable; + +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.ui.shadows.ShadowAnimatedStateListDrawable; +import org.chromium.ui.shadows.ShadowAppCompatResources; + +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE, + shadows = {ShadowAppCompatResources.class, ShadowAnimatedStateListDrawable.class}) +public class StateListDrawableBuilderTest { + private static final int[] CHECKED_STATE = new int[] {android.R.attr.state_checked}; + private static final int[] WILDCARD_STATE = new int[0]; + private static final int CHECKED_DRAWABLE = 34567; + private static final int DEFAULT_DRAWABLE = 45678; + + @Test + @Config(sdk = 18) + public void testPreL() { + StateListDrawableBuilder b = new StateListDrawableBuilder(RuntimeEnvironment.application); + b.addState(CHECKED_DRAWABLE, android.R.attr.state_checked); + b.addState(DEFAULT_DRAWABLE, WILDCARD_STATE); + StateListDrawable result = b.build(); + assertEquals(result.getClass(), StateListDrawable.class); + ShadowStateListDrawable drawable = shadowOf(result); + assertEquals(CHECKED_DRAWABLE, + shadowOf(drawable.getDrawableForState(CHECKED_STATE)).getCreatedFromResId()); + assertEquals(DEFAULT_DRAWABLE, + shadowOf(drawable.getDrawableForState(WILDCARD_STATE)).getCreatedFromResId()); + } + + @Test + @Config(sdk = 21) + public void testPostL() { + StateListDrawableBuilder b = new StateListDrawableBuilder(RuntimeEnvironment.application); + b.addState(CHECKED_DRAWABLE, android.R.attr.state_checked); + b.addState(DEFAULT_DRAWABLE, WILDCARD_STATE); + StateListDrawable result = b.build(); + assertEquals(result.getClass(), AnimatedStateListDrawable.class); + ShadowAnimatedStateListDrawable drawable = Shadow.extract(result); + assertEquals(CHECKED_DRAWABLE, + shadowOf(drawable.getDrawableForState(CHECKED_STATE)).getCreatedFromResId()); + assertEquals(DEFAULT_DRAWABLE, + shadowOf(drawable.getDrawableForState(WILDCARD_STATE)).getCreatedFromResId()); + } +}
diff --git a/ui/android/junit/src/org/chromium/ui/shadows/ShadowAnimatedStateListDrawable.java b/ui/android/junit/src/org/chromium/ui/shadows/ShadowAnimatedStateListDrawable.java new file mode 100644 index 0000000..94120e5 --- /dev/null +++ b/ui/android/junit/src/org/chromium/ui/shadows/ShadowAnimatedStateListDrawable.java
@@ -0,0 +1,18 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.ui.shadows; + +import android.graphics.drawable.AnimatedStateListDrawable; +import android.graphics.drawable.Drawable; + +import org.robolectric.annotation.Implements; +import org.robolectric.shadows.ShadowStateListDrawable; + +@Implements(AnimatedStateListDrawable.class) +public class ShadowAnimatedStateListDrawable extends ShadowStateListDrawable { + public void addState(int[] stateSet, Drawable drawable, int stateId) { + addState(stateSet, drawable); + } +}
diff --git a/ui/android/junit/src/org/chromium/ui/shadows/ShadowAppCompatResources.java b/ui/android/junit/src/org/chromium/ui/shadows/ShadowAppCompatResources.java new file mode 100644 index 0000000..036ed79 --- /dev/null +++ b/ui/android/junit/src/org/chromium/ui/shadows/ShadowAppCompatResources.java
@@ -0,0 +1,25 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.ui.shadows; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.support.annotation.DrawableRes; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v7.content.res.AppCompatResources; + +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; +import org.robolectric.shadows.ShadowDrawable; + +@Implements(AppCompatResources.class) +public class ShadowAppCompatResources { + @Implementation + @Nullable + public static Drawable getDrawable(@NonNull Context context, @DrawableRes int resId) { + return ShadowDrawable.createFromResourceId(resId); + } +}
diff --git a/ui/android/junit/src/org/chromium/ui/shadows/ShadowAppCompatResourcesTest.java b/ui/android/junit/src/org/chromium/ui/shadows/ShadowAppCompatResourcesTest.java new file mode 100644 index 0000000..c9d359d --- /dev/null +++ b/ui/android/junit/src/org/chromium/ui/shadows/ShadowAppCompatResourcesTest.java
@@ -0,0 +1,32 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.ui.shadows; + +import static org.junit.Assert.assertEquals; +import static org.robolectric.Shadows.shadowOf; + +import android.graphics.drawable.Drawable; +import android.support.v7.content.res.AppCompatResources; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +import org.chromium.base.test.BaseRobolectricTestRunner; + +/** Tests logic in the ShadowAppCompatResources class. */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE, shadows = {ShadowAppCompatResources.class}) +public class ShadowAppCompatResourcesTest { + private static final int DRAWABLE_RES_ID = 34567; + + @Test + public void testShadowAppCompatResources() { + Drawable drawable = + AppCompatResources.getDrawable(RuntimeEnvironment.application, DRAWABLE_RES_ID); + assertEquals(DRAWABLE_RES_ID, shadowOf(drawable).getCreatedFromResId()); + } +}
diff --git a/ui/compositor/BUILD.gn b/ui/compositor/BUILD.gn index e7675de1..3f4eb3e9 100644 --- a/ui/compositor/BUILD.gn +++ b/ui/compositor/BUILD.gn
@@ -184,7 +184,10 @@ if (use_ozone) { sources += [ "test/test_compositor_host_ozone.cc" ] - deps += [ "//ui/ozone" ] + deps += [ + "//ui/ozone", + "//ui/platform_window", + ] } else if (use_x11) { sources += [ "test/test_compositor_host_x11.cc" ] }
diff --git a/ui/file_manager/file_manager/test/BUILD.gn b/ui/file_manager/file_manager/test/BUILD.gn index 5ced0c7..c1d932254 100644 --- a/ui/file_manager/file_manager/test/BUILD.gn +++ b/ui/file_manager/file_manager/test/BUILD.gn
@@ -5,8 +5,21 @@ action("create_test_main") { script = "//ui/file_manager/file_manager/test/scripts/create_test_main.py" output = "$target_gen_dir/../test.html" - deps = [ - "//ui/file_manager:resources", + sources = [ + "../../../webui/resources/css/text_defaults.css", + "../background/js/background_common_scripts.js", + "../background/js/background_scripts.js", + "../foreground/elements/elements_bundle.html", + "../foreground/elements/files_quick_view.html", + "../foreground/elements/files_safe_media.html", + "../foreground/elements/files_safe_media.js", + "../foreground/js/elements_importer.js", + "../foreground/js/main_scripts.js", + "../main.html", + "check_select.js", + "crostini.js", + "quick_view.js", + "uma.js", ] args = [ "--output=" + rebase_path(output, root_build_dir) ] outputs = [
diff --git a/ui/file_manager/file_manager/test/scripts/create_test_main.py b/ui/file_manager/file_manager/test/scripts/create_test_main.py index b219430..8ea718a 100755 --- a/ui/file_manager/file_manager/test/scripts/create_test_main.py +++ b/ui/file_manager/file_manager/test/scripts/create_test_main.py
@@ -142,7 +142,6 @@ # into <script> tags in main.html. # Add polymer libs at start. # Define FILE_MANAGER_ROOT which is required to locate test data files. -bg_scripts = read('background/js/background_scripts.js').split('\n') includes2scripts('foreground/js/main_scripts.js') includes2scripts('background/js/background_common_scripts.js') includes2scripts('background/js/background_scripts.js')
diff --git a/ui/file_manager/integration_tests/file_manager/quick_view.js b/ui/file_manager/integration_tests/file_manager/quick_view.js index fe0667c..7d7c79c 100644 --- a/ui/file_manager/integration_tests/file_manager/quick_view.js +++ b/ui/file_manager/integration_tests/file_manager/quick_view.js
@@ -4,6 +4,14 @@ 'use strict'; +/** + * Returns an array of steps that opens the Quick View dialog on a given file + * |name|. The file must be present in the Files app file list. + * + * @param {string} appId Files app windowId. + * @param {string} name File name. + * @return {!Array<function>} + */ function openQuickViewSteps(appId, name) { let caller = getCaller(); @@ -39,6 +47,13 @@ ]; } +/** + * Assuming that Quick View is currently open per the openQuickViewSteps above, + * returns an array of steps that closes the Quick View dialog. + * + * @param {string} appId Files app windowId. + * @return {!Array<function>} + */ function closeQuickViewSteps(appId) { let caller = getCaller(); @@ -77,11 +92,12 @@ let appId; StepsRunner.run([ - // Open Files app on local downloads. + // Open Files app on Downloads containing ENTRIES.hello. function() { - setupAndWaitUntilReady(null, RootPath.DOWNLOADS, this.next); + setupAndWaitUntilReady( + null, RootPath.DOWNLOADS, this.next, [ENTRIES.hello], []); }, - // Open a file in Quick View. + // Open the file in Quick View. function(results) { appId = results.windowId; const openSteps = openQuickViewSteps(appId, ENTRIES.hello.nameText); @@ -100,11 +116,12 @@ let appId; StepsRunner.run([ - // Open Files app on local downloads. + // Open Files app on Downloads containing ENTRIES.hello. function() { - setupAndWaitUntilReady(null, RootPath.DOWNLOADS, this.next); + setupAndWaitUntilReady( + null, RootPath.DOWNLOADS, this.next, [ENTRIES.hello], []); }, - // Open a file in Quick View. + // Open the file in Quick View. function(results) { appId = results.windowId; const openSteps = openQuickViewSteps(appId, ENTRIES.hello.nameText); @@ -127,11 +144,12 @@ let appId; StepsRunner.run([ - // Open Files app on Drive. + // Open Files app on Drive containing ENTRIES.hello. function() { - setupAndWaitUntilReady(null, RootPath.DRIVE, this.next); + setupAndWaitUntilReady( + null, RootPath.DRIVE, this.next, [], [ENTRIES.hello]); }, - // Open a file in Quick View. + // Open the file in Quick View. function(results) { appId = results.windowId; const openSteps = openQuickViewSteps(appId, ENTRIES.hello.nameText); @@ -152,17 +170,18 @@ const USB_VOLUME_QUERY = '#directory-tree [volume-type-icon="removable"]'; StepsRunner.run([ - // Open Files app on local Downloads. + // Open Files app on Downloads containing ENTRIES.photos. function() { - setupAndWaitUntilReady(null, RootPath.DOWNLOADS, this.next); + setupAndWaitUntilReady( + null, RootPath.DOWNLOADS, this.next, [ENTRIES.photos], []); }, - // Mount an empty USB volume. + // Mount a USB volume. function(results) { appId = results.windowId; chrome.test.sendMessage( - JSON.stringify({name: 'mountFakeUsbEmpty'}), this.next); + JSON.stringify({name: 'mountFakeUsb'}), this.next); }, - // Wait for USB volume to mount. + // Wait for the USB volume to mount. function() { remoteCall.waitForElement(appId, USB_VOLUME_QUERY).then(this.next); }, @@ -171,22 +190,14 @@ remoteCall.callRemoteTestUtil( 'fakeMouseClick', appId, [USB_VOLUME_QUERY], this.next); }, - // Check: Files app is showing an empty USB volume. + // Check: the USB files should appear in the file list. function(result) { chrome.test.assertTrue(!!result, 'fakeMouseClick failed'); - remoteCall.waitForFiles(appId, []).then(this.next); - }, - // Add a file to the USB volume. - function() { - addEntries(['usb'], [ENTRIES.hello], this.next); - }, - // Check: the file should appear in the USB volume. - function() { - const files = [ENTRIES.hello.getExpectedRow()]; + const files = TestEntryInfo.getExpectedRows(BASIC_FAKE_ENTRY_SET); remoteCall.waitForFiles(appId, files, {ignoreLastModifiedTime: true}) .then(this.next); }, - // Open the file in Quick View. + // Open a USB file in Quick View. function() { const openSteps = openQuickViewSteps(appId, ENTRIES.hello.nameText); StepsRunner.run(openSteps).then(this.next); @@ -206,9 +217,10 @@ const MTP_VOLUME_QUERY = '#directory-tree [volume-type-icon="mtp"]'; StepsRunner.run([ - // Open Files app on local Downloads. + // Open Files app on Downloads containing ENTRIES.photos. function() { - setupAndWaitUntilReady(null, RootPath.DOWNLOADS, this.next); + setupAndWaitUntilReady( + null, RootPath.DOWNLOADS, this.next, [ENTRIES.photos], []); }, // Mount a non-empty MTP volume. function(results) { @@ -216,7 +228,7 @@ chrome.test.sendMessage( JSON.stringify({name: 'mountFakeMtp'}), this.next); }, - // Wait for MTP volume to mount. + // Wait for the MTP volume to mount. function() { remoteCall.waitForElement(appId, MTP_VOLUME_QUERY).then(this.next); }, @@ -225,14 +237,14 @@ remoteCall.callRemoteTestUtil( 'fakeMouseClick', appId, [MTP_VOLUME_QUERY], this.next); }, - // Check: the expected files should appear in the MTP volume. + // Check: the MTP files should appear in the file list. function(result) { chrome.test.assertTrue(!!result, 'fakeMouseClick failed'); const files = TestEntryInfo.getExpectedRows(BASIC_FAKE_ENTRY_SET); remoteCall.waitForFiles(appId, files, {ignoreLastModifiedTime: true}) .then(this.next); }, - // Open a file in Quick View. + // Open an MTP file in Quick View. function() { const openSteps = openQuickViewSteps(appId, ENTRIES.hello.nameText); StepsRunner.run(openSteps).then(this.next);
diff --git a/ui/ozone/platform/scenic/BUILD.gn b/ui/ozone/platform/scenic/BUILD.gn index b4ca1fc..1dd6dff 100644 --- a/ui/ozone/platform/scenic/BUILD.gn +++ b/ui/ozone/platform/scenic/BUILD.gn
@@ -29,6 +29,8 @@ "//third_party/fuchsia-sdk:images", "//third_party/fuchsia-sdk:mem", "//third_party/fuchsia-sdk:scenic", + "//third_party/fuchsia-sdk:views_v1", + "//third_party/fuchsia-sdk:views_v1_token", "//ui/base", "//ui/display/manager", "//ui/events/ozone:events_ozone_layout",
diff --git a/ui/ozone/platform/scenic/ozone_platform_scenic.cc b/ui/ozone/platform/scenic/ozone_platform_scenic.cc index f491e9f..4ec020dd 100644 --- a/ui/ozone/platform/scenic/ozone_platform_scenic.cc +++ b/ui/ozone/platform/scenic/ozone_platform_scenic.cc
@@ -75,8 +75,12 @@ std::unique_ptr<PlatformWindow> CreatePlatformWindow( PlatformWindowDelegate* delegate, PlatformWindowInitProperties properties) override { - NOTREACHED(); - return nullptr; + if (!properties.view_owner_request) { + NOTREACHED(); + return nullptr; + } + return std::make_unique<ScenicWindow>( + &window_manager_, delegate, std::move(properties.view_owner_request)); } std::unique_ptr<display::NativeDisplayDelegate> CreateNativeDisplayDelegate()
diff --git a/ui/ozone/platform/scenic/scenic_window.cc b/ui/ozone/platform/scenic/scenic_window.cc index cacb238..ba7987b 100644 --- a/ui/ozone/platform/scenic/scenic_window.cc +++ b/ui/ozone/platform/scenic/scenic_window.cc
@@ -6,6 +6,9 @@ #include <string> +#include <fuchsia/sys/cpp/fidl.h> + +#include "base/fuchsia/fuchsia_logging.h" #include "ui/events/event.h" #include "ui/events/event_constants.h" #include "ui/events/keycodes/dom/keycode_converter.h" @@ -16,25 +19,94 @@ namespace ui { -ScenicWindow::ScenicWindow(ScenicWindowManager* window_manager, - PlatformWindowDelegate* delegate) +namespace { + +const uint32_t kUsbHidKeyboardPage = 0x07; + +int KeyModifiersToFlags(int modifiers) { + int flags = 0; + if (modifiers & fuchsia::ui::input::kModifierShift) + flags |= EF_SHIFT_DOWN; + if (modifiers & fuchsia::ui::input::kModifierControl) + flags |= EF_CONTROL_DOWN; + if (modifiers & fuchsia::ui::input::kModifierAlt) + flags |= EF_ALT_DOWN; + // TODO(crbug.com/850697): Add AltGraph support. + return flags; +} + +} // namespace + +ScenicWindow::ScenicWindow( + ScenicWindowManager* window_manager, + PlatformWindowDelegate* delegate, + fidl::InterfaceRequest<fuchsia::ui::views_v1_token::ViewOwner> + view_owner_request) : manager_(window_manager), delegate_(delegate), - window_id_(manager_->AddWindow(this)) { - delegate_->OnAcceleratedWidgetAvailable(window_id_, - /*device_pixel_ratio=*/1.0); + window_id_(manager_->AddWindow(this)), + view_listener_binding_(this), + scenic_session_(manager_->GetScenic(), this), + input_listener_binding_(this) { + // Create event pair to import parent view node to Scenic. One end is passed + // directly to Scenic in ImportResource command and the second one is passed + // to ViewManager::CreateView(). ViewManager will passes it to Scenic when the + // view is added to a container. + zx::eventpair parent_export_token; + zx::eventpair parent_import_token; + zx_status_t status = + zx::eventpair::create(0u, &parent_import_token, &parent_export_token); + ZX_CHECK(status == ZX_OK, status) << "zx_eventpair_create()"; + + // Create a new node and add it as a child to the parent. + parent_node_id_ = scenic_session_.ImportResource( + fuchsia::ui::gfx::ImportSpec::NODE, std::move(parent_import_token)); + node_id_ = scenic_session_.CreateEntityNode(); + scenic_session_.AddNodeChild(parent_node_id_, node_id_); + + // Subscribe to metrics events from the parent node. These events are used to + // get |device_pixel_ratio_| for the screen. + scenic_session_.SetEventMask(parent_node_id_, + fuchsia::ui::gfx::kMetricsEventMask); + + // Create the view. + manager_->GetViewManager()->CreateView( + view_.NewRequest(), std::move(view_owner_request), + view_listener_binding_.NewBinding(), std::move(parent_export_token), + "Chromium"); + view_.set_error_handler(fit::bind_member(this, &ScenicWindow::OnViewError)); + view_listener_binding_.set_error_handler( + fit::bind_member(this, &ScenicWindow::OnViewError)); + + // Setup input event listener. + fuchsia::sys::ServiceProviderPtr view_service_provider; + view_->GetServiceProvider(view_service_provider.NewRequest()); + view_service_provider->ConnectToService( + fuchsia::ui::input::InputConnection::Name_, + input_connection_.NewRequest().TakeChannel()); + input_connection_->SetEventListener(input_listener_binding_.NewBinding()); + + // Call Present() to ensure that the scenic session commands are processed, + // which is necessary to receive metrics event from Scenic. + // OnAcceleratedWidgetAvailable() will be called after View metrics are + // received. + scenic_session_.Present(); } ScenicWindow::~ScenicWindow() { delegate_->OnAcceleratedWidgetDestroying(); + scenic_session_.ReleaseResource(node_id_); + scenic_session_.ReleaseResource(parent_node_id_); + manager_->RemoveWindow(window_id_, this); + view_.Unbind(); delegate_->OnAcceleratedWidgetDestroyed(); } gfx::Rect ScenicWindow::GetBounds() { - return gfx::Rect(size_); + return gfx::Rect(size_pixels_); } void ScenicWindow::SetBounds(const gfx::Rect& bounds) { @@ -112,4 +184,167 @@ return nullptr; } +void ScenicWindow::UpdateSize() { + gfx::SizeF scaled = ScaleSize(size_dips_, device_pixel_ratio_); + size_pixels_ = gfx::Size(ceilf(scaled.width()), ceilf(scaled.height())); + delegate_->OnBoundsChanged(gfx::Rect(size_pixels_)); +} + +void ScenicWindow::OnPropertiesChanged( + fuchsia::ui::views_v1::ViewProperties properties, + OnPropertiesChangedCallback callback) { + if (properties.view_layout) { + size_dips_.SetSize(properties.view_layout->size.width, + properties.view_layout->size.height); + if (device_pixel_ratio_ > 0.0) + UpdateSize(); + } + + callback(); +} + +void ScenicWindow::OnScenicError(const std::string& error) { + LOG(ERROR) << "ScenicSession failed: " << error; + delegate_->OnClosed(); +} + +void ScenicWindow::OnScenicEvents( + const std::vector<fuchsia::ui::scenic::Event>& events) { + for (const auto& event : events) { + if (!event.is_gfx() || !event.gfx().is_metrics()) + continue; + + auto& metrics = event.gfx().metrics(); + if (metrics.node_id == parent_node_id_) { + float new_device_pixel_ratio = + std::max(metrics.metrics.scale_x, metrics.metrics.scale_y); + if (device_pixel_ratio_ == 0.0) { + device_pixel_ratio_ = new_device_pixel_ratio; + delegate_->OnAcceleratedWidgetAvailable(window_id_, + device_pixel_ratio_); + if (!size_dips_.IsEmpty()) + UpdateSize(); + } else if (device_pixel_ratio_ != new_device_pixel_ratio) { + // Ozone currently doesn't support dynamic changes in + // device_pixel_ratio. + // TODO(crbug.com/850650): Update Ozone/Aura to allow DPI changes + // after OnAcceleratedWidgetAvailable(). + NOTIMPLEMENTED() << "Ignoring display metrics event."; + } + } + } +} + +void ScenicWindow::OnEvent(fuchsia::ui::input::InputEvent event, + OnEventCallback callback) { + bool result = false; + + switch (event.Which()) { + case fuchsia::ui::input::InputEvent::Tag::kPointer: + // TODO(crbug.com/829980): Add touch support. + if (event.pointer().type == fuchsia::ui::input::PointerEventType::MOUSE) + result = OnMouseEvent(event.pointer()); + break; + + case fuchsia::ui::input::InputEvent::Tag::kKeyboard: + result = OnKeyboardEvent(event.keyboard()); + break; + + case fuchsia::ui::input::InputEvent::Tag::kFocus: + case fuchsia::ui::input::InputEvent::Tag::Invalid: + break; + } + + callback(result); +} + +void ScenicWindow::OnViewError() { + VLOG(1) << "views_v1::View connection was closed."; + delegate_->OnClosed(); +} + +bool ScenicWindow::OnMouseEvent(const fuchsia::ui::input::PointerEvent& event) { + int flags = 0; + if (event.buttons & 1) + flags |= EF_LEFT_MOUSE_BUTTON; + if (event.buttons & 2) + flags |= EF_RIGHT_MOUSE_BUTTON; + if (event.buttons & 4) + flags |= EF_MIDDLE_MOUSE_BUTTON; + + EventType event_type; + + switch (event.phase) { + case fuchsia::ui::input::PointerEventPhase::DOWN: + event_type = ET_MOUSE_PRESSED; + break; + case fuchsia::ui::input::PointerEventPhase::MOVE: + event_type = flags ? ET_MOUSE_DRAGGED : ET_MOUSE_MOVED; + break; + case fuchsia::ui::input::PointerEventPhase::UP: + event_type = ET_MOUSE_RELEASED; + break; + + // Following phases are not expected for mouse events. + case fuchsia::ui::input::PointerEventPhase::HOVER: + case fuchsia::ui::input::PointerEventPhase::CANCEL: + case fuchsia::ui::input::PointerEventPhase::ADD: + case fuchsia::ui::input::PointerEventPhase::REMOVE: + NOTREACHED() << "Unexpected mouse phase " << event.phase; + return false; + } + + gfx::Point location = + gfx::Point(event.x * device_pixel_ratio_, event.y * device_pixel_ratio_); + ui::MouseEvent mouse_event(event_type, location, location, + base::TimeTicks::FromZxTime(event.event_time), + flags, 0); + delegate_->DispatchEvent(&mouse_event); + return true; +} + +bool ScenicWindow::OnKeyboardEvent( + const fuchsia::ui::input::KeyboardEvent& event) { + EventType event_type; + + switch (event.phase) { + case fuchsia::ui::input::KeyboardEventPhase::PRESSED: + case fuchsia::ui::input::KeyboardEventPhase::REPEAT: + event_type = ET_KEY_PRESSED; + break; + + case fuchsia::ui::input::KeyboardEventPhase::RELEASED: + event_type = ET_KEY_RELEASED; + break; + + case fuchsia::ui::input::KeyboardEventPhase::CANCELLED: + NOTIMPLEMENTED() << "Key event cancellation is not supported."; + event_type = ET_KEY_RELEASED; + break; + } + + // Currently KeyboardEvent doesn't specify HID Usage page. |hid_usage| + // field always contains values from the Keyboard page. See + // https://fuchsia.atlassian.net/browse/SCN-762 . + DomCode dom_code = KeycodeConverter::UsbKeycodeToDomCode( + (kUsbHidKeyboardPage << 16) | event.hid_usage); + DomKey dom_key; + KeyboardCode key_code; + if (!DomCodeToUsLayoutDomKey(dom_code, KeyModifiersToFlags(event.modifiers), + &dom_key, &key_code)) { + LOG(ERROR) << "DomCodeToUsLayoutDomKey() failed for usb_key: " + << event.hid_usage; + key_code = VKEY_UNKNOWN; + } + + if (event.code_point) + dom_key = DomKey::FromCharacter(event.code_point); + + KeyEvent key_event(ET_KEY_PRESSED, key_code, dom_code, + KeyModifiersToFlags(event.modifiers), dom_key, + base::TimeTicks::FromZxTime(event.event_time)); + delegate_->DispatchEvent(&key_event); + return true; +} + } // namespace ui
diff --git a/ui/ozone/platform/scenic/scenic_window.h b/ui/ozone/platform/scenic/scenic_window.h index c56d54e..5e257bd 100644 --- a/ui/ozone/platform/scenic/scenic_window.h +++ b/ui/ozone/platform/scenic/scenic_window.h
@@ -5,10 +5,16 @@ #ifndef UI_OZONE_PLATFORM_SCENIC_SCENIC_WINDOW_H_ #define UI_OZONE_PLATFORM_SCENIC_SCENIC_WINDOW_H_ +#include <fuchsia/ui/input/cpp/fidl.h> +#include <fuchsia/ui/views_v1/cpp/fidl.h> + #include "base/macros.h" #include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/size.h" +#include "ui/gfx/geometry/size_f.h" #include "ui/gfx/native_widget_types.h" #include "ui/ozone/ozone_export.h" +#include "ui/ozone/platform/scenic/scenic_session.h" #include "ui/platform_window/platform_window.h" namespace ui { @@ -16,13 +22,25 @@ class ScenicWindowManager; class PlatformWindowDelegate; -class OZONE_EXPORT ScenicWindow : public PlatformWindow { +class OZONE_EXPORT ScenicWindow : public PlatformWindow, + public ScenicSessionListener, + public fuchsia::ui::views_v1::ViewListener, + public fuchsia::ui::input::InputListener { public: // Both |window_manager| and |delegate| must outlive the ScenicWindow. + // |view_owner_request| is passed to the view managed when creating the + // underlying view. In order for the View to be displayed the ViewOwner must + // be used to add the view to a ViewContainer. ScenicWindow(ScenicWindowManager* window_manager, - PlatformWindowDelegate* delegate); + PlatformWindowDelegate* delegate, + fidl::InterfaceRequest<fuchsia::ui::views_v1_token::ViewOwner> + view_owner_request); ~ScenicWindow() override; + ScenicSession* scenic_session() { return &scenic_session_; } + ScenicSession::ResourceId node_id() const { return node_id_; } + float device_pixel_ratio() const { return device_pixel_ratio_; } + // PlatformWindow implementation. gfx::Rect GetBounds() override; void SetBounds(const gfx::Rect& bounds) override; @@ -45,11 +63,59 @@ PlatformImeController* GetPlatformImeController() override; private: + // views::ViewListener interface. + void OnPropertiesChanged(fuchsia::ui::views_v1::ViewProperties properties, + OnPropertiesChangedCallback callback) override; + + // fuchsia::ui::input::InputListener interface. + void OnEvent(fuchsia::ui::input::InputEvent event, + OnEventCallback callback) override; + + // ScenicSessionListener interface. + void OnScenicError(const std::string& error) override; + void OnScenicEvents( + const std::vector<fuchsia::ui::scenic::Event>& events) override; + + // Error handler for |view_|. This error normally indicates the View was + // destroyed (e.g. dropping ViewOwner). + void OnViewError(); + + void UpdateSize(); + + bool OnMouseEvent(const fuchsia::ui::input::PointerEvent& event); + bool OnKeyboardEvent(const fuchsia::ui::input::KeyboardEvent& event); + ScenicWindowManager* const manager_; PlatformWindowDelegate* const delegate_; gfx::AcceleratedWidget const window_id_; - gfx::Size size_; + // Underlying View in the view_manager. + fuchsia::ui::views_v1::ViewPtr view_; + fidl::Binding<fuchsia::ui::views_v1::ViewListener> view_listener_binding_; + + // Scenic session used for all drawing operations in this View. + ScenicSession scenic_session_; + + // Node ID in |scenic_session_| for the parent view. + ScenicSession::ResourceId parent_node_id_; + + // Node ID in |scenic_session_| for the view. + ScenicSession::ResourceId node_id_; + + // Current view size in DIPs. + gfx::SizeF size_dips_; + + // Current view size in device pixels. + gfx::Size size_pixels_; + + // Device pixel ratio for the current device. Initialized in + // OnPropertiesChanged(). + float device_pixel_ratio_ = 0.0; + + // InputConnection and InputListener binding used to receive input events from + // the view. + fuchsia::ui::input::InputConnectionPtr input_connection_; + fidl::Binding<fuchsia::ui::input::InputListener> input_listener_binding_; DISALLOW_COPY_AND_ASSIGN(ScenicWindow); };
diff --git a/ui/ozone/platform/scenic/scenic_window_manager.cc b/ui/ozone/platform/scenic/scenic_window_manager.cc index 14323a7..42dc0125 100644 --- a/ui/ozone/platform/scenic/scenic_window_manager.cc +++ b/ui/ozone/platform/scenic/scenic_window_manager.cc
@@ -11,6 +11,27 @@ ScenicWindowManager::ScenicWindowManager() = default; ScenicWindowManager::~ScenicWindowManager() = default; +fuchsia::ui::views_v1::ViewManager* ScenicWindowManager::GetViewManager() { + if (!view_manager_) { + view_manager_ = + base::fuchsia::ComponentContext::GetDefault() + ->ConnectToService<fuchsia::ui::views_v1::ViewManager>(); + view_manager_.set_error_handler( + [this]() { LOG(FATAL) << "ViewManager connection failed."; }); + } + + return view_manager_.get(); +} + +fuchsia::ui::scenic::Scenic* ScenicWindowManager::GetScenic() { + if (!scenic_) { + GetViewManager()->GetScenic(scenic_.NewRequest()); + scenic_.set_error_handler( + [this]() { LOG(FATAL) << "Scenic connection failed."; }); + } + return scenic_.get(); +} + int32_t ScenicWindowManager::AddWindow(ScenicWindow* window) { return windows_.Add(window); }
diff --git a/ui/ozone/platform/scenic/scenic_window_manager.h b/ui/ozone/platform/scenic/scenic_window_manager.h index af20882..f36dc83 100644 --- a/ui/ozone/platform/scenic/scenic_window_manager.h +++ b/ui/ozone/platform/scenic/scenic_window_manager.h
@@ -6,9 +6,10 @@ #define UI_OZONE_PLATFORM_SCENIC_SCENIC_WINDOW_MANAGER_H_ #include <stdint.h> - #include <memory> +#include <fuchsia/ui/views_v1/cpp/fidl.h> + #include "base/containers/id_map.h" #include "base/macros.h" #include "base/threading/thread_checker.h" @@ -32,6 +33,12 @@ ScenicWindowManager(); ~ScenicWindowManager(); + // ViewManager and Scenic services that are used by ScenicWindow. Both + // interfaces are initialized lazily on the first call and they don't change + // afterwards. ScenicWindowManager keeps the ownership. + fuchsia::ui::views_v1::ViewManager* GetViewManager(); + fuchsia::ui::scenic::Scenic* GetScenic(); + // Called by ScenicWindow when a new window instance is created. Returns // window ID for the |window|. int32_t AddWindow(ScenicWindow* window); @@ -44,6 +51,9 @@ private: base::IDMap<ScenicWindow*> windows_; + fuchsia::ui::views_v1::ViewManagerPtr view_manager_; + fuchsia::ui::scenic::ScenicPtr scenic_; + DISALLOW_COPY_AND_ASSIGN(ScenicWindowManager); };
diff --git a/ui/platform_window/BUILD.gn b/ui/platform_window/BUILD.gn index b4f5b61e..1da3728 100644 --- a/ui/platform_window/BUILD.gn +++ b/ui/platform_window/BUILD.gn
@@ -9,6 +9,7 @@ "platform_ime_controller.h", "platform_window.h", "platform_window_delegate.h", + "platform_window_init_properties.cc", "platform_window_init_properties.h", "text_input_state.cc", "text_input_state.h", @@ -20,6 +21,12 @@ "//ui/base/ime:text_input_types", "//ui/gfx", ] + + if (is_fuchsia) { + public_deps = [ + "//third_party/fuchsia-sdk:views_v1_token", + ] + } } group("platform_impls") {
diff --git a/ui/platform_window/platform_window_init_properties.cc b/ui/platform_window/platform_window_init_properties.cc new file mode 100644 index 0000000..7bb846a27 --- /dev/null +++ b/ui/platform_window/platform_window_init_properties.cc
@@ -0,0 +1,15 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/platform_window/platform_window_init_properties.h" + +namespace ui { + +PlatformWindowInitProperties::PlatformWindowInitProperties() = default; +PlatformWindowInitProperties::PlatformWindowInitProperties( + PlatformWindowInitProperties&& props) = default; + +PlatformWindowInitProperties::~PlatformWindowInitProperties() = default; + +} // namespace ui
diff --git a/ui/platform_window/platform_window_init_properties.h b/ui/platform_window/platform_window_init_properties.h index 181b641..eae71198 100644 --- a/ui/platform_window/platform_window_init_properties.h +++ b/ui/platform_window/platform_window_init_properties.h
@@ -7,9 +7,14 @@ #include <string> +#include "build/build_config.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/native_widget_types.h" +#if defined(OS_FUCHSIA) +#include <fuchsia/ui/views_v1_token/cpp/fidl.h> +#endif + namespace ui { enum PlatformWindowType { @@ -21,6 +26,11 @@ // Initial properties which are passed to PlatformWindow to be initialized // with a desired set of properties. struct PlatformWindowInitProperties { + PlatformWindowInitProperties(); + PlatformWindowInitProperties(PlatformWindowInitProperties&& props); + + ~PlatformWindowInitProperties(); + // Tells desired PlatformWindow type. It can be popup, menu or anything else. PlatformWindowType type = PlatformWindowType::PLATFORM_WINDOW_TYPE_WINDOW; // Sets the desired initial bounds. Can be empty. @@ -28,6 +38,11 @@ // Tells PlatformWindow which native widget its parent holds. It is usually // used to find a parent from internal list of PlatformWindows. gfx::AcceleratedWidget parent_widget = gfx::kNullAcceleratedWidget; + +#if defined(OS_FUCHSIA) + fidl::InterfaceRequest<fuchsia::ui::views_v1_token::ViewOwner> + view_owner_request; +#endif }; } // namespace ui
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc index 9ead733..d2b1a70 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc
@@ -75,7 +75,7 @@ ui::PlatformWindowInitProperties properties = ConvertWidgetInitParamsToInitProperties(params); - CreateAndSetPlatformWindow(properties); + CreateAndSetPlatformWindow(std::move(properties)); CreateCompositor(viz::FrameSinkId(), params.force_software_compositing); aura::WindowTreeHost::OnAcceleratedWidgetAvailable(); InitHost();