diff --git a/DEPS b/DEPS index 2e245fe0..bd4eb26 100644 --- a/DEPS +++ b/DEPS
@@ -138,11 +138,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': '2b650797a9920de9880c04b3df124e21a7c0fa80', + 'skia_revision': '29e013deb476758a29196cc49b95b60206c72f40', # 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': 'a2dee8aa24bafb0b1aaacd0602fbc7d2c730a3c2', + 'v8_revision': '2cb25737c9eb7893ac752674e75d400b4419f67c', # 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. @@ -150,7 +150,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': 'ded5f903261a8bee3481aad98d7ed47308b59563', + 'angle_revision': '262e2824847798c7549da0f79278fe7d6c9faea7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -173,7 +173,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling googletest # and whatever else without interference from each other. - 'googletest_revision': 'f71fb4f9a912ec945401cc49a287a759b6131026', + 'googletest_revision': 'f5edb4f542e155c75bc4b516f227911d99ec167c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling lighttpd # and whatever else without interference from each other. @@ -201,7 +201,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': 'f5a5c539a5ee7cac023729939ae3258dd9c9b0f9', + 'catapult_revision': '903755a1f84b0a3dc6813f5f177c14a89e72c38d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -1182,7 +1182,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '21362a5cf0dc76445506fb8e19d50110975c6d2d', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '7f727d4068ec466c3b1f3ba5f178fe2f58f1d1d7', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78', @@ -1350,7 +1350,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '6f0b34abee8dba611c253738d955c59f703c147a', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '673784153395ec210c33041aba74018efd8993dd', + Var('webrtc_git') + '/src.git' + '@' + '2f5554dae54d25918c2092f266eb8edf70801037', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1391,7 +1391,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@e9944e4e052c99b18dda79a7585654188c665b77', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@da94a1109604f8b358e2b6f1f0fe8c2f37b7a6a8', 'condition': 'checkout_src_internal', },
diff --git a/ash/system/message_center/message_center_ui_controller.cc b/ash/system/message_center/message_center_ui_controller.cc index 732c80e..38244db 100644 --- a/ash/system/message_center/message_center_ui_controller.cc +++ b/ash/system/message_center/message_center_ui_controller.cc
@@ -6,17 +6,10 @@ #include <memory> -#include "base/macros.h" #include "base/observer_list.h" -#include "base/strings/utf_string_conversions.h" -#include "build/build_config.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/models/simple_menu_model.h" #include "ui/message_center/message_center.h" #include "ui/message_center/message_center_types.h" #include "ui/message_center/notification_blocker.h" -#include "ui/message_center/views/notification_menu_model.h" -#include "ui/strings/grit/ui_strings.h" namespace ash {
diff --git a/base/metrics/field_trial.cc b/base/metrics/field_trial.cc index d2f6f1e..94e663f 100644 --- a/base/metrics/field_trial.cc +++ b/base/metrics/field_trial.cc
@@ -8,7 +8,6 @@ #include <utility> #include "base/base_switches.h" -#include "base/build_time.h" #include "base/command_line.h" #include "base/debug/activity_tracker.h" #include "base/logging.h" @@ -84,33 +83,6 @@ WriteStringPair(pickle, param.first, param.second); } -// Created a time value based on |year|, |month| and |day_of_month| parameters. -Time CreateTimeFromParams(int year, int month, int day_of_month) { - DCHECK_GT(year, 1970); - DCHECK_GT(month, 0); - DCHECK_LT(month, 13); - DCHECK_GT(day_of_month, 0); - DCHECK_LT(day_of_month, 32); - - Time::Exploded exploded; - exploded.year = year; - exploded.month = month; - exploded.day_of_week = 0; // Should be unused. - exploded.day_of_month = day_of_month; - exploded.hour = 0; - exploded.minute = 0; - exploded.second = 0; - exploded.millisecond = 0; - Time out_time; - if (!Time::FromLocalExploded(exploded, &out_time)) { - // TODO(maksims): implement failure handling. - // We might just return |out_time|, which is Time(0). - NOTIMPLEMENTED(); - } - - return out_time; -} - // Returns the boundary value for comparing against the FieldTrial's added // groups for a given |divisor| (total probability) and |entropy_value|. FieldTrial::Probability GetGroupBoundaryValue( @@ -229,8 +201,6 @@ const int FieldTrial::kDefaultGroupNumber = 0; bool FieldTrial::enable_benchmarking_ = false; -int FieldTrialList::kNoExpirationYear = 0; - //------------------------------------------------------------------------------ // FieldTrial methods and members. @@ -448,8 +418,8 @@ } bool FieldTrial::GetStateWhileLocked(State* field_trial_state, - bool include_expired) { - if (!include_expired && !enable_field_trial_) + bool include_disabled) { + if (!include_disabled && !enable_field_trial_) return false; FinalizeGroupChoiceImpl(true); field_trial_state->trial_name = &trial_name_; @@ -477,11 +447,6 @@ DCHECK(!global_); DCHECK(!used_without_global_); global_ = this; - - Time two_years_from_build_time = GetBuildTime() + TimeDelta::FromDays(730); - Time::Exploded exploded; - two_years_from_build_time.LocalExplode(&exploded); - kNoExpirationYear = exploded.year; } FieldTrialList::~FieldTrialList() { @@ -500,14 +465,11 @@ const std::string& trial_name, FieldTrial::Probability total_probability, const std::string& default_group_name, - const int year, - const int month, - const int day_of_month, FieldTrial::RandomizationType randomization_type, int* default_group_number) { return FactoryGetFieldTrialWithRandomizationSeed( - trial_name, total_probability, default_group_name, year, month, - day_of_month, randomization_type, 0, default_group_number, nullptr); + trial_name, total_probability, default_group_name, randomization_type, 0, + default_group_number, nullptr); } // static @@ -515,9 +477,6 @@ const std::string& trial_name, FieldTrial::Probability total_probability, const std::string& default_group_name, - const int year, - const int month, - const int day_of_month, FieldTrial::RandomizationType randomization_type, uint32_t randomization_seed, int* default_group_number, @@ -570,8 +529,6 @@ FieldTrial* field_trial = new FieldTrial(trial_name, total_probability, default_group_name, entropy_value); - if (GetBuildTime() > CreateTimeFromParams(year, month, day_of_month)) - field_trial->Disable(); FieldTrialList::Register(field_trial); return field_trial; } @@ -630,14 +587,14 @@ // static void FieldTrialList::AllStatesToString(std::string* output, - bool include_expired) { + bool include_disabled) { if (!global_) return; AutoLock auto_lock(global_->lock_); for (const auto& registered : global_->registered_) { FieldTrial::State trial; - if (!registered.second->GetStateWhileLocked(&trial, include_expired)) + if (!registered.second->GetStateWhileLocked(&trial, include_disabled)) continue; DCHECK_EQ(std::string::npos, trial.trial_name->find(kPersistentStringSeparator)); @@ -653,14 +610,14 @@ } // static -std::string FieldTrialList::AllParamsToString(bool include_expired, +std::string FieldTrialList::AllParamsToString(bool include_disabled, EscapeDataFunc encode_data_func) { FieldTrialParamAssociator* params_associator = FieldTrialParamAssociator::GetInstance(); std::string output; for (const auto& registered : GetRegisteredTrials()) { FieldTrial::State trial; - if (!registered.second->GetStateWhileLocked(&trial, include_expired)) + if (!registered.second->GetStateWhileLocked(&trial, include_disabled)) continue; DCHECK_EQ(std::string::npos, trial.trial_name->find(kPersistentStringSeparator));
diff --git a/base/metrics/field_trial.h b/base/metrics/field_trial.h index 8e75a9a..5834115 100644 --- a/base/metrics/field_trial.h +++ b/base/metrics/field_trial.h
@@ -36,8 +36,8 @@ // // 8 July, 2015, and after that all instances will be in "StandardMem". // scoped_refptr<base::FieldTrial> trial( // base::FieldTrialList::FactoryGetFieldTrial( -// "MemoryExperiment", 1000, "StandardMem", 2015, 7, 8, -// base::FieldTrial::ONE_TIME_RANDOMIZED, NULL)); +// "MemoryExperiment", 1000, "StandardMem", +// base::FieldTrial::ONE_TIME_RANDOMIZED, nullptr)); // // const int high_mem_group = // trial->AppendGroup("HighMem", 20); // 2% in HighMem group. @@ -79,7 +79,6 @@ #include "base/process/launch.h" #include "base/strings/string_piece.h" #include "base/synchronization/lock.h" -#include "base/time/time.h" #include "build/build_config.h" #if defined(OS_MACOSX) && !defined(OS_IOS) @@ -324,12 +323,11 @@ // Returns the trial name and selected group name for this field trial via // the output parameter |field_trial_state| for all the studies when - // |bool include_expired| is true. In case when |bool include_expired| is - // false, if the trial has not been disabled true is returned and - // |field_trial_state| is filled in; otherwise, the result is false and - // |field_trial_state| is left untouched. - // This function is deadlock-free if the caller is holding a lock. - bool GetStateWhileLocked(State* field_trial_state, bool include_expired); + // |include_disabled| is true. In case when |include_disabled| is false, if + // the trial has not been disabled true is returned and |field_trial_state| + // is filled in; otherwise, the result is false and |field_trial_state| is + // left untouched. + bool GetStateWhileLocked(State* field_trial_state, bool include_disabled); // Returns the group_name. A winner need not have been chosen. std::string group_name_internal() const { return group_name_; } @@ -401,10 +399,6 @@ // special characters from |input|. typedef std::string (*EscapeDataFunc)(const std::string& input); - // Year that is guaranteed to not be expired when instantiating a field trial - // via |FactoryGetFieldTrial()|. Set to two years from the build date. - static int kNoExpirationYear; - // Observer is notified when a FieldTrial's group is selected. class BASE_EXPORT Observer { public: @@ -437,12 +431,10 @@ // |default_group_number| can receive the group number of the default group as // AppendGroup returns the number of the subsequence groups. |trial_name| and // |default_group_name| may not be empty but |default_group_number| can be - // NULL if the value is not needed. + // null if the value is not needed. // // Group probabilities that are later supplied must sum to less than or equal - // to the |total_probability|. Arguments |year|, |month| and |day_of_month| - // specify the expiration time. If the build time is after the expiration time - // then the field trial reverts to the 'default' group. + // to the |total_probability|. // // Use this static method to get a startup-randomized FieldTrial or a // previously created forced FieldTrial. @@ -450,9 +442,6 @@ const std::string& trial_name, FieldTrial::Probability total_probability, const std::string& default_group_name, - const int year, - const int month, - const int day_of_month, FieldTrial::RandomizationType randomization_type, int* default_group_number); @@ -471,9 +460,6 @@ const std::string& trial_name, FieldTrial::Probability total_probability, const std::string& default_group_name, - const int year, - const int month, - const int day_of_month, FieldTrial::RandomizationType randomization_type, uint32_t randomization_seed, int* default_group_number, @@ -515,20 +501,20 @@ // resurrection in another process. This allows randomization to be done in // one process, and secondary processes can be synchronized on the result. // The resulting string contains the name and group name pairs of all - // registered FieldTrials including disabled based on |include_expired|, + // registered FieldTrials including disabled based on |include_disabled|, // with "/" used to separate all names and to terminate the string. All // activated trials have their name prefixed with "*". This string is parsed // by |CreateTrialsFromString()|. - static void AllStatesToString(std::string* output, bool include_expired); + static void AllStatesToString(std::string* output, bool include_disabled); // Creates a persistent representation of all FieldTrial params for // resurrection in another process. The returned string contains the trial // name and group name pairs of all registered FieldTrials including disabled - // based on |include_expired| separated by '.'. The pair is followed by ':' + // based on |include_disabled| separated by '.'. The pair is followed by ':' // separator and list of param name and values separated by '/'. It also takes // |encode_data_func| function pointer for encodeing special charactors. // This string is parsed by |AssociateParamsFromString()|. - static std::string AllParamsToString(bool include_expired, + static std::string AllParamsToString(bool include_disabled, EscapeDataFunc encode_data_func); // Fills in the supplied vector |active_groups| (which must be empty when
diff --git a/base/metrics/field_trial_params_unittest.cc b/base/metrics/field_trial_params_unittest.cc index d310c0d4..007e9d0 100644 --- a/base/metrics/field_trial_params_unittest.cc +++ b/base/metrics/field_trial_params_unittest.cc
@@ -15,7 +15,7 @@ namespace { -// Call FieldTrialList::FactoryGetFieldTrial() with a future expiry date. +// Call FieldTrialList::FactoryGetFieldTrial(). scoped_refptr<FieldTrial> CreateFieldTrial( const std::string& trial_name, int total_probability, @@ -23,8 +23,7 @@ int* default_group_number) { return FieldTrialList::FactoryGetFieldTrial( trial_name, total_probability, default_group_name, - FieldTrialList::kNoExpirationYear, 1, 1, FieldTrial::SESSION_RANDOMIZED, - default_group_number); + FieldTrial::SESSION_RANDOMIZED, default_group_number); } } // namespace
diff --git a/base/metrics/field_trial_unittest.cc b/base/metrics/field_trial_unittest.cc index dec567a1..c542bcf 100644 --- a/base/metrics/field_trial_unittest.cc +++ b/base/metrics/field_trial_unittest.cc
@@ -43,7 +43,7 @@ // Default group name used by several tests. const char kDefaultGroupName[] = "DefaultGroup"; -// Call FieldTrialList::FactoryGetFieldTrial() with a future expiry date. +// Call FieldTrialList::FactoryGetFieldTrial(). scoped_refptr<FieldTrial> CreateFieldTrial( const std::string& trial_name, int total_probability, @@ -51,15 +51,7 @@ int* default_group_number) { return FieldTrialList::FactoryGetFieldTrial( trial_name, total_probability, default_group_name, - FieldTrialList::kNoExpirationYear, 1, 1, FieldTrial::SESSION_RANDOMIZED, - default_group_number); -} - -int OneYearBeforeBuildTime() { - Time one_year_before_build_time = GetBuildTime() - TimeDelta::FromDays(365); - Time::Exploded exploded; - one_year_before_build_time.LocalExplode(&exploded); - return exploded.year; + FieldTrial::SESSION_RANDOMIZED, default_group_number); } // FieldTrialList::Observer implementation for testing. @@ -290,12 +282,12 @@ const std::string loser = "Loser"; const std::string name = "Trial"; - // Create a field trail that has expired. + // Create a field trail that is disabled. int default_group_number = -1; FieldTrial* trial = FieldTrialList::FactoryGetFieldTrial( - name, 1000000000, default_group_name, OneYearBeforeBuildTime(), 1, 1, - FieldTrial::SESSION_RANDOMIZED, + name, 1000000000, default_group_name, FieldTrial::SESSION_RANDOMIZED, &default_group_number); + trial->Disable(); trial->AppendGroup(loser, 999999999); // 99.9999999% chance of being chosen. // Because trial has expired, we should always be in the default group. @@ -506,14 +498,14 @@ EXPECT_EQ("Some name/Default some name/*trial2/Winner/*xxx/yyyy/zzz/default/", save_string); - // Create expired study. + // Create disabled study. int default_group_number = -1; - scoped_refptr<FieldTrial> expired_trial = + scoped_refptr<FieldTrial> disabled_trial = FieldTrialList::FactoryGetFieldTrial( - "Expired trial name", 1000000000, "Default group", - OneYearBeforeBuildTime(), 1, 1, FieldTrial::SESSION_RANDOMIZED, - &default_group_number); - expired_trial->AppendGroup("Expired trial group name", 999999999); + "Disabled trial name", 1000000000, "Default group", + FieldTrial::SESSION_RANDOMIZED, &default_group_number); + disabled_trial->AppendGroup("Disabled trial group name", 999999999); + disabled_trial->Disable(); save_string.clear(); FieldTrialList::AllStatesToString(&save_string, false); @@ -522,7 +514,7 @@ save_string.clear(); FieldTrialList::AllStatesToString(&save_string, true); EXPECT_EQ( - "Expired trial name/Default group/" + "Disabled trial name/Default group/" "Some name/Default some name/*trial2/Winner/*xxx/yyyy/zzz/default/", save_string); } @@ -1053,8 +1045,8 @@ EXPECT_TRUE(states.empty()); } -TEST_F(FieldTrialTest, ExpirationYearNotExpired) { - const char kTrialName[] = "NotExpired"; +TEST_F(FieldTrialTest, NotDisabled) { + const char kTrialName[] = "NotDisabled"; const char kGroupName[] = "Group2"; const int kProbability = 100; ASSERT_FALSE(FieldTrialList::TrialExists(kTrialName)); @@ -1178,7 +1170,6 @@ EXPECT_DEATH_IF_SUPPORTED( FieldTrialList::FactoryGetFieldTrial( "OneTimeRandomizedTrialWithoutFieldTrialList", 100, kDefaultGroupName, - FieldTrialList::kNoExpirationYear, 1, 1, FieldTrial::ONE_TIME_RANDOMIZED, nullptr), ""); }
diff --git a/base/task/post_task.cc b/base/task/post_task.cc index af810c9a..744eea2 100644 --- a/base/task/post_task.cc +++ b/base/task/post_task.cc
@@ -32,11 +32,10 @@ }; // Returns TaskTraits based on |traits|. If TaskPriority hasn't been set -// explicitly in |traits|, the returned TaskTraits have the current +// explicitly in |traits|, the returned TaskTraits will inherit the current // TaskPriority. TaskTraits GetTaskTraitsWithExplicitPriority(TaskTraits traits) { - if (!traits.priority_set_explicitly()) - traits.UpdatePriority(internal::GetTaskPriorityForCurrentThread()); + traits.InheritPriority(internal::GetTaskPriorityForCurrentThread()); return traits; }
diff --git a/base/task/post_task_unittest.cc b/base/task/post_task_unittest.cc index 796b6848..a152d992 100644 --- a/base/task/post_task_unittest.cc +++ b/base/task/post_task_unittest.cc
@@ -5,6 +5,7 @@ #include "base/task/post_task.h" #include "base/bind_helpers.h" +#include "base/task/scoped_set_task_priority_for_current_thread.h" #include "base/task/task_executor.h" #include "base/task/test_task_traits_extension.h" #include "base/test/gtest_util.h" @@ -122,10 +123,7 @@ // Tasks with extension should go to the executor. { TaskTraits traits = {TestExtensionBoolTrait()}; - TaskTraits traits_with_explicit_priority = traits; - traits_with_explicit_priority.UpdatePriority(TaskPriority::USER_VISIBLE); - EXPECT_CALL(executor_, PostDelayedTaskWithTraitsMock( - _, traits_with_explicit_priority, _, _)) + EXPECT_CALL(executor_, PostDelayedTaskWithTraitsMock(_, traits, _, _)) .Times(1); EXPECT_TRUE(PostTaskWithTraits(FROM_HERE, traits, DoNothing())); EXPECT_TRUE(executor_.runner()->HasPendingTask()); @@ -134,10 +132,7 @@ { TaskTraits traits = {MayBlock(), TestExtensionBoolTrait()}; - TaskTraits traits_with_explicit_priority = traits; - traits_with_explicit_priority.UpdatePriority(TaskPriority::USER_VISIBLE); - EXPECT_CALL(executor_, PostDelayedTaskWithTraitsMock( - _, traits_with_explicit_priority, _, _)) + EXPECT_CALL(executor_, PostDelayedTaskWithTraitsMock(_, traits, _, _)) .Times(1); EXPECT_TRUE(PostTaskWithTraits(FROM_HERE, traits, DoNothing())); EXPECT_TRUE(executor_.runner()->HasPendingTask()); @@ -146,10 +141,7 @@ { TaskTraits traits = {TestExtensionEnumTrait::kB, TestExtensionBoolTrait()}; - TaskTraits traits_with_explicit_priority = traits; - traits_with_explicit_priority.UpdatePriority(TaskPriority::USER_VISIBLE); - EXPECT_CALL(executor_, PostDelayedTaskWithTraitsMock( - _, traits_with_explicit_priority, _, _)) + EXPECT_CALL(executor_, PostDelayedTaskWithTraitsMock(_, traits, _, _)) .Times(1); EXPECT_TRUE(PostTaskWithTraits(FROM_HERE, traits, DoNothing())); EXPECT_TRUE(executor_.runner()->HasPendingTask()); @@ -159,27 +151,20 @@ // Task runners with extension should be the executor's. { TaskTraits traits = {TestExtensionBoolTrait()}; - TaskTraits traits_with_explicit_priority = traits; - traits_with_explicit_priority.UpdatePriority(TaskPriority::USER_VISIBLE); - EXPECT_CALL(executor_, - CreateTaskRunnerWithTraits(traits_with_explicit_priority)) - .Times(1); + EXPECT_CALL(executor_, CreateTaskRunnerWithTraits(traits)).Times(1); auto task_runner = CreateTaskRunnerWithTraits(traits); EXPECT_EQ(executor_.runner(), task_runner); - EXPECT_CALL(executor_, CreateSequencedTaskRunnerWithTraits( - traits_with_explicit_priority)) + EXPECT_CALL(executor_, CreateSequencedTaskRunnerWithTraits(traits)) .Times(1); auto sequenced_task_runner = CreateSequencedTaskRunnerWithTraits(traits); EXPECT_EQ(executor_.runner(), sequenced_task_runner); - EXPECT_CALL(executor_, CreateSingleThreadTaskRunnerWithTraits( - traits_with_explicit_priority, _)) + EXPECT_CALL(executor_, CreateSingleThreadTaskRunnerWithTraits(traits, _)) .Times(1); auto single_thread_task_runner = CreateSingleThreadTaskRunnerWithTraits(traits); EXPECT_EQ(executor_.runner(), single_thread_task_runner); #if defined(OS_WIN) - EXPECT_CALL(executor_, CreateCOMSTATaskRunnerWithTraits( - traits_with_explicit_priority, _)) + EXPECT_CALL(executor_, CreateCOMSTATaskRunnerWithTraits(traits, _)) .Times(1); auto comsta_task_runner = CreateCOMSTATaskRunnerWithTraits(traits); EXPECT_EQ(executor_.runner(), comsta_task_runner); @@ -193,4 +178,18 @@ RegisterTaskExecutor(TestTaskTraitsExtension::kExtensionId, &executor_)); } +TEST_F(PostTaskTestWithExecutor, PriorityInherited) { + internal::ScopedSetTaskPriorityForCurrentThread scoped_priority( + TaskPriority::BEST_EFFORT); + TaskTraits traits = {TestExtensionBoolTrait()}; + TaskTraits traits_with_inherited_priority = traits; + traits_with_inherited_priority.InheritPriority(TaskPriority::BEST_EFFORT); + EXPECT_CALL(executor_, PostDelayedTaskWithTraitsMock( + _, traits_with_inherited_priority, _, _)) + .Times(1); + EXPECT_TRUE(PostTaskWithTraits(FROM_HERE, traits, DoNothing())); + EXPECT_TRUE(executor_.runner()->HasPendingTask()); + executor_.runner()->ClearPendingTasks(); +} + } // namespace base
diff --git a/base/task/task_traits.h b/base/task/task_traits.h index a3621699..d893a2a 100644 --- a/base/task/task_traits.h +++ b/base/task/task_traits.h
@@ -227,6 +227,13 @@ priority_set_explicitly_ = true; } + // Sets the priority to |priority| if it wasn't explicitly set before. + void InheritPriority(TaskPriority priority) { + if (priority_set_explicitly_) + return; + priority_ = priority; + } + // Returns true if the priority was set explicitly. constexpr bool priority_set_explicitly() const { return priority_set_explicitly_;
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 2df3a4b..10c3dcbc 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -8912170263713353808 \ No newline at end of file +8912145958322470880 \ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 56371b1..83c4b4d 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -8912173536394146880 \ No newline at end of file +8912143166642018320 \ No newline at end of file
diff --git a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_form_counter_input.xml b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_form_counter_input.xml index 1011a9d..4e4ebe4 100644 --- a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_form_counter_input.xml +++ b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_form_counter_input.xml
@@ -15,7 +15,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="4dp" - android:textAppearance="@style/TextAppearance.BlackTitle2"/> + android:textAppearance="@style/TextAppearance.BlackButtonText"/> <LinearLayout android:id="@+id/expand_label_container" android:layout_width="match_parent"
diff --git a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_form_selection_input.xml b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_form_selection_input.xml index db97496..1037d60 100644 --- a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_form_selection_input.xml +++ b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_form_selection_input.xml
@@ -14,7 +14,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="4dp" - android:textAppearance="@style/TextAppearance.BlackTitle2"/> + android:textAppearance="@style/TextAppearance.BlackButtonText"/> <org.chromium.chrome.browser.autofill_assistant.payment.AssistantChoiceList android:id="@+id/choice_list"
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/form/AssistantFormSelectionInput.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/form/AssistantFormSelectionInput.java index 8285484..8e4d88c 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/form/AssistantFormSelectionInput.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/form/AssistantFormSelectionInput.java
@@ -52,10 +52,9 @@ for (int i = 0; i < mChoices.size(); i++) { AssistantFormSelectionChoice choice = mChoices.get(i); - // Set the same style as Payment Request T&C. TextView choiceView = new TextView(context); ApiCompatibilityUtils.setTextAppearance( - choiceView, org.chromium.chrome.R.style.TextAppearance_BlackCaption); + choiceView, org.chromium.chrome.R.style.TextAppearance_BlackCaptionDefault); choiceView.setText(choice.getLabel()); int index = i; // needed for the lambda.
diff --git a/chrome/android/features/keyboard_accessory/BUILD.gn b/chrome/android/features/keyboard_accessory/BUILD.gn index 211f4274..a33f1ff5 100644 --- a/chrome/android/features/keyboard_accessory/BUILD.gn +++ b/chrome/android/features/keyboard_accessory/BUILD.gn
@@ -41,6 +41,7 @@ "javatests/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryModernViewTest.java", "javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_component/AccessorySheetViewTest.java", "javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessorySheetViewTest.java", + "javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessoryIntegrationTest.java", "javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessoryIntegrationTest.java", "javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetViewTest.java", "javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewTest.java",
diff --git a/chrome/android/features/keyboard_accessory/internal/java/res/layout/address_accessory_sheet.xml b/chrome/android/features/keyboard_accessory/internal/java/res/layout/address_accessory_sheet.xml index 6309f7eb..61ad525 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/res/layout/address_accessory_sheet.xml +++ b/chrome/android/features/keyboard_accessory/internal/java/res/layout/address_accessory_sheet.xml
@@ -5,6 +5,7 @@ <android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/addresses_sheet" android:fillViewport="true" android:layout_height="match_parent" android:layout_width="match_parent"
diff --git a/chrome/android/features/keyboard_accessory/internal/java/res/layout/password_accessory_sheet.xml b/chrome/android/features/keyboard_accessory/internal/java/res/layout/password_accessory_sheet.xml index fc8c4ac..a8964ec 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/res/layout/password_accessory_sheet.xml +++ b/chrome/android/features/keyboard_accessory/internal/java/res/layout/password_accessory_sheet.xml
@@ -5,6 +5,7 @@ <android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/passwords_sheet" android:fillViewport="true" android:layout_height="match_parent" android:layout_width="match_parent"
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingComponentBridge.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingComponentBridge.java index 6ffcc0f..1e0b4cf1 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingComponentBridge.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingComponentBridge.java
@@ -21,7 +21,9 @@ import org.chromium.ui.base.WindowAndroid; class ManualFillingComponentBridge { - private final PropertyProvider<AccessorySheetData> mSheetDataProvider = + private final PropertyProvider<AccessorySheetData> mPasswordSheetProvider = + new PropertyProvider<>(); + private final PropertyProvider<AccessorySheetData> mAddressSheetProvider = new PropertyProvider<>(); private final PropertyProvider<Action[]> mActionProvider = new PropertyProvider<>(AccessoryAction.GENERATE_PASSWORD_AUTOMATIC); @@ -33,7 +35,8 @@ mNativeView = nativeView; mActivity = (ChromeActivity) windowAndroid.getActivity().get(); mManualFillingComponent = mActivity.getManualFillingComponent(); - mManualFillingComponent.registerPasswordProvider(mSheetDataProvider); + mManualFillingComponent.registerPasswordProvider(mPasswordSheetProvider); + mManualFillingComponent.registerAddressProvider(mAddressSheetProvider); mManualFillingComponent.registerCreditCardProvider(); mManualFillingComponent.registerActionProvider(mActionProvider); } @@ -49,13 +52,13 @@ AccessorySheetData accessorySheetData = (AccessorySheetData) objAccessorySheetData; switch (accessorySheetData.getSheetType()) { case AccessoryTabType.PASSWORDS: - mSheetDataProvider.notifyObservers(accessorySheetData); + mPasswordSheetProvider.notifyObservers((AccessorySheetData) objAccessorySheetData); return; case AccessoryTabType.CREDIT_CARDS: // TODO(crbug.com/926365): Implement. return; case AccessoryTabType.ADDRESSES: - // TODO(crbug.com/962548): Implement. + mAddressSheetProvider.notifyObservers((AccessorySheetData) objAccessorySheetData); return; } } @@ -114,7 +117,8 @@ @CalledByNative private void destroy() { - mSheetDataProvider.notifyObservers(null); + mPasswordSheetProvider.notifyObservers(null); + mAddressSheetProvider.notifyObservers(null); mNativeView = 0; }
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingCoordinator.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingCoordinator.java index 11d4c9a6..babe071 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingCoordinator.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingCoordinator.java
@@ -94,6 +94,12 @@ } @Override + public void registerAddressProvider( + PropertyProvider<KeyboardAccessoryData.AccessorySheetData> sheetDataProvider) { + mMediator.registerAddressProvider(sheetDataProvider); + } + + @Override public void registerCreditCardProvider() { mMediator.registerCreditCardProvider(); }
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMediator.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMediator.java index d0eec850..5a4f5a5 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMediator.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMediator.java
@@ -41,6 +41,7 @@ import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData.Action; import org.chromium.chrome.browser.keyboard_accessory.data.PropertyProvider; import org.chromium.chrome.browser.keyboard_accessory.sheet_component.AccessorySheetCoordinator; +import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AddressAccessorySheetCoordinator; import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.CreditCardAccessorySheetCoordinator; import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.PasswordAccessorySheetCoordinator; import org.chromium.chrome.browser.tab.EmptyTabObserver; @@ -200,6 +201,16 @@ accessorySheet.registerDataProvider(state.getPasswordSheetDataProvider()); } + void registerAddressProvider( + PropertyProvider<KeyboardAccessoryData.AccessorySheetData> dataProvider) { + ManualFillingState state = mStateCache.getStateFor(mActivity.getCurrentWebContents()); + + state.wrapAddressSheetDataProvider(dataProvider); + AddressAccessorySheetCoordinator accessorySheet = getOrCreateAddressSheet(); + if (accessorySheet == null) return; // Not available or initialized yet. + accessorySheet.registerDataProvider(state.getAddressSheetDataProvider()); + } + void registerCreditCardProvider() { CreditCardAccessorySheetCoordinator accessorySheet = getOrCreateCreditCardSheet(); if (accessorySheet == null) return; @@ -612,6 +623,32 @@ } /** + * Returns the address sheet for the current WebContents or creates one if it doesn't exist. + * @return A {@link AddressAccessorySheetCoordinator} or null if unavailable. + */ + @VisibleForTesting + @Nullable + AddressAccessorySheetCoordinator getOrCreateAddressSheet() { + if (!isInitialized()) return null; + if (!ChromeFeatureList.isEnabled(ChromeFeatureList.AUTOFILL_KEYBOARD_ACCESSORY)) { + return null; + } + WebContents webContents = mActivity.getCurrentWebContents(); + if (webContents == null) return null; // There is no active tab or it's being destroyed. + ManualFillingState state = mStateCache.getStateFor(webContents); + if (state.getAddressAccessorySheet() != null) return state.getAddressAccessorySheet(); + + AddressAccessorySheetCoordinator addressSheet = new AddressAccessorySheetCoordinator( + mActivity, mAccessorySheet.getScrollListener()); + state.setAddressAccessorySheet(addressSheet); + if (state.getAddressSheetDataProvider() != null) { + addressSheet.registerDataProvider(state.getAddressSheetDataProvider()); + } + refreshTabs(); + return addressSheet; + } + + /** * Returns the credit card sheet for the current WebContents or creates one if it doesn't exist. * @return A {@link CreditCardAccessorySheetCoordinator} or null if unavailable. */
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingState.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingState.java index f1cd6046..6f32bd85 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingState.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingState.java
@@ -12,6 +12,7 @@ import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData.AccessorySheetData; import org.chromium.chrome.browser.keyboard_accessory.data.PropertyProvider; import org.chromium.chrome.browser.keyboard_accessory.data.Provider; +import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AddressAccessorySheetCoordinator; import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.CreditCardAccessorySheetCoordinator; import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.PasswordAccessorySheetCoordinator; import org.chromium.content_public.browser.WebContents; @@ -28,7 +29,9 @@ private boolean mWebContentsShowing; private @Nullable CachedProviderAdapter<KeyboardAccessoryData.Action[]> mActionsProvider; private @Nullable CachedProviderAdapter<AccessorySheetData> mPasswordSheetDataProvider; + private @Nullable CachedProviderAdapter<AccessorySheetData> mAddressSheetDataProvider; private @Nullable PasswordAccessorySheetCoordinator mPasswordAccessorySheet; + private @Nullable AddressAccessorySheetCoordinator mAddressAccessorySheet; private @Nullable CreditCardAccessorySheetCoordinator mCreditCardAccessorySheet; private class Observer extends WebContentsObserver { @@ -82,6 +85,7 @@ ArrayList<KeyboardAccessoryData.Tab> tabs = new ArrayList<>(); if (mPasswordAccessorySheet != null) tabs.add(mPasswordAccessorySheet.getTab()); if (mCreditCardAccessorySheet != null) tabs.add(mCreditCardAccessorySheet.getTab()); + if (mAddressAccessorySheet != null) tabs.add(mAddressAccessorySheet.getTab()); return tabs.toArray(new KeyboardAccessoryData.Tab[0]); } @@ -91,6 +95,7 @@ mPasswordSheetDataProvider = null; mPasswordAccessorySheet = null; mCreditCardAccessorySheet = null; + mAddressAccessorySheet = null; mWebContentsShowing = false; } @@ -139,6 +144,32 @@ return mPasswordAccessorySheet; } + /** + * Wraps the given provider for address data in a {@link CachedProviderAdapter} and stores it. + * @param provider A {@link PropertyProvider} providing password sheet data. + */ + void wrapAddressSheetDataProvider(PropertyProvider<AccessorySheetData> provider) { + mAddressSheetDataProvider = + new CachedProviderAdapter<>(provider, null, this::onAdapterReceivedNewData); + } + + /** + * Returns the wrapped provider set with {@link #wrapAddressSheetDataProvider}. + * @return A {@link CachedProviderAdapter} wrapping a {@link PropertyProvider}. + */ + Provider<AccessorySheetData> getAddressSheetDataProvider() { + return mAddressSheetDataProvider; + } + + void setAddressAccessorySheet(@Nullable AddressAccessorySheetCoordinator sheet) { + mAddressAccessorySheet = sheet; + } + + @Nullable + AddressAccessorySheetCoordinator getAddressAccessorySheet() { + return mAddressAccessorySheet; + } + void setCreditCardAccessorySheet(@Nullable CreditCardAccessorySheetCoordinator sheet) { mCreditCardAccessorySheet = sheet; }
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingTestHelper.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingTestHelper.java index 8ea0030..1ee83f4 100644 --- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingTestHelper.java +++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingTestHelper.java
@@ -44,6 +44,7 @@ import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData; import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData.AccessorySheetData; import org.chromium.chrome.browser.keyboard_accessory.data.PropertyProvider; +import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AddressAccessorySheetCoordinator; import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.PasswordAccessorySheetCoordinator; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.content_public.browser.ImeAdapter; @@ -148,6 +149,10 @@ return DOMUtils.getNodeValue(mWebContentsRef.get(), PASSWORD_NODE_ID); } + public String getFieldText(String nodeId) throws TimeoutException, InterruptedException { + return DOMUtils.getNodeValue(mWebContentsRef.get(), nodeId); + } + public void clickEmailField(boolean forceAccessory) throws TimeoutException, InterruptedException { // TODO(fhorschig): This should be |focusNode|. Change with autofill popup deprecation. @@ -252,6 +257,10 @@ return getManualFillingCoordinator().getMediatorForTesting().getOrCreatePasswordSheet(); } + public AddressAccessorySheetCoordinator getOrCreateAddressAccessorySheet() { + return getManualFillingCoordinator().getMediatorForTesting().getOrCreateAddressSheet(); + } + // ---------------------------------- // Helpers to set up the native side. // ----------------------------------
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingUiCaptureTest.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingUiCaptureTest.java index 477dea6..17d2489 100644 --- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingUiCaptureTest.java +++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingUiCaptureTest.java
@@ -8,7 +8,6 @@ import static android.support.test.espresso.contrib.RecyclerViewActions.actionOnItem; import static android.support.test.espresso.contrib.RecyclerViewActions.scrollTo; import static android.support.test.espresso.matcher.ViewMatchers.withId; -import static android.support.test.espresso.matcher.ViewMatchers.withParent; import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout; import static org.chromium.chrome.browser.keyboard_accessory.ManualFillingTestHelper.scrollToLastElement; @@ -86,8 +85,7 @@ waitForUnrelatedChromeUi(); mScreenShooter.shoot("AccessorySheetPasswords"); - whenDisplayed(withParent(withId(R.id.keyboard_accessory_sheet))) - .perform(scrollToLastElement()); + whenDisplayed(withId(R.id.passwords_sheet)).perform(scrollToLastElement()); waitForUnrelatedChromeUi(); mScreenShooter.shoot("AccessorySheetPasswordsScrolled"); } @@ -113,8 +111,7 @@ waitForUnrelatedChromeUi(); mScreenShooter.shoot("AccessorySheetPasswordsRTL"); - whenDisplayed(withParent(withId(R.id.keyboard_accessory_sheet))) - .perform(scrollToLastElement()); + whenDisplayed(withId(R.id.passwords_sheet)).perform(scrollToLastElement()); waitForUnrelatedChromeUi(); mScreenShooter.shoot("AccessorySheetPasswordsScrolledRTL"); } @@ -144,8 +141,7 @@ waitForUnrelatedChromeUi(); mScreenShooter.shoot("AccessorySheetPasswordsV2"); - whenDisplayed(withParent(withId(R.id.keyboard_accessory_sheet))) - .perform(scrollToLastElement()); + whenDisplayed(withId(R.id.passwords_sheet)).perform(scrollToLastElement()); waitForUnrelatedChromeUi(); mScreenShooter.shoot("AccessorySheetPasswordsV2Scrolled"); } @@ -175,8 +171,7 @@ waitForUnrelatedChromeUi(); mScreenShooter.shoot("AccessorySheetPasswordsV2RTL"); - whenDisplayed(withParent(withId(R.id.keyboard_accessory_sheet))) - .perform(scrollToLastElement()); + whenDisplayed(withId(R.id.passwords_sheet)).perform(scrollToLastElement()); waitForUnrelatedChromeUi(); mScreenShooter.shoot("AccessorySheetPasswordsV2ScrolledRTL"); } @@ -195,7 +190,7 @@ private void waitForSuggestionsInSheet() { whenDisplayed(withId(R.id.keyboard_accessory_sheet)); - onView(withParent(withId(R.id.keyboard_accessory_sheet))).check((view, noViewFound) -> { + onView(withId(R.id.passwords_sheet)).check((view, noViewFound) -> { if (noViewFound != null) throw noViewFound; RecyclerViewTestUtils.waitForStableRecyclerView((RecyclerView) view); });
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessoryIntegrationTest.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessoryIntegrationTest.java new file mode 100644 index 0000000..2ebb4ef0 --- /dev/null +++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessoryIntegrationTest.java
@@ -0,0 +1,149 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.keyboard_accessory.sheet_tabs; + +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.action.ViewActions.click; +import static android.support.test.espresso.assertion.ViewAssertions.matches; +import static android.support.test.espresso.contrib.RecyclerViewActions.actionOnItem; +import static android.support.test.espresso.contrib.RecyclerViewActions.scrollTo; +import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.withContentDescription; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static android.support.test.espresso.matcher.ViewMatchers.withText; + +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.not; + +import static org.chromium.chrome.browser.keyboard_accessory.ManualFillingTestHelper.selectTabAtPosition; +import static org.chromium.chrome.browser.keyboard_accessory.ManualFillingTestHelper.whenDisplayed; +import static org.chromium.chrome.browser.keyboard_accessory.tab_layout_component.KeyboardAccessoryTabTestHelper.isKeyboardAccessoryTabLayout; + +import android.support.test.filters.MediumTest; +import android.support.test.filters.SmallTest; +import android.widget.TextView; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.RetryOnFailure; +import org.chromium.chrome.browser.ChromeFeatureList; +import org.chromium.chrome.browser.ChromeSwitches; +import org.chromium.chrome.browser.ChromeWindow; +import org.chromium.chrome.browser.autofill.AutofillTestHelper; +import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; +import org.chromium.chrome.browser.keyboard_accessory.FakeKeyboard; +import org.chromium.chrome.browser.keyboard_accessory.ManualFillingTestHelper; +import org.chromium.chrome.browser.keyboard_accessory.R; +import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.chrome.test.ChromeTabbedActivityTestRule; +import org.chromium.chrome.test.util.browser.Features.DisableFeatures; +import org.chromium.chrome.test.util.browser.Features.EnableFeatures; +import org.chromium.content_public.browser.test.util.CriteriaHelper; +import org.chromium.content_public.browser.test.util.DOMUtils; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; + +/** + * Integration tests for address accessory views. + */ +@RunWith(ChromeJUnit4ClassRunner.class) +@RetryOnFailure +@EnableFeatures({ChromeFeatureList.PASSWORDS_KEYBOARD_ACCESSORY}) +@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) +public class AddressAccessoryIntegrationTest { + @Rule + public final ChromeTabbedActivityTestRule mActivityTestRule = + new ChromeTabbedActivityTestRule(); + + private final ManualFillingTestHelper mHelper = new ManualFillingTestHelper(mActivityTestRule); + + @After + public void tearDown() { + mHelper.clear(); + } + + private void loadTestPage(ChromeWindow.KeyboardVisibilityDelegateFactory keyboardDelegate) + throws InterruptedException, TimeoutException { + mHelper.loadTestPage("/chrome/test/data/autofill/autofill_test_form.html", false, false, + keyboardDelegate); + new AutofillTestHelper().setProfile(new AutofillProfile("", "https://www.example.com", + "Marcus McSpartangregor", "Acme Inc", "1 Main\nApt A", "CA", "San Francisco", "", + "94102", "", "US", "(415) 999-0000", "marc@acme-mail.inc", "en")); + DOMUtils.waitForNonZeroNodeBounds(mHelper.getWebContents(), "NAME_FIRST"); + } + + @Test + @SmallTest + @EnableFeatures({ChromeFeatureList.AUTOFILL_KEYBOARD_ACCESSORY}) + public void testAddressSheetIsAvailable() throws InterruptedException { + mHelper.loadTestPage(false); + + CriteriaHelper.pollUiThread(() -> { + return mHelper.getOrCreateAddressAccessorySheet() != null; + }, "Address sheet should be bound to accessory sheet."); + } + + @Test + @SmallTest + @DisableFeatures({ChromeFeatureList.AUTOFILL_KEYBOARD_ACCESSORY}) + public void testAddressSheetUnavailableWithoutFeature() throws InterruptedException { + mHelper.loadTestPage(false); + + Assert.assertNull("Address sheet should not have been created.", + mHelper.getOrCreateAddressAccessorySheet()); + } + + @Test + @SmallTest + @EnableFeatures({ChromeFeatureList.AUTOFILL_KEYBOARD_ACCESSORY}) + public void testDisplaysEmptyStateMessageWithoutSavedPasswords() + throws InterruptedException, TimeoutException { + mHelper.loadTestPage(false); + + // Focus the field to bring up the accessory. + mHelper.focusPasswordField(); + mHelper.waitForKeyboardAccessoryToBeShown(); + + // Click the tab to show the sheet and hide the keyboard. + whenDisplayed(allOf(withContentDescription(R.string.address_accessory_sheet_toggle), + not(isAssignableFrom(TextView.class)))) + .perform(click()); + mHelper.waitForKeyboardToDisappear(); + whenDisplayed(withId(R.id.addresses_sheet)); + onView(withText(containsString("No saved addresses"))).check(matches(isDisplayed())); + } + + @Test + @MediumTest + @EnableFeatures({ChromeFeatureList.AUTOFILL_KEYBOARD_ACCESSORY}) + public void testFillsSuggestionOnClick() + throws ExecutionException, InterruptedException, TimeoutException { + loadTestPage(FakeKeyboard::new); + mHelper.clickNodeAndShowKeyboard("NAME_FIRST"); + mHelper.waitForKeyboardAccessoryToBeShown(); + + // Scroll to last element and click the second icon: + whenDisplayed(withId(R.id.bar_items_view)) + .perform(scrollTo(isKeyboardAccessoryTabLayout()), + actionOnItem(isKeyboardAccessoryTabLayout(), selectTabAtPosition(1))); + + // Wait for the sheet to come up and be stable. + whenDisplayed(withId(R.id.addresses_sheet)); + + // Click a suggestion. + whenDisplayed(withText("McSpartangregor")).perform(click()); + + CriteriaHelper.pollInstrumentationThread( + () -> { return mHelper.getFieldText("NAME_FIRST").equals("McSpartangregor"); }); + } +}
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessoryIntegrationTest.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessoryIntegrationTest.java index e66e707..3d3a5eb 100644 --- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessoryIntegrationTest.java +++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessoryIntegrationTest.java
@@ -41,9 +41,7 @@ import java.util.concurrent.TimeoutException; /** - * Integration tests for password accessory views. This integration test currently stops testing at - * the bridge - ideally, there should be an easy way to add a temporary account with temporary - * passwords. + * Integration tests for password accessory views. */ @RunWith(ChromeJUnit4ClassRunner.class) @RetryOnFailure @@ -66,9 +64,9 @@ public void testPasswordSheetIsAvailable() throws InterruptedException { mHelper.loadTestPage(false); - CriteriaHelper.pollUiThread(() - -> mHelper.getOrCreatePasswordAccessorySheet() != null, - "Password Sheet should be bound to accessory sheet."); + CriteriaHelper.pollUiThread(() -> { + return mHelper.getOrCreatePasswordAccessorySheet() != null; + }, " Password Sheet should be bound to accessory sheet."); } @Test @@ -112,7 +110,7 @@ whenDisplayed(withId(R.id.tabs)).perform(selectTabAtPosition(0)); mHelper.waitForKeyboardToDisappear(); - whenDisplayed(withId(R.id.keyboard_accessory_sheet)); + whenDisplayed(withId(R.id.passwords_sheet)); onView(withText(containsString("Manage password"))).check(matches(isDisplayed())); } @@ -151,7 +149,7 @@ // Click the tab to show the sheet and hide the keyboard. whenDisplayed(withId(R.id.tabs)).perform(selectTabAtPosition(0)); mHelper.waitForKeyboardToDisappear(); - whenDisplayed(withId(R.id.keyboard_accessory_sheet)); + whenDisplayed(withId(R.id.passwords_sheet)); onView(withText(containsString("No saved passwords"))).check(matches(isDisplayed())); } }
diff --git a/chrome/android/features/keyboard_accessory/public/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingComponent.java b/chrome/android/features/keyboard_accessory/public/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingComponent.java index 44d9fd00..9c6c606 100644 --- a/chrome/android/features/keyboard_accessory/public/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingComponent.java +++ b/chrome/android/features/keyboard_accessory/public/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingComponent.java
@@ -61,6 +61,14 @@ PropertyProvider<KeyboardAccessoryData.AccessorySheetData> sheetDataProvider); /** + * By registering this provider, an empty tab for addresses is created. Call + * {@link PropertyProvider#notifyObservers(Object)} to fill or update the sheet. + * @param sheetDataProvider The {@link PropertyProvider} the tab will get it's data from. + */ + void registerAddressProvider( + PropertyProvider<KeyboardAccessoryData.AccessorySheetData> sheetDataProvider); + + /** * By calling this function, an empty tab for credit cards is created. */ void registerCreditCardProvider();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/permissions/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/permissions/OWNERS index 05c118d..25e782b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/permissions/OWNERS +++ b/chrome/android/java/src/org/chromium/chrome/browser/permissions/OWNERS
@@ -1,3 +1,4 @@ dominickn@chromium.org +engedy@chromium.org # COMPONENT: UI>Browser>Permissions>Prompts
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabFromChromeExternalNavigationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabFromChromeExternalNavigationTest.java index bdd44f1b..7db207e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabFromChromeExternalNavigationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabFromChromeExternalNavigationTest.java
@@ -4,19 +4,15 @@ package org.chromium.chrome.browser.customtabs; -import android.app.Activity; import android.content.Intent; import android.net.Uri; -import android.os.Build; import android.support.test.InstrumentationRegistry; import android.support.test.filters.LargeTest; import android.support.test.filters.MediumTest; import android.util.Base64; import android.view.Menu; -import org.junit.After; import org.junit.Assert; -import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -25,7 +21,6 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.ApplicationStatus; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.Feature; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeSwitches; @@ -39,9 +34,8 @@ import org.chromium.content_public.browser.test.util.Criteria; import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.content_public.browser.test.util.TestThreadUtils; -import org.chromium.net.test.EmbeddedTestServer; +import org.chromium.net.test.EmbeddedTestServerRule; -import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicReference; /** @@ -51,58 +45,40 @@ @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) public class CustomTabFromChromeExternalNavigationTest { @Rule - public CustomTabActivityTestRule mCustomTabActivityTestRule = new CustomTabActivityTestRule(); + public CustomTabActivityTestRule mActivityRule = new CustomTabActivityTestRule(); - private EmbeddedTestServer mTestServer; - - @Before - public void setUp() throws Exception { - mTestServer = EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext()); - } - - @After - public void tearDown() throws Exception { - mTestServer.stopAndDestroyServer(); - } - - private void startActivityCompletely(Intent intent) { - Activity activity = InstrumentationRegistry.getInstrumentation().startActivitySync(intent); - Assert.assertTrue(activity instanceof CustomTabActivity); - mCustomTabActivityTestRule.setActivity((CustomTabActivity) activity); - } + @Rule + public EmbeddedTestServerRule mServerRule = new EmbeddedTestServerRule(); private Intent getCustomTabFromChromeIntent(final String url, final boolean markFromChrome) { - return TestThreadUtils.runOnUiThreadBlockingNoException(new Callable<Intent>() { - @Override - public Intent call() throws Exception { - Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent = LaunchIntentDispatcher.createCustomTabActivityIntent( - InstrumentationRegistry.getTargetContext(), intent); - if (markFromChrome) { - // Explicitly not marking this as a trusted intent. If you add the trusted bit, - // then it prohibits launching external apps. We want to allow external apps - // to be launched, so we are intentionally not adding that for now. Ideally, - // being opened by Chrome would only be allowed with the corresponding trusted - // flag, but that requires additional refactoring in our external navigation - // handling. - intent.putExtra(CustomTabIntentDataProvider.EXTRA_IS_OPENED_BY_CHROME, true); - } - return intent; + return TestThreadUtils.runOnUiThreadBlockingNoException(() -> { + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent = LaunchIntentDispatcher.createCustomTabActivityIntent( + InstrumentationRegistry.getTargetContext(), intent); + if (markFromChrome) { + // Explicitly not marking this as a trusted intent. If you add the trusted bit, + // then it prohibits launching external apps. We want to allow external apps + // to be launched, so we are intentionally not adding that for now. Ideally, + // being opened by Chrome would only be allowed with the corresponding trusted + // flag, but that requires additional refactoring in our external navigation + // handling. + intent.putExtra(CustomTabIntentDataProvider.EXTRA_IS_OPENED_BY_CHROME, true); } + return intent; }); } private void startCustomTabFromChrome(String url) throws InterruptedException { Intent intent = getCustomTabFromChromeIntent(url, true); - mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); + mActivityRule.startCustomTabActivityWithIntent(intent); } private void startPaymentRequestUIFromChrome(String url) throws InterruptedException { Intent intent = getCustomTabFromChromeIntent(url, false); CustomTabIntentDataProvider.addPaymentRequestUIExtras(intent); - mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); + mActivityRule.startCustomTabActivityWithIntent(intent); InstrumentationRegistry.getInstrumentation().waitForIdleSync(); } @@ -112,7 +88,7 @@ public void testUsingStandardExternalNavigationHandler() throws Exception { startCustomTabFromChrome("about:blank"); - Tab tab = mCustomTabActivityTestRule.getActivity().getActivityTab(); + Tab tab = mActivityRule.getActivity().getActivityTab(); TabDelegateFactory delegateFactory = tab.getDelegateFactory(); Assert.assertTrue(delegateFactory instanceof CustomTabDelegateFactory); CustomTabDelegateFactory customTabDelegateFactory = @@ -124,54 +100,43 @@ @Test @Feature("CustomTabFromChrome") @LargeTest - @DisableIf.Build(message = "Flaky on K, https://crbug.com/962974", - sdk_is_less_than = Build.VERSION_CODES.LOLLIPOP) - public void - testIntentWithRedirectToApp() throws Exception { + public void testIntentWithRedirectToApp() throws Exception { final String redirectUrl = "https://maps.google.com/maps?q=1600+amphitheatre+parkway"; final String initialUrl = - mTestServer.getURL("/chrome/test/data/android/redirect/js_redirect.html" + mServerRule.getServer().getURL("/chrome/test/data/android/redirect/js_redirect.html" + "?replace_text=" + Base64.encodeToString( - ApiCompatibilityUtils.getBytesUtf8("PARAM_URL"), Base64.URL_SAFE) + ApiCompatibilityUtils.getBytesUtf8("PARAM_URL"), Base64.URL_SAFE) + ":" - + Base64.encodeToString(ApiCompatibilityUtils.getBytesUtf8(redirectUrl), - Base64.URL_SAFE)); + + Base64.encodeToString( + ApiCompatibilityUtils.getBytesUtf8(redirectUrl), Base64.URL_SAFE)); - startActivityCompletely(getCustomTabFromChromeIntent(initialUrl, true)); - mCustomTabActivityTestRule.waitForActivityNativeInitializationComplete(); + mActivityRule.startActivityCompletely(getCustomTabFromChromeIntent(initialUrl, true)); + mActivityRule.waitForActivityNativeInitializationComplete(); final AtomicReference<InterceptNavigationDelegateImpl> navigationDelegate = new AtomicReference<>(); - CriteriaHelper.pollUiThread(new Criteria("Tab never selected/initialized.") { - @Override - public boolean isSatisfied() { - Tab tab = mCustomTabActivityTestRule.getActivity().getActivityTab(); - if (tab == null) return false; - InterceptNavigationDelegateImpl delegate = InterceptNavigationDelegateImpl.get(tab); - if (delegate == null) return false; - navigationDelegate.set(delegate); - return true; - } - }); - CriteriaHelper.pollUiThread(Criteria.equals( - OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT, new Callable<Integer>() { - @Override - public @OverrideUrlLoadingResult Integer call() throws Exception { - return navigationDelegate.get().getLastOverrideUrlLoadingResultForTests(); - } - })); + CriteriaHelper.pollUiThread(() -> { + return mActivityRule.getActivity().getActivityTab() != null; + }, "Tab never initialized."); - CriteriaHelper.pollUiThread(new Criteria() { - @Override - public boolean isSatisfied() { - int activityState = ApplicationStatus.getStateForActivity( - mCustomTabActivityTestRule.getActivity()); - return activityState == ActivityState.STOPPED - || activityState == ActivityState.DESTROYED; - } - }); + CriteriaHelper.pollUiThread(() -> { + Tab tab = mActivityRule.getActivity().getActivityTab(); + InterceptNavigationDelegateImpl delegate = InterceptNavigationDelegateImpl.get(tab); + if (delegate == null) return false; + navigationDelegate.set(delegate); + return true; + }, "Navigation delegate never initialized."); + + CriteriaHelper.pollUiThread( + Criteria.equals(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT, + navigationDelegate.get()::getLastOverrideUrlLoadingResultForTests)); + + CriteriaHelper.pollUiThread(() -> { + int state = ApplicationStatus.getStateForActivity(mActivityRule.getActivity()); + return state == ActivityState.STOPPED || state == ActivityState.DESTROYED; + }, "Activity never stopped or destroyed."); } @Test @@ -180,7 +145,7 @@ public void testIntentToOpenPaymentRequestUI() throws Exception { startPaymentRequestUIFromChrome("about:blank"); - Tab tab = mCustomTabActivityTestRule.getActivity().getActivityTab(); + Tab tab = mActivityRule.getActivity().getActivityTab(); TabDelegateFactory delegateFactory = tab.getDelegateFactory(); Assert.assertTrue(delegateFactory instanceof CustomTabDelegateFactory); CustomTabDelegateFactory customTabDelegateFactory = @@ -188,8 +153,8 @@ Assert.assertFalse(customTabDelegateFactory.getExternalNavigationDelegate() instanceof CustomTabNavigationDelegate); - CustomTabsTestUtils.openAppMenuAndAssertMenuShown(mCustomTabActivityTestRule.getActivity()); - Menu menu = mCustomTabActivityTestRule.getMenu(); + CustomTabsTestUtils.openAppMenuAndAssertMenuShown(mActivityRule.getActivity()); + Menu menu = mActivityRule.getMenu(); Assert.assertTrue(menu.findItem(R.id.icon_row_menu_id).isVisible()); Assert.assertTrue(menu.findItem(R.id.find_in_page_id).isVisible());
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 9dd8d27..7c4c6460 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -937,6 +937,9 @@ <message name="IDS_LOGIN_SAML_NOTICE" desc="Text message displayed above SAML portal to early indicate that the user is being redirected to another sign-in provider. This is the version of the string used in the GAIA flow."> This sign-in service is hosted by <ph name="SAML_DOMAIN">$1<ex>saml.com</ex></ph> </message> + <message name="IDS_LOGIN_SAML_PASSWORD_CHANGE_NOTICE" desc="Text message displayed in the system dialog title. The dialog shows a web-page where the user can change their SAML password while staying in the session"> + This authentication service is hosted by <ph name="SAML_DOMAIN">$1<ex>saml.com</ex></ph> + </message> <message name="IDS_LOGIN_SAML_NOTICE_WITH_VIDEO" desc="Text message displayed above SAML portal to early indicate that the user is being redirected to another sign-in provider which has requested video media access."> This sign-in service, hosted by <ph name="SAML_DOMAIN">$1<ex>saml.com</ex></ph>, is accessing your camera. </message>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index ca421f5..fca57ac 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1227,9 +1227,6 @@ "predictors/autocomplete_action_predictor_factory.h", "predictors/autocomplete_action_predictor_table.cc", "predictors/autocomplete_action_predictor_table.h", - "predictors/glowplug_key_value_data.h", - "predictors/glowplug_key_value_table.cc", - "predictors/glowplug_key_value_table.h", "predictors/loading_data_collector.cc", "predictors/loading_data_collector.h", "predictors/loading_predictor.cc", @@ -1238,10 +1235,15 @@ "predictors/loading_predictor_config.h", "predictors/loading_predictor_factory.cc", "predictors/loading_predictor_factory.h", + "predictors/loading_predictor_key_value_data.h", + "predictors/loading_predictor_key_value_table.cc", + "predictors/loading_predictor_key_value_table.h", "predictors/loading_predictor_tab_helper.cc", "predictors/loading_predictor_tab_helper.h", "predictors/loading_stats_collector.cc", "predictors/loading_stats_collector.h", + "predictors/navigation_id.cc", + "predictors/navigation_id.h", "predictors/preconnect_manager.cc", "predictors/preconnect_manager.h", "predictors/predictor_database.cc", @@ -1254,8 +1256,6 @@ "predictors/proxy_lookup_client_impl.h", "predictors/resolve_host_client_impl.cc", "predictors/resolve_host_client_impl.h", - "predictors/resource_prefetch_common.cc", - "predictors/resource_prefetch_common.h", "predictors/resource_prefetch_predictor.cc", "predictors/resource_prefetch_predictor.h", "predictors/resource_prefetch_predictor_tables.cc", @@ -1514,6 +1514,13 @@ "sessions/session_tab_helper.h", "sessions/tab_restore_service_factory.cc", "sessions/tab_restore_service_factory.h", + "sharing/sharing_device_info.cc", + "sharing/sharing_device_info.h", + "sharing/sharing_message_handler.h", + "sharing/sharing_service.cc", + "sharing/sharing_service.h", + "sharing/sharing_service_factory.cc", + "sharing/sharing_service_factory.h", "shell_integration.cc", "shell_integration.h", "shell_integration_android.cc", @@ -1863,6 +1870,7 @@ "//chrome/browser/resource_coordinator:mojo_bindings", "//chrome/browser/resource_coordinator:tab_manager_features", "//chrome/browser/safe_browsing", + "//chrome/browser/sharing/proto", "//chrome/browser/ssl:proto", "//chrome/browser/ui", "//chrome/browser/ui/webui/bluetooth_internals",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index fd0f681c..b7ec08a1 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -30,7 +30,6 @@ #include "chrome/browser/browser_features.h" #include "chrome/browser/flag_descriptions.h" #include "chrome/browser/predictors/loading_predictor_config.h" -#include "chrome/browser/predictors/resource_prefetch_common.h" #include "chrome/browser/prerender/prerender_field_trial.h" #include "chrome/browser/resource_coordinator/tab_manager_features.h" #include "chrome/browser/search/ntp_features.h" @@ -154,7 +153,6 @@ #include "ui/android/buildflags.h" #else // OS_ANDROID #include "chrome/browser/media/router/media_router_feature.h" -#include "ui/message_center/public/cpp/features.h" #endif // OS_ANDROID #if defined(OS_CHROMEOS) @@ -1613,18 +1611,12 @@ flag_descriptions::kExtensionContentVerificationName, flag_descriptions::kExtensionContentVerificationDescription, kOsDesktop, MULTI_VALUE_TYPE(kExtensionContentVerificationChoices)}, -#if !defined(OS_ANDROID) #if defined(OS_CHROMEOS) {"enable-lock-screen-notification", flag_descriptions::kLockScreenNotificationName, flag_descriptions::kLockScreenNotificationDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kLockScreenNotifications)}, #endif // OS_CHROMEOS - {"enable-message-center-new-style-notification", - flag_descriptions::kMessageCenterNewStyleNotificationName, - flag_descriptions::kMessageCenterNewStyleNotificationDescription, - kOsDesktop, FEATURE_VALUE_TYPE(message_center::kNewStyleNotifications)}, -#endif // !OS_ANDROID #if defined(OS_CHROMEOS) {"wake-on-wifi-packet", flag_descriptions::kWakeOnPacketsName, flag_descriptions::kWakeOnPacketsDescription, kOsCrOSOwnerOnly, @@ -3702,6 +3694,11 @@ flag_descriptions::kCupsPrintersUiOverhaulName, flag_descriptions::kCupsPrintersUiOverhaulDescription, kOsCrOS, FEATURE_VALUE_TYPE(features::kCupsPrintersUiOverhaul)}, + + {"use-search-click-for-right-click", + flag_descriptions::kUseSearchClickForRightClickName, + flag_descriptions::kUseSearchClickForRightClickDescription, kOsCrOS, + FEATURE_VALUE_TYPE(chromeos::features::kUseSearchClickForRightClick)}, #endif // OS_CHROMEOS {"autofill-off-no-server-data",
diff --git a/chrome/browser/android/digital_asset_links/digital_asset_links_handler.cc b/chrome/browser/android/digital_asset_links/digital_asset_links_handler.cc index f14b73ce..095e5d481 100644 --- a/chrome/browser/android/digital_asset_links/digital_asset_links_handler.cc +++ b/chrome/browser/android/digital_asset_links/digital_asset_links_handler.cc
@@ -137,11 +137,11 @@ data_decoder::SafeJsonParser::Parse( /* connector=*/nullptr, // Connector is unused on Android. *response_body, - base::Bind(&DigitalAssetLinksHandler::OnJSONParseSucceeded, - weak_ptr_factory_.GetWeakPtr(), package, fingerprint, - relationship), - base::Bind(&DigitalAssetLinksHandler::OnJSONParseFailed, - weak_ptr_factory_.GetWeakPtr())); + base::BindOnce(&DigitalAssetLinksHandler::OnJSONParseSucceeded, + weak_ptr_factory_.GetWeakPtr(), package, fingerprint, + relationship), + base::BindOnce(&DigitalAssetLinksHandler::OnJSONParseFailed, + weak_ptr_factory_.GetWeakPtr())); url_loader_.reset(nullptr); }
diff --git a/chrome/browser/android/explore_sites/ntp_json_fetcher.cc b/chrome/browser/android/explore_sites/ntp_json_fetcher.cc index 7fad868..ff7d4d8 100644 --- a/chrome/browser/android/explore_sites/ntp_json_fetcher.cc +++ b/chrome/browser/android/explore_sites/ntp_json_fetcher.cc
@@ -100,10 +100,10 @@ data_decoder::SafeJsonParser::Parse( content::ServiceManagerConnection::GetForProcess()->GetConnector(), *response_body, - base::BindRepeating(&NTPJsonFetcher::OnJsonParseSuccess, - weak_factory_.GetWeakPtr()), - base::BindRepeating(&NTPJsonFetcher::OnJsonParseError, - weak_factory_.GetWeakPtr())); + base::BindOnce(&NTPJsonFetcher::OnJsonParseSuccess, + weak_factory_.GetWeakPtr()), + base::BindOnce(&NTPJsonFetcher::OnJsonParseError, + weak_factory_.GetWeakPtr())); } void NTPJsonFetcher::OnJsonParseSuccess(base::Value parsed_json) {
diff --git a/chrome/browser/autofill/autofill_interactive_uitest.cc b/chrome/browser/autofill/autofill_interactive_uitest.cc index adb50bc..39800d8 100644 --- a/chrome/browser/autofill/autofill_interactive_uitest.cc +++ b/chrome/browser/autofill/autofill_interactive_uitest.cc
@@ -78,7 +78,6 @@ #include "net/url_request/url_request_status.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "ui/compositor/compositor_switches.h" #include "ui/events/base_event_utils.h" #include "ui/events/keycodes/dom_us_layout_data.h" #include "ui/events/keycodes/keyboard_code_conversion.h" @@ -512,6 +511,7 @@ ExpectFieldValue("zip", "78744"); ExpectFieldValue("country", "US"); ExpectFieldValue("phone", "15125551234"); + LOG(ERROR) << "crbug/967588: Verified form was filled as expected"; } void ExpectClearedForm() { @@ -555,17 +555,22 @@ void TryBasicFormFill() { FocusFirstNameField(); + LOG(ERROR) << "crbug/967588: Focussed first name field"; // Start filling the first name field with "M" and wait for the popup to be // shown. SendKeyToPageAndWait(ui::DomKey::FromCharacter('M'), ui::DomCode::US_M, ui::VKEY_M, {ObservedUiEvents::kSuggestionShown}); + LOG(ERROR) << "crbug/967588: Sent 'M' and saw suggestion"; + // Press the down arrow to select the suggestion and preview the autofilled // form. SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN, {ObservedUiEvents::kPreviewFormData}); + LOG(ERROR) << "crbug/967588: Sent '<down arrow>' and saw preview"; + // The previewed values should not be accessible to JavaScript. ExpectFieldValue("firstname", "M"); ExpectFieldValue("lastname", std::string()); @@ -579,10 +584,15 @@ // TODO(isherman): It would be nice to test that the previewed values are // displayed: http://crbug.com/57220 + LOG(ERROR) + << "crbug/967588: Verified field contents remain unfilled for preview"; + // Press Enter to accept the autofill suggestions. SendKeyToPopupAndWait(ui::DomKey::ENTER, {ObservedUiEvents::kFormDataFilled}); + LOG(ERROR) << "crbug/967588: Form was filled after pressing enter"; + // The form should be filled. ExpectFilledTestForm(); } @@ -703,24 +713,25 @@ command_line->AppendSwitchASCII( translate::switches::kTranslateScriptURL, embedded_test_server()->GetURL("/mock_translate_script.js").spec()); - // TODO(crbug.com/966475) This temporary switch enables pixel outputs to - // understand why the tests time out. Check the "shard #xx isolated out" - // links on the try bot site to see the screenshots. - command_line->AppendSwitch(switches::kEnablePixelOutputInTests); } }; // Test that basic form fill is working. IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, BasicFormFill) { + LOG(ERROR) << "crbug/967588: In case of flakes, report log statements to " + "crbug.com/967588"; CreateTestProfile(); + LOG(ERROR) << "crbug/967588: Test profile created"; // Load the test page. SetTestUrlResponse(kTestShippingFormString); ASSERT_NO_FATAL_FAILURE( ui_test_utils::NavigateToURL(browser(), GetTestUrl())); + LOG(ERROR) << "crbug/967588: Loaded test page"; // Invoke Autofill. TryBasicFormFill(); + LOG(ERROR) << "crbug/967588: Basic form filling completed"; } IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, BasicClear) {
diff --git a/chrome/browser/background_fetch/background_fetch_download_client.cc b/chrome/browser/background_fetch/background_fetch_download_client.cc index c455b885..c534bd3 100644 --- a/chrome/browser/background_fetch/background_fetch_download_client.cc +++ b/chrome/browser/background_fetch/background_fetch_download_client.cc
@@ -70,7 +70,7 @@ if (download.paused) { // We need to resurface the notification in a paused state. - content::BrowserThread::PostAfterStartupTask( + content::BrowserThread::PostBestEffortTask( FROM_HERE, base::SequencedTaskRunnerHandle::Get(), base::BindOnce(&BackgroundFetchDelegateImpl::RestartPausedDownload, GetDelegate()->GetWeakPtr(), download.guid));
diff --git a/chrome/browser/chromeos/arc/policy/arc_policy_bridge.cc b/chrome/browser/chromeos/arc/policy/arc_policy_bridge.cc index e9db85d..09ed48e6 100644 --- a/chrome/browser/chromeos/arc/policy/arc_policy_bridge.cc +++ b/chrome/browser/chromeos/arc/policy/arc_policy_bridge.cc
@@ -436,9 +436,9 @@ data_decoder::SafeJsonParser::Parse( content::ServiceManagerConnection::GetForProcess()->GetConnector(), request, - base::Bind(&ArcPolicyBridge::OnReportComplianceParseSuccess, - weak_ptr_factory_.GetWeakPtr(), repeating_callback), - base::Bind(&OnReportComplianceParseFailure, repeating_callback)); + base::BindOnce(&ArcPolicyBridge::OnReportComplianceParseSuccess, + weak_ptr_factory_.GetWeakPtr(), repeating_callback), + base::BindOnce(&OnReportComplianceParseFailure, repeating_callback)); } void ArcPolicyBridge::ReportCloudDpsRequested(
diff --git a/chrome/browser/chromeos/kiosk_next_home/intent_config_helper.cc b/chrome/browser/chromeos/kiosk_next_home/intent_config_helper.cc index e1d5e764..61412d5 100644 --- a/chrome/browser/chromeos/kiosk_next_home/intent_config_helper.cc +++ b/chrome/browser/chromeos/kiosk_next_home/intent_config_helper.cc
@@ -126,10 +126,10 @@ // Parse JSON in utility process via Data Decoder Service. data_decoder::SafeJsonParser::Parse( connection->GetConnector(), json_config, - base::BindRepeating(&IntentConfigHelper::ParseConfigDone, - weak_factory_.GetWeakPtr()), - base::BindRepeating(&IntentConfigHelper::ParseConfigFailed, - weak_factory_.GetWeakPtr())); + base::BindOnce(&IntentConfigHelper::ParseConfigDone, + weak_factory_.GetWeakPtr()), + base::BindOnce(&IntentConfigHelper::ParseConfigFailed, + weak_factory_.GetWeakPtr())); } void IntentConfigHelper::ParseConfigDone(base::Value config_value) {
diff --git a/chrome/browser/chromeos/login/enrollment/enrollment_local_policy_server_browsertest.cc b/chrome/browser/chromeos/login/enrollment/enrollment_local_policy_server_browsertest.cc index 9c85611e..3ab89e43 100644 --- a/chrome/browser/chromeos/login/enrollment/enrollment_local_policy_server_browsertest.cc +++ b/chrome/browser/chromeos/login/enrollment/enrollment_local_policy_server_browsertest.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h" #include "chrome/browser/chromeos/login/test/oobe_base_test.h" #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h" +#include "chrome/browser/chromeos/login/test/oobe_screens_utils.h" #include "chrome/browser/chromeos/login/test/test_condition_waiter.h" #include "chrome/browser/chromeos/login/ui/login_display_host.h" #include "chrome/browser/chromeos/login/wizard_controller.h" @@ -44,17 +45,13 @@ constexpr char kTestDomain[] = "test-domain.com"; -void OnScreenExit(base::OnceClosure closure, - EnrollmentScreen::Result expected, - EnrollmentScreen::Result actual) { - EXPECT_EQ(expected, actual); - std::move(closure).Run(); -} +std::string GetDmTokenFromPolicy(const std::string& blob) { + enterprise_management::PolicyFetchResponse policy; + CHECK(policy.ParseFromString(blob)); -EnrollmentScreen::ScreenExitCallback UserCannotSkipCallback( - base::OnceClosure closure) { - return base::AdaptCallbackForRepeating(base::BindOnce( - OnScreenExit, std::move(closure), EnrollmentScreen::Result::BACK)); + enterprise_management::PolicyData policy_data; + CHECK(policy_data.ParseFromString(policy.policy_data())); + return policy_data.request_token(); } } // namespace @@ -496,11 +493,9 @@ kTestDomain)); host()->StartWizard(AutoEnrollmentCheckScreenView::kScreenId); OobeScreenWaiter(EnrollmentScreenView::kScreenId).Wait(); - base::RunLoop loop; - enrollment_screen()->set_exit_callback_for_testing( - UserCannotSkipCallback(loop.QuitClosure())); + enrollment_ui_.SetExitHandler(); enrollment_screen()->OnCancel(); - loop.Run(); + EXPECT_EQ(EnrollmentScreen::Result::BACK, enrollment_ui_.WaitForScreenExit()); } // Device is disabled. @@ -603,4 +598,63 @@ OobeScreenWaiter(EnrollmentScreenView::kScreenId).Wait(); } +class EnrollmentRecoveryTest : public EnrollmentLocalPolicyServerBase { + public: + EnrollmentRecoveryTest() : EnrollmentLocalPolicyServerBase() { + device_state_.SetState( + DeviceStateMixin::State::OOBE_COMPLETED_CLOUD_ENROLLED); + } + + ~EnrollmentRecoveryTest() override = default; + + protected: + void SetUpInProcessBrowserTestFixture() override { + EnrollmentLocalPolicyServerBase::SetUpInProcessBrowserTestFixture(); + + // This triggers recovery enrollment. + device_state_.RequestDevicePolicyUpdate()->policy_data()->Clear(); + } + + private: + DISALLOW_COPY_AND_ASSIGN(EnrollmentRecoveryTest); +}; + +IN_PROC_BROWSER_TEST_F(EnrollmentRecoveryTest, Success) { + test::SkipToEnrollmentOnRecovery(); + + ASSERT_TRUE(StartupUtils::IsDeviceRegistered()); + ASSERT_TRUE(InstallAttributes::Get()->IsEnterpriseManaged()); + // No DM Token + ASSERT_TRUE( + GetDmTokenFromPolicy(FakeSessionManagerClient::Get()->device_policy()) + .empty()); + + // User can't skip. + enrollment_ui_.SetExitHandler(); + enrollment_screen()->OnCancel(); + EXPECT_EQ(EnrollmentScreen::Result::BACK, enrollment_ui_.WaitForScreenExit()); + + enrollment_screen()->OnLoginDone(FakeGaiaMixin::kEnterpriseUser1, + FakeGaiaMixin::kFakeAuthCode); + enrollment_ui_.WaitForStep(test::ui::kEnrollmentStepSuccess); + + // DM Token is in the device policy. + EXPECT_FALSE( + GetDmTokenFromPolicy(FakeSessionManagerClient::Get()->device_policy()) + .empty()); +} + +IN_PROC_BROWSER_TEST_F(EnrollmentRecoveryTest, DifferentDomain) { + test::SkipToEnrollmentOnRecovery(); + + ASSERT_TRUE(StartupUtils::IsDeviceRegistered()); + ASSERT_TRUE(InstallAttributes::Get()->IsEnterpriseManaged()); + enrollment_screen()->OnLoginDone(FakeGaiaMixin::kFakeUserEmail, + FakeGaiaMixin::kFakeAuthCode); + enrollment_ui_.WaitForStep(test::ui::kEnrollmentStepError); + enrollment_ui_.ExpectErrorMessage( + IDS_ENTERPRISE_ENROLLMENT_STATUS_LOCK_WRONG_USER, true); + enrollment_ui_.RetryAfterError(); +} + } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/enrollment/enrollment_screen_browsertest.cc b/chrome/browser/chromeos/login/enrollment/enrollment_screen_browsertest.cc index 389d89a..cb27e26b 100644 --- a/chrome/browser/chromeos/login/enrollment/enrollment_screen_browsertest.cc +++ b/chrome/browser/chromeos/login/enrollment/enrollment_screen_browsertest.cc
@@ -10,14 +10,15 @@ #include "chrome/browser/chromeos/login/enrollment/enrollment_screen.h" #include "chrome/browser/chromeos/login/enrollment/mock_enrollment_screen.h" #include "chrome/browser/chromeos/login/login_wizard.h" +#include "chrome/browser/chromeos/login/mixin_based_in_process_browser_test.h" #include "chrome/browser/chromeos/login/oobe_screen.h" #include "chrome/browser/chromeos/login/startup_utils.h" +#include "chrome/browser/chromeos/login/test/enrollment_ui_mixin.h" #include "chrome/browser/chromeos/login/test/js_checker.h" #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h" #include "chrome/browser/chromeos/login/ui/login_display_host.h" #include "chrome/browser/chromeos/login/ui/webui_login_view.h" #include "chrome/browser/chromeos/login/wizard_controller.h" -#include "chrome/test/base/in_process_browser_test.h" #include "chromeos/constants/chromeos_switches.h" #include "chromeos/test/chromeos_test_utils.h" #include "content/public/test/test_utils.h" @@ -30,26 +31,23 @@ namespace chromeos { -class EnrollmentScreenTest : public InProcessBrowserTest { +class EnrollmentScreenTest : public MixinBasedInProcessBrowserTest { public: EnrollmentScreenTest() = default; ~EnrollmentScreenTest() override = default; - // InProcessBrowserTest: + // MixinBasedInProcessBrowserTest: void SetUpCommandLine(base::CommandLine* command_line) override { - InProcessBrowserTest::SetUpCommandLine(command_line); + MixinBasedInProcessBrowserTest::SetUpCommandLine(command_line); command_line->AppendArg(switches::kLoginManager); } + + // MixinBasedInProcessBrowserTest: void SetUpOnMainThread() override { - InProcessBrowserTest::SetUpOnMainThread(); + MixinBasedInProcessBrowserTest::SetUpOnMainThread(); ShowLoginWizard(EnrollmentScreenView::kScreenId); EXPECT_EQ(WizardController::default_controller()->current_screen(), enrollment_screen()); - enrollment_screen()->set_exit_callback_for_testing(base::BindRepeating( - &EnrollmentScreenTest::HandleScreenExit, base::Unretained(this))); - } - void TearDownOnMainThread() override { - InProcessBrowserTest::TearDownOnMainThread(); } EnrollmentScreen* enrollment_screen() { @@ -60,48 +58,25 @@ return enrollment_screen; } - // Runs loop until the enrollment screen reports exit. It will return the - // last result returned by the enrollment screen. - // NOTE: This will not work if the screen is expected to be shown more than - // once - to support that use case, screen_result_ would have to be reset - // before showing another EnrollmentScreen. - EnrollmentScreen::Result WaitForScreenExit() { - if (screen_result_.has_value()) - return screen_result_.value(); - if (!screen_exit_waiter_) - screen_exit_waiter_ = std::make_unique<base::RunLoop>(); - screen_exit_waiter_->Run(); - return screen_result_.value(); - } + test::EnrollmentUIMixin enrollment_ui_{&mixin_host_}; private: - void HandleScreenExit(EnrollmentScreen::Result result) { - EXPECT_FALSE(screen_result_.has_value()); - screen_result_ = result; - if (screen_exit_waiter_) - screen_exit_waiter_->Quit(); - } - - base::Optional<EnrollmentScreen::Result> screen_result_; - - // Created lazily in WaitForScreenExit(). - // Note: unique_ptr because RunLoops cannot be created without a thread - // context, which does not exist in the test ctor. - std::unique_ptr<base::RunLoop> screen_exit_waiter_; DISALLOW_COPY_AND_ASSIGN(EnrollmentScreenTest); }; IN_PROC_BROWSER_TEST_F(EnrollmentScreenTest, TestCancel) { + enrollment_ui_.SetExitHandler(); enrollment_screen()->OnCancel(); - EnrollmentScreen::Result screen_result = WaitForScreenExit(); + EnrollmentScreen::Result screen_result = enrollment_ui_.WaitForScreenExit(); EXPECT_EQ(EnrollmentScreen::Result::COMPLETED, screen_result); } IN_PROC_BROWSER_TEST_F(EnrollmentScreenTest, TestSuccess) { WizardController::SkipEnrollmentPromptsForTesting(); + enrollment_ui_.SetExitHandler(); enrollment_screen()->OnDeviceAttributeUpdatePermission(false /* granted */); - EnrollmentScreen::Result screen_result = WaitForScreenExit(); + EnrollmentScreen::Result screen_result = enrollment_ui_.WaitForScreenExit(); EXPECT_EQ(EnrollmentScreen::Result::COMPLETED, screen_result); EXPECT_TRUE(StartupUtils::IsDeviceRegistered()); @@ -124,8 +99,9 @@ IN_PROC_BROWSER_TEST_F(AttestationAuthEnrollmentScreenTest, TestCancel) { ASSERT_FALSE(enrollment_screen()->AdvanceToNextAuth()); + enrollment_ui_.SetExitHandler(); enrollment_screen()->OnCancel(); - EnrollmentScreen::Result screen_result = WaitForScreenExit(); + EnrollmentScreen::Result screen_result = enrollment_ui_.WaitForScreenExit(); EXPECT_EQ(EnrollmentScreen::Result::COMPLETED, screen_result); } @@ -172,8 +148,9 @@ IN_PROC_BROWSER_TEST_F(ForcedAttestationAuthEnrollmentScreenTest, TestCancel) { ASSERT_FALSE(enrollment_screen()->AdvanceToNextAuth()); + enrollment_ui_.SetExitHandler(); enrollment_screen()->OnCancel(); - EnrollmentScreen::Result screen_result = WaitForScreenExit(); + EnrollmentScreen::Result screen_result = enrollment_ui_.WaitForScreenExit(); EXPECT_EQ(EnrollmentScreen::Result::BACK, screen_result); } @@ -201,8 +178,9 @@ IN_PROC_BROWSER_TEST_F(MultiAuthEnrollmentScreenTest, TestCancel) { ASSERT_TRUE(enrollment_screen()->AdvanceToNextAuth()); + enrollment_ui_.SetExitHandler(); enrollment_screen()->OnCancel(); - EnrollmentScreen::Result screen_result = WaitForScreenExit(); + EnrollmentScreen::Result screen_result = enrollment_ui_.WaitForScreenExit(); EXPECT_EQ(EnrollmentScreen::Result::BACK, screen_result); } @@ -227,8 +205,9 @@ }; IN_PROC_BROWSER_TEST_F(ProvisionedEnrollmentScreenTest, TestBackButton) { + enrollment_ui_.SetExitHandler(); enrollment_screen()->OnCancel(); - EnrollmentScreen::Result screen_result = WaitForScreenExit(); + EnrollmentScreen::Result screen_result = enrollment_ui_.WaitForScreenExit(); EXPECT_EQ(EnrollmentScreen::Result::BACK, screen_result); }
diff --git a/chrome/browser/chromeos/login/oobe_interactive_ui_test.cc b/chrome/browser/chromeos/login/oobe_interactive_ui_test.cc index 0a94da9..905e40a 100644 --- a/chrome/browser/chromeos/login/oobe_interactive_ui_test.cc +++ b/chrome/browser/chromeos/login/oobe_interactive_ui_test.cc
@@ -9,7 +9,6 @@ #include "base/optional.h" #include "base/test/scoped_feature_list.h" #include "base/values.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/arc/arc_service_launcher.h" #include "chrome/browser/chromeos/arc/arc_session_manager.h" #include "chrome/browser/chromeos/extensions/quick_unlock_private/quick_unlock_private_api.h" @@ -17,8 +16,6 @@ #include "chrome/browser/chromeos/login/screens/recommend_apps/recommend_apps_fetcher.h" #include "chrome/browser/chromeos/login/screens/recommend_apps/recommend_apps_fetcher_delegate.h" #include "chrome/browser/chromeos/login/screens/recommend_apps/scoped_test_recommend_apps_fetcher_factory.h" -#include "chrome/browser/chromeos/login/screens/sync_consent_screen.h" -#include "chrome/browser/chromeos/login/screens/update_screen.h" #include "chrome/browser/chromeos/login/test/device_state_mixin.h" #include "chrome/browser/chromeos/login/test/embedded_test_server_mixin.h" #include "chrome/browser/chromeos/login/test/fake_gaia_mixin.h" @@ -27,6 +24,7 @@ #include "chrome/browser/chromeos/login/test/oobe_base_test.h" #include "chrome/browser/chromeos/login/test/oobe_screen_exit_waiter.h" #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h" +#include "chrome/browser/chromeos/login/test/oobe_screens_utils.h" #include "chrome/browser/chromeos/login/test/test_predicate_waiter.h" #include "chrome/browser/chromeos/login/ui/login_display_host.h" #include "chrome/browser/chromeos/login/wizard_controller.h" @@ -34,23 +32,16 @@ #include "chrome/browser/ui/ash/tablet_mode_client.h" #include "chrome/browser/ui/webui/chromeos/login/app_downloading_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.h" -#include "chrome/browser/ui/webui/chromeos/login/discover_screen_handler.h" -#include "chrome/browser/ui/webui/chromeos/login/eula_screen_handler.h" -#include "chrome/browser/ui/webui/chromeos/login/fingerprint_setup_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h" -#include "chrome/browser/ui/webui/chromeos/login/network_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/recommend_apps_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/terms_of_service_screen_handler.h" -#include "chrome/browser/ui/webui/chromeos/login/update_screen_handler.h" -#include "chrome/browser/ui/webui/chromeos/login/welcome_screen_handler.h" #include "chromeos/constants/chromeos_switches.h" #include "chromeos/dbus/update_engine_client.h" #include "components/arc/arc_service_manager.h" #include "components/arc/arc_util.h" #include "components/arc/session/arc_session_runner.h" #include "components/arc/test/fake_arc_session.h" -#include "content/public/browser/notification_service.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_utils.h" #include "net/dns/mock_host_resolver.h" @@ -79,14 +70,6 @@ return "unknown"; } -void WaitForOobeWelcomeScreen() { - content::WindowedNotificationObserver observer( - chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, - content::NotificationService::AllSources()); - observer.Wait(); - OobeScreenWaiter(WelcomeView::kScreenId).Wait(); -} - void RunWelcomeScreenChecks() { #if defined(GOOGLE_CHROME_BUILD) constexpr int kNumberOfVideosPlaying = 1; @@ -105,33 +88,14 @@ kNumberOfVideosPlaying); } -void TapWelcomeNext() { - test::OobeJS().TapOnPath({"connect", "welcomeScreen", "welcomeNextButton"}); -} - -void WaitForNetworkSelectionScreen() { - OobeScreenWaiter(NetworkScreenView::kScreenId).Wait(); - LOG(INFO) << "OobeInteractiveUITest: Switched to 'network-selection' screen."; -} - void RunNetworkSelectionScreenChecks() { test::OobeJS().ExpectTrue( "!$('oobe-network-md').$.networkDialog.querySelector('oobe-next-button'" ").disabled"); } -void TapNetworkSelectionNext() { - test::OobeJS().ExecuteAsync( - "$('oobe-network-md').$.networkDialog.querySelector('oobe-next-button')" - ".click()"); -} #if defined(GOOGLE_CHROME_BUILD) -void WaitForEulaScreen() { - OobeScreenWaiter(EulaView::kScreenId).Wait(); - LOG(INFO) << "OobeInteractiveUITest: Switched to 'eula' screen."; -} - void RunEulaScreenChecks() { // Wait for actual EULA to appear. test::OobeJS() @@ -139,27 +103,8 @@ ->Wait(); test::OobeJS().ExpectTrue("!$('oobe-eula-md').$.acceptButton.disabled"); } - -void TapEulaAccept() { - test::OobeJS().TapOnPath({"oobe-eula-md", "acceptButton"}); -} #endif -void WaitForUpdateScreen() { - OobeScreenWaiter(UpdateView::kScreenId).Wait(); - test::OobeJS().CreateVisibilityWaiter(true, {"update"})->Wait(); - - LOG(INFO) << "OobeInteractiveUITest: Switched to 'update' screen."; -} - -void ExitUpdateScreenNoUpdate() { - UpdateScreen* screen = static_cast<UpdateScreen*>( - WizardController::default_controller()->GetScreen(UpdateView::kScreenId)); - UpdateEngineClient::Status status; - status.status = UpdateEngineClient::UPDATE_STATUS_ERROR; - screen->UpdateStatusChanged(status); -} - void WaitForGaiaSignInScreen(bool arc_available) { OobeScreenWaiter(GaiaView::kScreenId).Wait(); @@ -189,44 +134,6 @@ LOG(INFO) << "OobeInteractiveUITest: Logged in."; } -#if defined(GOOGLE_CHROME_BUILD) -void WaitForSyncConsentScreen() { - LOG(INFO) << "OobeInteractiveUITest: Waiting for 'sync-consent' screen."; - OobeScreenWaiter(SyncConsentScreenView::kScreenId).Wait(); -} - -void ExitScreenSyncConsent() { - SyncConsentScreen* screen = static_cast<SyncConsentScreen*>( - WizardController::default_controller()->GetScreen( - SyncConsentScreenView::kScreenId)); - - screen->SetProfileSyncDisabledByPolicyForTesting(true); - screen->OnStateChanged(nullptr); - LOG(INFO) << "OobeInteractiveUITest: Waiting for 'sync-consent' screen " - "to close."; - OobeScreenExitWaiter(SyncConsentScreenView::kScreenId).Wait(); -} -#endif - -void WaitForFingerprintScreen() { - LOG(INFO) << "OobeInteractiveUITest: Waiting for 'fingerprint-setup' screen."; - OobeScreenWaiter(FingerprintSetupScreenView::kScreenId).Wait(); - LOG(INFO) << "OobeInteractiveUITest: Waiting for fingerprint setup screen " - "to show."; - test::OobeJS().CreateVisibilityWaiter(true, {"fingerprint-setup"})->Wait(); - LOG(INFO) << "OobeInteractiveUITest: Waiting for fingerprint setup screen " - "to initializes."; - test::OobeJS() - .CreateVisibilityWaiter(true, {"fingerprint-setup-impl"}) - ->Wait(); - LOG(INFO) << "OobeInteractiveUITest: Waiting for fingerprint setup screen " - "to show setupFingerprint."; - test::OobeJS() - .CreateVisibilityWaiter(true, - {"fingerprint-setup-impl", "setupFingerprint"}) - ->Wait(); -} - void RunFingerprintScreenChecks() { test::OobeJS().ExpectVisible("fingerprint-setup"); test::OobeJS().ExpectVisible("fingerprint-setup-impl"); @@ -243,24 +150,6 @@ ->Wait(); } -void ExitFingerprintPinSetupScreen() { - test::OobeJS().ExpectVisiblePath({"fingerprint-setup-impl", "placeFinger"}); - // This might be the last step in flow. Synchronious execute gets stuck as - // WebContents may be destroyed in the process. So it may never return. - // So we use ExecuteAsync() here. - test::OobeJS().ExecuteAsync( - "$('fingerprint-setup-impl').$.setupFingerprintLater.click()"); - LOG(INFO) << "OobeInteractiveUITest: Waiting for fingerprint setup screen " - "to close."; - OobeScreenExitWaiter(FingerprintSetupScreenView::kScreenId).Wait(); - LOG(INFO) << "OobeInteractiveUITest: 'fingerprint-setup' screen done."; -} - -void WaitForDiscoverScreen() { - OobeScreenWaiter(DiscoverScreenView::kScreenId).Wait(); - LOG(INFO) << "OobeInteractiveUITest: Switched to 'discover' screen."; -} - void RunDiscoverScreenChecks() { test::OobeJS().ExpectVisible("discover"); test::OobeJS().ExpectVisible("discover-impl"); @@ -272,17 +161,6 @@ "setup.hidden"); } -void ExitDiscoverPinSetupScreen() { - // This might be the last step in flow. Synchronious execute gets stuck as - // WebContents may be destroyed in the process. So it may never return. - // So we use ExecuteAsync() here. - test::OobeJS().ExecuteAsync( - "$('discover-impl').root.querySelector('discover-pin-setup-module')." - "$.setupSkipButton.click()"); - OobeScreenExitWaiter(DiscoverScreenView::kScreenId).Wait(); - LOG(INFO) << "OobeInteractiveUITest: 'discover' screen done."; -} - // Waits for the ARC terms of service screen to be shown, it accepts or // declines the terms based in |accept_terms| value, and waits for the flow to // leave the ARC terms of service screen. @@ -624,53 +502,52 @@ EmbeddedTestServerSetupMixin arc_tos_server_setup_{&mixin_host_, &arc_tos_server_}; OobeEndToEndTestSetupMixin setup_{&mixin_host_, &arc_tos_server_, GetParam()}; - DISALLOW_COPY_AND_ASSIGN(OobeInteractiveUITest); }; void OobeInteractiveUITest::SimpleEndToEnd() { ScopedQuickUnlockPrivateGetAuthTokenFunctionObserver get_auth_token_observer; - WaitForOobeWelcomeScreen(); + test::WaitForWelcomeScreen(); RunWelcomeScreenChecks(); - TapWelcomeNext(); + test::TapWelcomeNext(); - WaitForNetworkSelectionScreen(); + test::WaitForNetworkSelectionScreen(); RunNetworkSelectionScreenChecks(); - TapNetworkSelectionNext(); + test::TapNetworkSelectionNext(); #if defined(GOOGLE_CHROME_BUILD) - WaitForEulaScreen(); + test::WaitForEulaScreen(); RunEulaScreenChecks(); - TapEulaAccept(); + test::TapEulaAccept(); #endif - WaitForUpdateScreen(); - ExitUpdateScreenNoUpdate(); + test::WaitForUpdateScreen(); + test::ExitUpdateScreenNoUpdate(); WaitForGaiaSignInScreen(test_setup()->arc_state() != ArcState::kNotAvailable); LogInAsRegularUser(); #if defined(GOOGLE_CHROME_BUILD) - WaitForSyncConsentScreen(); - ExitScreenSyncConsent(); + test::WaitForSyncConsentScreen(); + test::ExitScreenSyncConsent(); #endif if (test_setup()->is_quick_unlock_enabled()) { - WaitForFingerprintScreen(); + test::WaitForFingerprintScreen(); RunFingerprintScreenChecks(); - ExitFingerprintPinSetupScreen(); + test::ExitFingerprintPinSetupScreen(); } if (test_setup()->is_tablet()) { - WaitForDiscoverScreen(); + test::WaitForDiscoverScreen(); RunDiscoverScreenChecks(); EXPECT_TRUE(get_auth_token_observer.get_auth_token_password().has_value()); EXPECT_EQ(get_auth_token_observer.get_auth_token_password().value(), FakeGaiaMixin::kFakeUserPassword); - ExitDiscoverPinSetupScreen(); + test::ExitDiscoverPinSetupScreen(); } if (test_setup()->arc_state() != ArcState::kNotAvailable) { @@ -867,24 +744,24 @@ LogInAsRegularUser(); #if defined(GOOGLE_CHROME_BUILD) - WaitForSyncConsentScreen(); - ExitScreenSyncConsent(); + test::WaitForSyncConsentScreen(); + test::ExitScreenSyncConsent(); #endif if (test_setup()->is_quick_unlock_enabled()) { - WaitForFingerprintScreen(); + test::WaitForFingerprintScreen(); RunFingerprintScreenChecks(); - ExitFingerprintPinSetupScreen(); + test::ExitFingerprintPinSetupScreen(); } if (test_setup()->is_tablet()) { - WaitForDiscoverScreen(); + test::WaitForDiscoverScreen(); RunDiscoverScreenChecks(); EXPECT_TRUE(get_auth_token_observer.get_auth_token_password().has_value()); EXPECT_EQ("", get_auth_token_observer.get_auth_token_password().value()); - ExitDiscoverPinSetupScreen(); + test::ExitDiscoverPinSetupScreen(); } if (test_setup()->arc_state() != ArcState::kNotAvailable) {
diff --git a/chrome/browser/chromeos/login/saml/saml_browsertest.cc b/chrome/browser/chromeos/login/saml/saml_browsertest.cc index a754826..5a3168c 100644 --- a/chrome/browser/chromeos/login/saml/saml_browsertest.cc +++ b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
@@ -480,17 +480,22 @@ StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail); // Saml flow UI expectations. - test::OobeJS().ExpectVisible("saml-notice-container"); - test::OobeJS().ExpectVisible("signin-back-button"); - std::string js = "$('saml-notice-message').textContent.indexOf('$Host') > -1"; + test::OobeJS().ExpectVisiblePath({"gaia-signin", "saml-notice-container"}); + test::OobeJS().ExpectVisiblePath({"gaia-signin", "signin-back-button"}); + std::string js = "$SamlNoticeMessagePath.textContent.indexOf('$Host') > -1"; + base::ReplaceSubstringsAfterOffset( + &js, 0, "$SamlNoticeMessagePath", + test::GetOobeElementPath({"gaia-signin", "saml-notice-message"})); base::ReplaceSubstringsAfterOffset(&js, 0, "$Host", kIdPHost); test::OobeJS().ExpectTrue(js); content::DOMMessageQueue message_queue; // Observe before 'back'. SetupAuthFlowChangeListener(); // Click on 'back'. - content::ExecuteScriptAsync(GetLoginUI()->GetWebContents(), - "$('signin-back-button').fire('tap');"); + content::ExecuteScriptAsync( + GetLoginUI()->GetWebContents(), + test::GetOobeElementPath({"gaia-signin", "signin-back-button"}) + + ".fire('tap');"); // Auth flow should change back to Gaia. std::string message; @@ -499,7 +504,7 @@ } while (message != "\"GaiaLoaded\""); // Saml flow is gone. - test::OobeJS().ExpectHidden("saml-notice-container"); + test::OobeJS().ExpectHiddenPath({"gaia-signin", "saml-notice-container"}); } // Tests the sign-in flow when the credentials passing API is used. @@ -735,8 +740,7 @@ // |kAdditionalIdPHost|. std::string js = "var sendIfHostFound = function() {" - " var found =" - " $('saml-notice-message').textContent.indexOf('$Host') > -1;" + " var found = $SamlNoticeMessagePath.textContent.indexOf('$Host') > -1;" " if (found)" " window.domAutomationController.send(true);" " return found;" @@ -755,13 +759,16 @@ " 'authDomainChange'," " processEventsAndSendIfHostFound);" "}"; + base::ReplaceSubstringsAfterOffset( + &js, 0, "$SamlNoticeMessagePath", + test::GetOobeElementPath({"gaia-signin", "saml-notice-message"})); base::ReplaceSubstringsAfterOffset(&js, 0, "$Host", kAdditionalIdPHost); bool dummy; EXPECT_TRUE(content::ExecuteScriptAndExtractBool( GetLoginUI()->GetWebContents(), js, &dummy)); // Verify that the notice is visible. - test::OobeJS().ExpectVisible("saml-notice-container"); + test::OobeJS().ExpectVisiblePath({"gaia-signin", "saml-notice-container"}); } // Verifies that when GAIA attempts to redirect to a SAML IdP served over http, @@ -1103,22 +1110,24 @@ login_screen_load_observer_->Wait(); WaitForOobeUI(); + std::string js = + "{" + " let notify = function() {" + " window.domAutomationController.send('samlInterstitialPageReady');" + " };" + " if ($('gaia-signin').samlInterstitialPageReady) {" + " window.setTimeout(notify, 0);" + " } else {" + " $SamlInterstitialPath.addEventListener(" + " 'samlInterstitialPageReady', notify);" + " }" + "}"; + base::ReplaceSubstringsAfterOffset( + &js, 0, "$SamlInterstitialPath", + test::GetOobeElementPath({"gaia-signin", "saml-interstitial"})); + content::DOMMessageQueue message_queue; - ASSERT_TRUE( - content::ExecuteScript(GetLoginUI()->GetWebContents(), - "{" - " let notify = function() {" - " window.domAutomationController.send(" - " 'samlInterstitialPageReady');" - " };" - " if($('gaia-signin')." - " samlInterstitialPageReady) {" - " window.setTimeout(notify,0);" - " } else {" - " $('saml-interstitial').addEventListener(" - " 'samlInterstitialPageReady', notify);" - " }" - "}")); + ASSERT_TRUE(content::ExecuteScript(GetLoginUI()->GetWebContents(), js)); ASSERT_TRUE(test::LoginScreenTester().ClickAddUserButton()); std::string message; @@ -1133,8 +1142,10 @@ content::DOMMessageQueue message_queue; SetupAuthFlowChangeListener(); - ASSERT_TRUE(content::ExecuteScript(GetLoginUI()->GetWebContents(), - "$('saml-interstitial').submit();")); + std::string js = + test::GetOobeElementPath({"gaia-signin", "saml-interstitial"}) + + ".submit();"; + ASSERT_TRUE(content::ExecuteScript(GetLoginUI()->GetWebContents(), js)); std::string message; do { @@ -1144,13 +1155,18 @@ void SAMLPolicyTest::ClickChangeAccountOnSAMLInterstitialPage() { login_screen_load_observer_->Wait(); - content::DOMMessageQueue message_queue; - ASSERT_TRUE(content::ExecuteScript( - GetLoginUI()->GetWebContents(), + + std::string js = "$('gaia-signin').authenticator_.addEventListener('ready', function() {" " window.domAutomationController.send('ready');" "});" - "$('saml-interstitial').changeAccountLink.click();")); + "$SamlInterstitialPath.changeAccountLink.click();"; + base::ReplaceSubstringsAfterOffset( + &js, 0, "$SamlInterstitialPath", + test::GetOobeElementPath({"gaia-signin", "saml-interstitial"})); + + content::DOMMessageQueue message_queue; + ASSERT_TRUE(content::ExecuteScript(GetLoginUI()->GetWebContents(), js)); std::string message; do { @@ -1357,18 +1373,18 @@ WaitForSigninScreen(); ShowSAMLInterstitial(); - test::OobeJS().ExpectHidden("signin-frame"); - test::OobeJS().ExpectHidden("offline-gaia"); - test::OobeJS().ExpectVisible("saml-interstitial"); + test::OobeJS().ExpectHiddenPath({"gaia-signin", "signin-frame"}); + test::OobeJS().ExpectHiddenPath({"gaia-signin", "offline-gaia"}); + test::OobeJS().ExpectVisiblePath({"gaia-signin", "saml-interstitial"}); // Click the "change account" link on the SAML interstitial page. ClickChangeAccountOnSAMLInterstitialPage(); // Expects that only the gaia signin frame is visible and shown. - test::OobeJS().ExpectHasClass("show", {"signin-frame"}); - test::OobeJS().ExpectVisible("signin-frame"); - test::OobeJS().ExpectHidden("offline-gaia"); - test::OobeJS().ExpectHidden("saml-interstitial"); + test::OobeJS().ExpectHasClass("show", {"gaia-signin", "signin-frame"}); + test::OobeJS().ExpectVisiblePath({"gaia-signin", "signin-frame"}); + test::OobeJS().ExpectHiddenPath({"gaia-signin", "offline-gaia"}); + test::OobeJS().ExpectHiddenPath({"gaia-signin", "saml-interstitial"}); } // Tests that clicking "Next" in the SAML interstitial page successfully
diff --git a/chrome/browser/chromeos/login/saml/saml_password_expiry_notification.cc b/chrome/browser/chromeos/login/saml/saml_password_expiry_notification.cc index c2a0d6fe..48d6d7d 100644 --- a/chrome/browser/chromeos/login/saml/saml_password_expiry_notification.cc +++ b/chrome/browser/chromeos/login/saml/saml_password_expiry_notification.cc
@@ -5,12 +5,15 @@ #include "chrome/browser/chromeos/login/saml/saml_password_expiry_notification.h" #include "ash/public/cpp/notification_utils.h" +#include "ash/public/cpp/session/session_activation_observer.h" +#include "ash/public/cpp/session/session_controller.h" #include "base/bind.h" #include "base/strings/string16.h" #include "base/strings/string_util.h" #include "base/task/post_task.h" #include "base/task/task_traits.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/notifications/notification_common.h" #include "chrome/browser/notifications/notification_display_service.h" #include "chrome/browser/notifications/notification_display_service_factory.h" @@ -75,15 +78,6 @@ const base::NoDestructor<base::string16> kLineSeparator( base::string16(1, '\n')); -// Callback called when notification is clicked - opens password-change page. -void OnNotificationClicked() { - PasswordChangeDialog::Show(); -} - -const base::NoDestructor<scoped_refptr<HandleNotificationClickDelegate>> - kClickDelegate(base::MakeRefCounted<HandleNotificationClickDelegate>( - base::BindRepeating(&OnNotificationClicked))); - base::string16 GetTitleText(int less_than_n_days) { const bool hasExpired = (less_than_n_days <= 0); return hasExpired ? l10n_util::GetStringUTF16(IDS_PASSWORD_HAS_EXPIRED_TITLE) @@ -109,57 +103,75 @@ content::BrowserThread::UI, base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}; -// A task to check again if the notification should be shown at a later time. -// This has weak pointers so that it pending tasks can be canceled. -class RecheckTask { +// Returns true if |profile| is still valid. +bool IsValidProfile(Profile* profile) { + ProfileManager* profile_manager = g_browser_process->profile_manager(); + return profile_manager && profile_manager->IsValidProfile(profile); +} + +// Returns true if showing the notification is enabled for this profile. +bool IsEnabledForProfile(Profile* profile) { + return chromeos::ProfileHelper::IsPrimaryProfile(profile) && + profile->GetPrefs()->GetBoolean( + prefs::kSamlInSessionPasswordChangeEnabled); +} + +// The Rechecker checks periodically if the notification should be shown or +// updated. When it checks depends on when the password will expire. +// There is only at most one Rechecker at a time - for the primary user. +class Rechecker : public ash::SessionActivationObserver { public: - void Run(Profile* profile) { - MaybeShowSamlPasswordExpiryNotification(profile); - } + // Checks again if the notification should be shown, and maybe shows it. + void Recheck(); - // Check again whether to show notification for |profile| after |delay|. - void PostDelayed(Profile* profile, base::TimeDelta delay) { - base::PostDelayedTaskWithTraits( - FROM_HERE, kRecheckTaskTraits, - base::BindOnce(&RecheckTask::Run, weak_ptr_factory.GetWeakPtr(), - profile), - delay); - } + // Calls recheck after the given |delay|. + void RecheckAfter(base::TimeDelta delay); - // Cancel any scheduled tasks to check again. - void CancelIfPending() { weak_ptr_factory.InvalidateWeakPtrs(); } + // Cancels any pending tasks to call Recheck again. + void CancelPendingRecheck(); + + // ash::SessionActivationObserver: + void OnSessionActivated(bool activated) override {} // Not needed. + void OnLockStateChanged(bool locked) override; + + // Ensures the singleton is initialized and started for the given profile. + static void StartForProfile(Profile* profile); + // Stops and deletes the Rechecker singleton. + static void Stop(); private: - base::WeakPtrFactory<RecheckTask> weak_ptr_factory{this}; + // The constructor and destructor also maintain the singleton instance. + Rechecker(Profile* profile, const AccountId& account_id); + ~Rechecker() override; + + // Singleton, since we only ever need one instance_ for the primary user. + static Rechecker* instance_; + + Profile* profile_; + const AccountId account_id_; + base::WeakPtrFactory<Rechecker> weak_ptr_factory_{this}; + + DISALLOW_COPY_AND_ASSIGN(Rechecker); }; -// Keep only a single instance of the RecheckTask, so that we can easily cancel -// all pending tasks just by invalidating weak pointers to this one task. -base::NoDestructor<RecheckTask> recheck_task_instance; +void Rechecker::Recheck() { + // This cancels any pending call to Recheck - we don't want some bug to cause + // us to queue up lots of calls to Recheck in the future, we only want one. + CancelPendingRecheck(); -} // namespace - -void MaybeShowSamlPasswordExpiryNotification(Profile* profile) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - // This cancels any pending RecheckTask - we don't want a situation where - // accidentally this function more than once means lots of identical - // RecheckTasks are added to the work queue. - recheck_task_instance->CancelIfPending(); - - // This could be run after a long delay. Check it still makes sense to run. - ProfileManager* profile_manager = g_browser_process->profile_manager(); - if (!profile_manager || !profile_manager->IsValidProfile(profile)) { + // In case the profile has been deleted since this task was posted. + if (!IsValidProfile(profile_)) { + delete this; // No need to keep calling recheck. return; } - PrefService* prefs = profile->GetPrefs(); + PrefService* prefs = profile_->GetPrefs(); SamlPasswordAttributes attrs = SamlPasswordAttributes::LoadFromPrefs(prefs); - if (!prefs->GetBoolean(prefs::kSamlInSessionPasswordChangeEnabled) || - !attrs.has_expiration_time()) { - // No information about password expiry, or this feature is disabled. - // Hide the notification (just in case it is shown) and return. - DismissSamlPasswordExpiryNotification(profile); + if (!IsEnabledForProfile(profile_) || !attrs.has_expiration_time()) { + // Feature is not enabled for this profile, or profile is not primary, or + // there is no expiration time. Dismiss if shown, and stop checking. + DismissSamlPasswordExpiryNotification(profile_); + delete this; return; } @@ -174,25 +186,95 @@ if (less_than_n_days <= advance_warning_days) { // The password is expired, or expires in less than |advance_warning_days|. // So we show a notification immediately. - ShowSamlPasswordExpiryNotification(profile, less_than_n_days); + ShowSamlPasswordExpiryNotification(profile_, less_than_n_days); // We check again whether to reshow / update the notification after one day: - recheck_task_instance->PostDelayed(profile, kOneDay); - return; + RecheckAfter(kOneDay); + + } else { + // We have not yet reached the advance warning threshold. Check again + // once we have arrived at expiry_time minus advance_warning_days... + base::TimeDelta recheck_delay = + time_until_expiry - base::TimeDelta::FromDays(advance_warning_days); + // But, wait an extra hour so that when this code is next run, it is clear + // we are now inside advance_warning_days (and not right on the boundary). + recheck_delay += kOneHour; + RecheckAfter(recheck_delay); + } +} + +void Rechecker::RecheckAfter(base::TimeDelta delay) { + base::PostDelayedTaskWithTraits( + FROM_HERE, kRecheckTaskTraits, + base::BindOnce(&Rechecker::Recheck, weak_ptr_factory_.GetWeakPtr()), + std::max(delay, kOneHour)); + // This always waits at least one hour before calling Recheck again - we don't + // want some bug to cause this code to run every millisecond. +} + +void Rechecker::CancelPendingRecheck() { + weak_ptr_factory_.InvalidateWeakPtrs(); +} + +void Rechecker::OnLockStateChanged(bool locked) { + if (!locked) { + // TODO(olsen): Reshow the notification when screen is unlocked. + } +} + +// static +void Rechecker::StartForProfile(Profile* profile) { + if (!instance_) { + const AccountId account_id = + ProfileHelper::Get()->GetUserByProfile(profile)->GetAccountId(); + new Rechecker(profile, account_id); + } + DCHECK(instance_ && instance_->profile_ == profile); + instance_->Recheck(); +} + +// static +void Rechecker::Stop() { + delete instance_; +} + +// static +Rechecker* Rechecker::instance_ = nullptr; + +Rechecker::Rechecker(Profile* profile, const AccountId& account_id) + : profile_(profile), account_id_(account_id) { + // There must not be an existing singleton instance. + DCHECK(!instance_); + instance_ = this; + + // Add |this| as a SessionActivationObserver to see when the screen is locked. + auto* session_controller = ash::SessionController::Get(); + if (session_controller) { + session_controller->AddSessionActivationObserverForAccountId(account_id_, + this); + } +} + +Rechecker::~Rechecker() { + // Remove this as a SessionActivationObserver. + auto* session_controller = ash::SessionController::Get(); + if (session_controller) { + session_controller->RemoveSessionActivationObserverForAccountId(account_id_, + this); } - // We have not yet reached the advance warning threshold. Run this code again - // once we have arrived at expiry_time minus advance_warning_days... - base::TimeDelta recheck_delay = - time_until_expiry - base::TimeDelta::FromDays(advance_warning_days); - // But, wait an extra hour so that when this code is next run, it is clear we - // are now inside advance_warning_days (and not right on the boundary). - recheck_delay += kOneHour; - // And never wait less than an hour before running again - we don't want some - // bug causing this code to run every millisecond... - recheck_delay = std::max(recheck_delay, kOneHour); + // This should still be the singleton instance. + DCHECK_EQ(this, instance_); + instance_ = nullptr; +} - // Check again whether to show notification after recheck_delay. - recheck_task_instance->PostDelayed(profile, recheck_delay); +} // namespace + +void MaybeShowSamlPasswordExpiryNotification(Profile* profile) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + if (IsEnabledForProfile(profile)) { + Rechecker::StartForProfile(profile); + } } void ShowSamlPasswordExpiryNotification(Profile* profile, @@ -202,9 +284,12 @@ const base::string16 title = GetTitleText(less_than_n_days); const base::string16 body = GetBodyText(less_than_n_days); + auto click_delegate = base::MakeRefCounted<HandleNotificationClickDelegate>( + base::BindRepeating(&PasswordChangeDialog::Show, profile)); + std::unique_ptr<Notification> notification = ash::CreateSystemNotification( kNotificationType, kNotificationId, title, body, *kDisplaySource, - *kOriginUrl, *kNotifierId, *kRichNotificationData, *kClickDelegate, kIcon, + *kOriginUrl, *kNotifierId, *kRichNotificationData, click_delegate, kIcon, kWarningLevel); NotificationDisplayServiceFactory::GetForProfile(profile)->Display( @@ -217,4 +302,9 @@ kNotificationHandlerType, kNotificationId); } +void ResetSamlPasswordExpiryNotificationForTesting() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + Rechecker::Stop(); +} + } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/saml/saml_password_expiry_notification.h b/chrome/browser/chromeos/login/saml/saml_password_expiry_notification.h index 45413f4..23f3a32 100644 --- a/chrome/browser/chromeos/login/saml/saml_password_expiry_notification.h +++ b/chrome/browser/chromeos/login/saml/saml_password_expiry_notification.h
@@ -26,6 +26,9 @@ // Hides the password expiry notification if it is currently shown. void DismissSamlPasswordExpiryNotification(Profile* profile); +// Stop waiting for the password to expire and free up any resources. +void ResetSamlPasswordExpiryNotificationForTesting(); + } // namespace chromeos #endif // CHROME_BROWSER_CHROMEOS_LOGIN_SAML_SAML_PASSWORD_EXPIRY_NOTIFICATION_H_
diff --git a/chrome/browser/chromeos/login/saml/saml_password_expiry_notification_unittest.cc b/chrome/browser/chromeos/login/saml/saml_password_expiry_notification_unittest.cc index 2b0a7b9..b542dfe 100644 --- a/chrome/browser/chromeos/login/saml/saml_password_expiry_notification_unittest.cc +++ b/chrome/browser/chromeos/login/saml/saml_password_expiry_notification_unittest.cc
@@ -7,6 +7,8 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/scoped_task_environment.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" +#include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/notifications/notification_display_service_impl.h" #include "chrome/browser/notifications/notification_display_service_tester.h" #include "chrome/browser/profiles/profile_manager.h" @@ -15,6 +17,8 @@ #include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile_manager.h" #include "chromeos/login/auth/saml_password_attributes.h" +#include "components/user_manager/scoped_user_manager.h" +#include "components/user_manager/user_names.h" #include "content/public/test/test_browser_thread_bundle.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -50,11 +54,22 @@ prefs::kSamlPasswordExpirationAdvanceWarningDays, kAdvanceWarningTime.InDays()); + std::unique_ptr<FakeChromeUserManager> fake_user_manager = + std::make_unique<FakeChromeUserManager>(); + fake_user_manager->AddUser(user_manager::StubAccountId()); + fake_user_manager->LoginUser(user_manager::StubAccountId()); + ASSERT_TRUE(fake_user_manager->GetPrimaryUser()); + scoped_user_manager_ = std::make_unique<user_manager::ScopedUserManager>( + std::move(fake_user_manager)); + display_service_tester_ = std::make_unique<NotificationDisplayServiceTester>(profile_); } - void TearDown() override { display_service_tester_.reset(); } + void TearDown() override { + display_service_tester_.reset(); + ResetSamlPasswordExpiryNotificationForTesting(); + } protected: base::Optional<Notification> Notification() { @@ -78,6 +93,8 @@ base::test::ScopedTaskEnvironment::NowSource::MAIN_THREAD_MOCK_TIME}; TestingProfileManager profile_manager_{TestingBrowserProcess::GetGlobal()}; TestingProfile* profile_; + + std::unique_ptr<user_manager::ScopedUserManager> scoped_user_manager_; std::unique_ptr<NotificationDisplayServiceTester> display_service_tester_; };
diff --git a/chrome/browser/chromeos/login/test/active_directory_login_mixin.cc b/chrome/browser/chromeos/login/test/active_directory_login_mixin.cc index 00011277..7eea554 100644 --- a/chrome/browser/chromeos/login/test/active_directory_login_mixin.cc +++ b/chrome/browser/chromeos/login/test/active_directory_login_mixin.cc
@@ -4,6 +4,9 @@ #include "chrome/browser/chromeos/login/test/active_directory_login_mixin.h" +#include <initializer_list> + +#include "base/strings/string_piece.h" #include "chrome/browser/chromeos/login/login_shelf_test_helper.h" #include "chrome/browser/chromeos/login/test/js_checker.h" #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h" @@ -18,7 +21,8 @@ namespace { -constexpr char kGaiaSigninId[] = "signin-frame-dialog"; +constexpr char kGaiaSigninId[] = "gaia-signin"; +constexpr char kGaiaSigninDialogId[] = "signin-frame-dialog"; constexpr char kAdOfflineAuthId[] = "offline-ad-auth"; constexpr char kAdMachineInput[] = "machineNameInput"; @@ -39,6 +43,23 @@ constexpr char kNavigationId[] = "navigation"; constexpr char kCloseButtonId[] = "closeButton"; +void ExpectValid(std::initializer_list<base::StringPiece> element_ids, + bool valid) { + std::string js = test::GetOobeElementPath(element_ids) + ".invalid"; + if (valid) + test::OobeJS().ExpectFalse(js); + else + test::OobeJS().ExpectTrue(js); +} + +// Returns string representing element that matches the given selector applied +// to the specified parent element. +std::string JSElement( + std::initializer_list<base::StringPiece> parent_element_path, + const std::string& selector) { + return test::GetOobeElementPath(parent_element_path) + "." + selector; +} + } // namespace ActiveDirectoryLoginMixin::ActiveDirectoryLoginMixin( @@ -77,32 +98,27 @@ test::OobeJS().TapOnPath({kPasswordChangeId, kNavigationId, kCloseButtonId}); } -void ActiveDirectoryLoginMixin::ExpectValid(const std::string& parent_id, - const std::string& child_id, - bool valid) { - std::string js = test::GetOobeElementPath({parent_id, child_id}) + ".invalid"; - if (valid) - test::OobeJS().ExpectFalse(js); - else - test::OobeJS().ExpectTrue(js); -} - // Checks if Active Directory login is visible. void ActiveDirectoryLoginMixin::TestLoginVisible() { OobeScreenWaiter screen_waiter(GaiaView::kScreenId); screen_waiter.Wait(); // Checks if Gaia signin is hidden. - test::OobeJS().ExpectHidden(kGaiaSigninId); + test::OobeJS().ExpectHiddenPath({kGaiaSigninId, kGaiaSigninDialogId}); // Checks if Active Directory signin is visible. - test::OobeJS().ExpectVisible(kAdOfflineAuthId); - test::OobeJS().ExpectHiddenPath({kAdOfflineAuthId, kAdMachineInput}); - test::OobeJS().ExpectHiddenPath({kAdOfflineAuthId, kAdMoreOptionsButton}); - test::OobeJS().ExpectVisiblePath({kAdOfflineAuthId, kAdUserInput}); - test::OobeJS().ExpectVisiblePath({kAdOfflineAuthId, kAdPasswordInput}); + test::OobeJS().ExpectVisiblePath({kGaiaSigninId, kAdOfflineAuthId}); + test::OobeJS().ExpectHiddenPath( + {kGaiaSigninId, kAdOfflineAuthId, kAdMachineInput}); + test::OobeJS().ExpectHiddenPath( + {kGaiaSigninId, kAdOfflineAuthId, kAdMoreOptionsButton}); + test::OobeJS().ExpectVisiblePath( + {kGaiaSigninId, kAdOfflineAuthId, kAdUserInput}); + test::OobeJS().ExpectVisiblePath( + {kGaiaSigninId, kAdOfflineAuthId, kAdPasswordInput}); test::OobeJS().ExpectEQ( - JSElement(kAdOfflineAuthId, kAdAutocompleteRealm) + ".innerText.trim()", + JSElement({kGaiaSigninId, kAdOfflineAuthId}, kAdAutocompleteRealm) + + ".innerText.trim()", autocomplete_realm_); EXPECT_TRUE(LoginShelfTestHelper().IsLoginShelfShown()); @@ -111,7 +127,7 @@ // Checks if Active Directory password change screen is shown. void ActiveDirectoryLoginMixin::TestPasswordChangeVisible() { // Checks if Gaia signin is hidden. - test::OobeJS().ExpectHidden(kGaiaSigninId); + test::OobeJS().ExpectHiddenPath({kGaiaSigninId, kGaiaSigninDialogId}); // Checks if Active Directory signin is visible. test::OobeJS().ExpectVisible(kPasswordChangeId); test::OobeJS().ExpectTrue( @@ -124,43 +140,47 @@ // Checks if user input is marked as invalid. void ActiveDirectoryLoginMixin::TestUserError() { TestLoginVisible(); - ExpectValid(kAdOfflineAuthId, kAdUserInput, false); + ExpectValid({kGaiaSigninId, kAdOfflineAuthId, kAdUserInput}, false); } void ActiveDirectoryLoginMixin::SetUserInput(const std::string& value) { - test::OobeJS().TypeIntoPath(value, {kAdOfflineAuthId, kAdUserInput}); + test::OobeJS().TypeIntoPath(value, + {kGaiaSigninId, kAdOfflineAuthId, kAdUserInput}); } void ActiveDirectoryLoginMixin::TestUserInput(const std::string& value) { - test::OobeJS().ExpectEQ( - test::GetOobeElementPath({kAdOfflineAuthId, kAdUserInput}) + ".value", - value); + test::OobeJS().ExpectEQ(test::GetOobeElementPath( + {kGaiaSigninId, kAdOfflineAuthId, kAdUserInput}) + + ".value", + value); } // Checks if password input is marked as invalid. void ActiveDirectoryLoginMixin::TestPasswordError() { TestLoginVisible(); - ExpectValid(kAdOfflineAuthId, kAdPasswordInput, false); + ExpectValid({kGaiaSigninId, kAdOfflineAuthId, kAdPasswordInput}, false); } // Checks that machine, password and user inputs are valid. void ActiveDirectoryLoginMixin::TestNoError() { TestLoginVisible(); - ExpectValid(kAdOfflineAuthId, kAdMachineInput, true); - ExpectValid(kAdOfflineAuthId, kAdUserInput, true); - ExpectValid(kAdOfflineAuthId, kAdPasswordInput, true); + ExpectValid({kGaiaSigninId, kAdOfflineAuthId, kAdMachineInput}, true); + ExpectValid({kGaiaSigninId, kAdOfflineAuthId, kAdUserInput}, true); + ExpectValid({kGaiaSigninId, kAdOfflineAuthId, kAdPasswordInput}, true); } // Checks if autocomplete domain is visible for the user input. void ActiveDirectoryLoginMixin::TestDomainVisible() { test::OobeJS().ExpectTrue( - "!" + JSElement(kAdOfflineAuthId, kAdAutocompleteRealm) + ".hidden"); + "!" + JSElement({kGaiaSigninId, kAdOfflineAuthId}, kAdAutocompleteRealm) + + ".hidden"); } // Checks if autocomplete domain is hidden for the user input. void ActiveDirectoryLoginMixin::TestDomainHidden() { - test::OobeJS().ExpectTrue(JSElement(kAdOfflineAuthId, kAdAutocompleteRealm) + - ".hidden"); + test::OobeJS().ExpectTrue( + JSElement({kGaiaSigninId, kAdOfflineAuthId}, kAdAutocompleteRealm) + + ".hidden"); } void ActiveDirectoryLoginMixin::TestPasswordChangeNoErrors() { @@ -198,9 +218,11 @@ void ActiveDirectoryLoginMixin::SubmitActiveDirectoryCredentials( const std::string& username, const std::string& password) { - test::OobeJS().TypeIntoPath(username, {kAdOfflineAuthId, kAdUserInput}); - test::OobeJS().TypeIntoPath(password, {kAdOfflineAuthId, kAdPasswordInput}); - test::OobeJS().TapOnPath({kAdOfflineAuthId, kAdCredsButton}); + test::OobeJS().TypeIntoPath(username, + {kGaiaSigninId, kAdOfflineAuthId, kAdUserInput}); + test::OobeJS().TypeIntoPath( + password, {kGaiaSigninId, kAdOfflineAuthId, kAdPasswordInput}); + test::OobeJS().TapOnPath({kGaiaSigninId, kAdOfflineAuthId, kAdCredsButton}); } // Sets username and password for the Active Directory login and submits it. @@ -235,13 +257,6 @@ } while (message != expected_message); } -// Returns string representing element with id=|element_id| inside Active -// Directory login element. -std::string ActiveDirectoryLoginMixin::JSElement(const std::string& parent_id, - const std::string& selector) { - return "document.querySelector('#" + parent_id + "')." + selector; -} - ActiveDirectoryLoginMixin::~ActiveDirectoryLoginMixin() = default; } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/test/active_directory_login_mixin.h b/chrome/browser/chromeos/login/test/active_directory_login_mixin.h index 85fa9cba..2d6acf5 100644 --- a/chrome/browser/chromeos/login/test/active_directory_login_mixin.h +++ b/chrome/browser/chromeos/login/test/active_directory_login_mixin.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_CHROMEOS_LOGIN_TEST_ACTIVE_DIRECTORY_LOGIN_MIXIN_H_ #include <memory> +#include <string> #include "base/macros.h" #include "base/values.h" @@ -75,13 +76,6 @@ private: void SetupActiveDirectoryJSNotifications(); void TestPasswordChangeError(const std::string& invalid_element); - void ExpectValid(const std::string& parent_id, - const std::string& child_id, - bool valid); - // Returns string representing element with id=|element_id| inside Active - // Directory login element. - std::string JSElement(const std::string& parent_id, - const std::string& selector); std::string autocomplete_realm_; std::unique_ptr<content::DOMMessageQueue> message_queue_;
diff --git a/chrome/browser/chromeos/login/test/enrollment_ui_mixin.cc b/chrome/browser/chromeos/login/test/enrollment_ui_mixin.cc index af60a5a9..7a1d6f4f 100644 --- a/chrome/browser/chromeos/login/test/enrollment_ui_mixin.cc +++ b/chrome/browser/chromeos/login/test/enrollment_ui_mixin.cc
@@ -7,6 +7,7 @@ #include "chrome/browser/chromeos/login/enrollment/enrollment_screen.h" #include "chrome/browser/chromeos/login/test/js_checker.h" #include "chrome/browser/chromeos/login/test/test_predicate_waiter.h" +#include "chrome/browser/chromeos/login/wizard_controller.h" #include "ui/base/l10n/l10n_util.h" namespace chromeos { @@ -122,5 +123,35 @@ OobeJS().TapOn("enroll-attributes-submit-button"); } +void EnrollmentUIMixin::SetExitHandler() { + ASSERT_NE(WizardController::default_controller(), nullptr); + EnrollmentScreen* enrollment_screen = EnrollmentScreen::Get( + WizardController::default_controller()->screen_manager()); + ASSERT_NE(enrollment_screen, nullptr); + enrollment_screen->set_exit_callback_for_testing(base::BindRepeating( + &EnrollmentUIMixin::HandleScreenExit, base::Unretained(this))); +} + +EnrollmentScreen::Result EnrollmentUIMixin::WaitForScreenExit() { + if (screen_result_.has_value()) + return screen_result_.value(); + + DCHECK(!screen_exit_waiter_.has_value()); + screen_exit_waiter_.emplace(); + screen_exit_waiter_->Run(); + DCHECK(screen_result_.has_value()); + EnrollmentScreen::Result result = screen_result_.value(); + screen_result_.reset(); + screen_exit_waiter_.reset(); + return result; +} + +void EnrollmentUIMixin::HandleScreenExit(EnrollmentScreen::Result result) { + EXPECT_FALSE(screen_result_.has_value()); + screen_result_ = result; + if (screen_exit_waiter_) + screen_exit_waiter_->Quit(); +} + } // namespace test } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/test/enrollment_ui_mixin.h b/chrome/browser/chromeos/login/test/enrollment_ui_mixin.h index 7eb6ada3c..f27102f6 100644 --- a/chrome/browser/chromeos/login/test/enrollment_ui_mixin.h +++ b/chrome/browser/chromeos/login/test/enrollment_ui_mixin.h
@@ -8,6 +8,8 @@ #include <string> #include "base/macros.h" +#include "base/optional.h" +#include "chrome/browser/chromeos/login/enrollment/enrollment_screen.h" #include "chrome/browser/chromeos/login/mixin_based_in_process_browser_test.h" namespace chromeos { @@ -68,7 +70,18 @@ // Proceeds with selected license. void UseSelectedLicense(); + void SetExitHandler(); + // Runs loop until the enrollment screen reports exit. It will return the + // last result returned by the enrollment screen. + // NOTE: Please call SetExitHandler above before cancelling the screen. + EnrollmentScreen::Result WaitForScreenExit(); + private: + base::Optional<EnrollmentScreen::Result> screen_result_; + base::Optional<base::RunLoop> screen_exit_waiter_; + + void HandleScreenExit(EnrollmentScreen::Result result); + DISALLOW_COPY_AND_ASSIGN(EnrollmentUIMixin); };
diff --git a/chrome/browser/chromeos/login/test/offline_gaia_test_mixin.cc b/chrome/browser/chromeos/login/test/offline_gaia_test_mixin.cc index a308ed7..052bda24 100644 --- a/chrome/browser/chromeos/login/test/offline_gaia_test_mixin.cc +++ b/chrome/browser/chromeos/login/test/offline_gaia_test_mixin.cc
@@ -95,30 +95,40 @@ .CreateWaiter("window.$ && $('error-offline-login-link')") ->Wait(); test::ExecuteOobeJS("$('error-offline-login-link').onclick();"); - test::OobeJS().CreateVisibilityWaiter(true, {"offline-gaia"})->Wait(); + test::OobeJS() + .CreateVisibilityWaiter(true, {"gaia-signin", "offline-gaia"}) + ->Wait(); } void OfflineGaiaTestMixin::SubmitGaiaAuthOfflineForm( const std::string& user_email, const std::string& password) { - test::OobeJS().ExpectVisible("offline-gaia"); - test::OobeJS().ExpectHidden("signin-frame"); + test::OobeJS().ExpectVisiblePath({"gaia-signin", "offline-gaia"}); + test::OobeJS().ExpectHiddenPath({"gaia-signin", "signin-frame"}); test::OobeJS() - .CreateDisplayedWaiter(true, {"offline-gaia", "email-section"}) + .CreateDisplayedWaiter(true, + {"gaia-signin", "offline-gaia", "email-section"}) ->Wait(); test::OobeJS() - .CreateDisplayedWaiter(false, {"offline-gaia", "password-section"}) + .CreateDisplayedWaiter( + false, {"gaia-signin", "offline-gaia", "password-section"}) ->Wait(); - test::OobeJS().TypeIntoPath(user_email, {"offline-gaia", "emailInput"}); - test::OobeJS().TapOnPath({"offline-gaia", "email-input-form", "button"}); + test::OobeJS().TypeIntoPath(user_email, + {"gaia-signin", "offline-gaia", "emailInput"}); + test::OobeJS().TapOnPath( + {"gaia-signin", "offline-gaia", "email-input-form", "button"}); test::OobeJS() - .CreateDisplayedWaiter(false, {"offline-gaia", "email-section"}) + .CreateDisplayedWaiter(false, + {"gaia-signin", "offline-gaia", "email-section"}) ->Wait(); test::OobeJS() - .CreateDisplayedWaiter(true, {"offline-gaia", "password-section"}) + .CreateDisplayedWaiter( + true, {"gaia-signin", "offline-gaia", "password-section"}) ->Wait(); - test::OobeJS().TypeIntoPath(password, {"offline-gaia", "passwordInput"}); - test::OobeJS().TapOnPath({"offline-gaia", "password-input-form", "button"}); + test::OobeJS().TypeIntoPath(password, + {"gaia-signin", "offline-gaia", "passwordInput"}); + test::OobeJS().TapOnPath( + {"gaia-signin", "offline-gaia", "password-input-form", "button"}); } } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/test/oobe_screens_utils.cc b/chrome/browser/chromeos/login/test/oobe_screens_utils.cc new file mode 100644 index 0000000..1300183 --- /dev/null +++ b/chrome/browser/chromeos/login/test/oobe_screens_utils.cc
@@ -0,0 +1,165 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/login/test/oobe_screens_utils.h" + +#include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/chromeos/login/oobe_screen.h" +#include "chrome/browser/chromeos/login/screens/sync_consent_screen.h" +#include "chrome/browser/chromeos/login/screens/update_screen.h" +#include "chrome/browser/chromeos/login/test/js_checker.h" +#include "chrome/browser/chromeos/login/test/oobe_screen_exit_waiter.h" +#include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h" +#include "chrome/browser/chromeos/login/test/test_condition_waiter.h" +#include "chrome/browser/chromeos/login/wizard_controller.h" +#include "chrome/browser/ui/webui/chromeos/login/discover_screen_handler.h" +#include "chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h" +#include "chrome/browser/ui/webui/chromeos/login/eula_screen_handler.h" +#include "chrome/browser/ui/webui/chromeos/login/fingerprint_setup_screen_handler.h" +#include "chrome/browser/ui/webui/chromeos/login/network_screen_handler.h" +#include "chrome/browser/ui/webui/chromeos/login/update_screen_handler.h" +#include "chrome/browser/ui/webui/chromeos/login/welcome_screen_handler.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/test_utils.h" + +namespace chromeos { +namespace test { + +namespace { + +void WaitFor(OobeScreenId screen_id) { + OobeScreenWaiter(screen_id).Wait(); + LOG(INFO) << "Switched to '" << screen_id.name << "' screen."; +} + +void WaitForExit(OobeScreenId screen_id) { + OobeScreenExitWaiter(screen_id).Wait(); + LOG(INFO) << "Screen '" << screen_id.name << "' is done."; +} + +} // namespace + +void WaitForWelcomeScreen() { + content::WindowedNotificationObserver observer( + chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, + content::NotificationService::AllSources()); + observer.Wait(); + WaitFor(WelcomeView::kScreenId); +} + +void TapWelcomeNext() { + test::OobeJS().TapOnPath({"connect", "welcomeScreen", "welcomeNextButton"}); +} + +void WaitForNetworkSelectionScreen() { + WaitFor(NetworkScreenView::kScreenId); +} + +void TapNetworkSelectionNext() { + test::OobeJS().TapOnPath({"oobe-network-md", "nextButton"}); +} + +void WaitForUpdateScreen() { + WaitFor(UpdateView::kScreenId); + test::OobeJS().CreateVisibilityWaiter(true, {"update"})->Wait(); +} + +void ExitUpdateScreenNoUpdate() { + UpdateEngineClient::Status status; + status.status = UpdateEngineClient::UPDATE_STATUS_ERROR; + + UpdateScreen* screen = UpdateScreen::Get( + WizardController::default_controller()->screen_manager()); + screen->UpdateStatusChanged(status); +} + +void WaitForFingerprintScreen() { + LOG(INFO) << "Waiting for 'fingerprint-setup' screen."; + OobeScreenWaiter(FingerprintSetupScreenView::kScreenId).Wait(); + LOG(INFO) << "Waiting for fingerprint setup screen " + "to show."; + test::OobeJS().CreateVisibilityWaiter(true, {"fingerprint-setup"})->Wait(); + LOG(INFO) << "Waiting for fingerprint setup screen " + "to initializes."; + test::OobeJS() + .CreateVisibilityWaiter(true, {"fingerprint-setup-impl"}) + ->Wait(); + LOG(INFO) << "Waiting for fingerprint setup screen " + "to show setupFingerprint."; + test::OobeJS() + .CreateVisibilityWaiter(true, + {"fingerprint-setup-impl", "setupFingerprint"}) + ->Wait(); +} + +void ExitFingerprintPinSetupScreen() { + test::OobeJS().ExpectVisiblePath({"fingerprint-setup-impl", "placeFinger"}); + // This might be the last step in flow. Synchronous execute gets stuck as + // WebContents may be destroyed in the process. So it may never return. + // So we use ExecuteAsync() here. + test::OobeJS().ExecuteAsync( + "$('fingerprint-setup-impl').$.setupFingerprintLater.click()"); + LOG(INFO) << "OobeInteractiveUITest: Waiting for fingerprint setup screen " + "to close."; + WaitForExit(FingerprintSetupScreenView::kScreenId); +} + +void WaitForDiscoverScreen() { + WaitFor(DiscoverScreenView::kScreenId); +} + +void ExitDiscoverPinSetupScreen() { + // This might be the last step in flow. Synchronous execute gets stuck as + // WebContents may be destroyed in the process. So it may never return. + // So we use ExecuteAsync() here. + test::OobeJS().ExecuteAsync( + "$('discover-impl').root.querySelector('discover-pin-setup-module')." + "$.setupSkipButton.click()"); + WaitForExit(DiscoverScreenView::kScreenId); +} + +void SkipToEnrollmentOnRecovery() { + test::WaitForWelcomeScreen(); + test::TapWelcomeNext(); + + test::WaitForNetworkSelectionScreen(); + test::TapNetworkSelectionNext(); + +#if defined(GOOGLE_CHROME_BUILD) + WaitForEulaScreen(); + TapEulaAccept(); +#endif + + test::WaitForUpdateScreen(); + test::ExitUpdateScreenNoUpdate(); + + WaitFor(EnrollmentScreenView::kScreenId); +} + +#if defined(GOOGLE_CHROME_BUILD) +void WaitForEulaScreen() { + WaitFor(EulaView::kScreenId); +} + +void TapEulaAccept() { + test::OobeJS().TapOnPath({"oobe-eula-md", "acceptButton"}); +} + +void WaitForSyncConsentScreen() { + WaitFor(SyncConsentScreenView::kScreenId); +} + +void ExitScreenSyncConsent() { + SyncConsentScreen* screen = static_cast<SyncConsentScreen*>( + WizardController::default_controller()->GetScreen( + SyncConsentScreenView::kScreenId)); + + screen->SetProfileSyncDisabledByPolicyForTesting(true); + screen->OnStateChanged(nullptr); + WaitForExit(SyncConsentScreenView::kScreenId); +} +#endif + +} // namespace test +} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/test/oobe_screens_utils.h b/chrome/browser/chromeos/login/test/oobe_screens_utils.h new file mode 100644 index 0000000..678cdc6 --- /dev/null +++ b/chrome/browser/chromeos/login/test/oobe_screens_utils.h
@@ -0,0 +1,34 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_TEST_OOBE_SCREENS_UTILS_H_ +#define CHROME_BROWSER_CHROMEOS_LOGIN_TEST_OOBE_SCREENS_UTILS_H_ + +namespace chromeos { +namespace test { + +// TODO(rsorokin): Move all these functions into a Mixin. +void WaitForWelcomeScreen(); +void TapWelcomeNext(); +void WaitForNetworkSelectionScreen(); +void TapNetworkSelectionNext(); +void WaitForUpdateScreen(); +void ExitUpdateScreenNoUpdate(); +void WaitForFingerprintScreen(); +void ExitFingerprintPinSetupScreen(); +void WaitForDiscoverScreen(); +void ExitDiscoverPinSetupScreen(); +void SkipToEnrollmentOnRecovery(); + +#if defined(GOOGLE_CHROME_BUILD) +void WaitForEulaScreen(); +void TapEulaAccept(); +void WaitForSyncConsentScreen(); +void ExitScreenSyncConsent(); +#endif + +} // namespace test +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_LOGIN_TEST_OOBE_SCREENS_UTILS_H_
diff --git a/chrome/browser/chromeos/login/webview_login_browsertest.cc b/chrome/browser/chromeos/login/webview_login_browsertest.cc index 2f06ef7..6753eb2 100644 --- a/chrome/browser/chromeos/login/webview_login_browsertest.cc +++ b/chrome/browser/chromeos/login/webview_login_browsertest.cc
@@ -2,6 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <initializer_list> +#include <iterator> +#include <string> + #include "base/bind.h" #include "base/callback.h" #include "base/files/file_util.h" @@ -9,6 +13,7 @@ #include "base/json/json_writer.h" #include "base/macros.h" #include "base/run_loop.h" +#include "base/strings/string_piece.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/task/post_task.h" @@ -181,16 +186,18 @@ protected: void ExpectIdentifierPage() { // First page: back button, #identifier input field. - test::OobeJS().ExpectVisible("signin-back-button"); + test::OobeJS().ExpectVisiblePath({"gaia-signin", "signin-back-button"}); test::OobeJS().ExpectTrue( - "$('signin-frame').src.indexOf('#identifier') != -1"); + test::GetOobeElementPath({"gaia-signin", "signin-frame"}) + + ".src.indexOf('#identifier') != -1"); } void ExpectPasswordPage() { // Second page: back button, #challengepassword input field. - test::OobeJS().ExpectVisible("signin-back-button"); + test::OobeJS().ExpectVisiblePath({"gaia-signin", "signin-back-button"}); test::OobeJS().ExpectTrue( - "$('signin-frame').src.indexOf('#challengepassword') != -1"); + test::GetOobeElementPath({"gaia-signin", "signin-frame"}) + + ".src.indexOf('#challengepassword') != -1"); } bool WebViewVisited(content::BrowserContext* browser_context, @@ -270,7 +277,7 @@ ExpectPasswordPage(); // Click back to identifier page. - test::OobeJS().TapOn("signin-back-button"); + test::OobeJS().TapOnPath({"gaia-signin", "signin-back-button"}); WaitForGaiaPageBackButtonUpdate(); ExpectIdentifierPage(); // Click next to password page, user id is remembered. @@ -326,8 +333,8 @@ content::WebContents* web_contents = GetLoginUI()->GetWebContents(); content::BrowserContext* browser_context = web_contents->GetBrowserContext(); - std::string signin_frame_partition_name_1 = - test::OobeJS().GetString("$('signin-frame').partition"); + std::string signin_frame_partition_name_1 = test::OobeJS().GetString( + test::GetOobeElementPath({"gaia-signin", "signin-frame"}) + ".partition"); content::StoragePartition* signin_frame_partition_1 = login::GetSigninPartition(); @@ -344,14 +351,14 @@ // Press the back button at a sign-in screen without pre-existing users to // start a new sign-in attempt. - test::OobeJS().TapOn("signin-back-button"); + test::OobeJS().TapOnPath({"gaia-signin", "signin-back-button"}); WaitForGaiaPageBackButtonUpdate(); // Expect that we got back to the identifier page, as there are no known users // so the sign-in screen will not display user pods. ExpectIdentifierPage(); - std::string signin_frame_partition_name_2 = - test::OobeJS().GetString("$('signin-frame').partition"); + std::string signin_frame_partition_name_2 = test::OobeJS().GetString( + test::GetOobeElementPath({"gaia-signin", "signin-frame"}) + ".partition"); content::StoragePartition* signin_frame_partition_2 = login::GetSigninPartition(); @@ -486,9 +493,10 @@ ASSERT_TRUE(https_server_->Start()); } - // Requests |http_server_|'s client-cert test page in the webview with the id - // |webview_id|. Returns the content of the client-cert test page. - std::string RequestClientCertTestPageInFrame(const std::string& webview_id) { + // Requests |http_server_|'s client-cert test page in the webview specified by + // the given |webview_path|. Returns the content of the client-cert test page. + std::string RequestClientCertTestPageInFrame( + std::initializer_list<base::StringPiece> webview_path) { const GURL url = https_server_->GetURL("client-cert"); content::TestNavigationObserver navigation_observer(url); navigation_observer.WatchExistingWebContents(); @@ -498,11 +506,13 @@ // If you see this after April 2019, please ping the owner of the above bug. LOG(INFO) << "Triggering navigation to " << url.spec() << "."; test::OobeJS().Evaluate(base::StringPrintf( - "$('%s').src='%s'", webview_id.c_str(), url.spec().c_str())); + "%s.src='%s'", test::GetOobeElementPath(webview_path).c_str(), + url.spec().c_str())); navigation_observer.Wait(); LOG(INFO) << "Navigation done."; content::WebContents* main_web_contents = GetLoginUI()->GetWebContents(); + const std::string webview_id = std::prev(webview_path.end())->as_string(); content::WebContents* frame_web_contents = signin::GetAuthFrameWebContents(main_web_contents, webview_id); test::JSChecker frame_js_checker(frame_web_contents); @@ -629,7 +639,7 @@ WaitForGaiaPageLoadAndPropertyUpdate(); const std::string https_reply_content = - RequestClientCertTestPageInFrame(gaia_frame_parent_); + RequestClientCertTestPageInFrame({"gaia-signin", gaia_frame_parent_}); EXPECT_EQ( "got client cert with fingerprint: " "c66145f49caca4d1325db96ace0f12f615ba4981", @@ -661,7 +671,7 @@ WaitForGaiaPageLoadAndPropertyUpdate(); const std::string https_reply_content = - RequestClientCertTestPageInFrame(gaia_frame_parent_); + RequestClientCertTestPageInFrame({"gaia-signin", gaia_frame_parent_}); EXPECT_EQ( "got client cert with fingerprint: " "c66145f49caca4d1325db96ace0f12f615ba4981", @@ -687,7 +697,7 @@ WaitForGaiaPageLoadAndPropertyUpdate(); const std::string https_reply_content = - RequestClientCertTestPageInFrame(gaia_frame_parent_); + RequestClientCertTestPageInFrame({"gaia-signin", gaia_frame_parent_}); EXPECT_EQ("got no client cert", https_reply_content); } @@ -718,7 +728,7 @@ WaitForGaiaPageLoadAndPropertyUpdate(); const std::string https_reply_content = - RequestClientCertTestPageInFrame(gaia_frame_parent_); + RequestClientCertTestPageInFrame({"gaia-signin", gaia_frame_parent_}); EXPECT_EQ( "got client cert with fingerprint: " "c66145f49caca4d1325db96ace0f12f615ba4981", @@ -754,7 +764,7 @@ WaitForGaiaPageLoadAndPropertyUpdate(); const std::string https_reply_content = - RequestClientCertTestPageInFrame(gaia_frame_parent_); + RequestClientCertTestPageInFrame({"gaia-signin", gaia_frame_parent_}); EXPECT_EQ("got no client cert", https_reply_content); } @@ -788,7 +798,7 @@ WaitForGaiaPageLoadAndPropertyUpdate(); const std::string https_reply_content = - RequestClientCertTestPageInFrame(gaia_frame_parent_); + RequestClientCertTestPageInFrame({"gaia-signin", gaia_frame_parent_}); EXPECT_EQ("got no client cert", https_reply_content); } @@ -826,7 +836,7 @@ WaitForGaiaPageLoadAndPropertyUpdate(); const std::string https_reply_content = - RequestClientCertTestPageInFrame(gaia_frame_parent_); + RequestClientCertTestPageInFrame({"gaia-signin", gaia_frame_parent_}); EXPECT_EQ( "got client cert with fingerprint: " "c66145f49caca4d1325db96ace0f12f615ba4981", @@ -853,7 +863,7 @@ // Use |watch_new_webcontents| because the EULA webview has not navigated yet. const std::string https_reply_content = - RequestClientCertTestPageInFrame("cros-eula-frame"); + RequestClientCertTestPageInFrame({"cros-eula-frame"}); EXPECT_EQ("got no client cert", https_reply_content); } @@ -1012,7 +1022,7 @@ // start a new sign-in attempt. // This will re-load gaia, rotating the StoragePartition. The new // StoragePartition must also have the proxy auth details. - test::OobeJS().TapOn("signin-back-button"); + test::OobeJS().TapOnPath({"gaia-signin", "signin-back-button"}); WaitForGaiaPageBackButtonUpdate(); // Expect that we got back to the identifier page, as there are no known users // so the sign-in screen will not display user pods.
diff --git a/chrome/browser/chromeos/wilco_dtc_supportd/wilco_dtc_supportd_web_request_service.cc b/chrome/browser/chromeos/wilco_dtc_supportd/wilco_dtc_supportd_web_request_service.cc index 8a7da21..7110dbe 100644 --- a/chrome/browser/chromeos/wilco_dtc_supportd/wilco_dtc_supportd_web_request_service.cc +++ b/chrome/browser/chromeos/wilco_dtc_supportd/wilco_dtc_supportd_web_request_service.cc
@@ -242,8 +242,8 @@ // Got a network error. if (net_error != net::OK && (response_code == -1 || IsHttpOkCode(response_code))) { - DVLOG(0) << "Web request failed with error: " << net_error - << net::ErrorToString(net_error); + VLOG(0) << "Web request failed with error: " << net_error << " " + << net::ErrorToString(net_error); std::move(active_request_->callback) .Run(wilco_dtc_supportd::mojom::WilcoDtcSupportdWebRequestStatus:: kNetworkError,
diff --git a/chrome/browser/component_updater/supervised_user_whitelist_installer.cc b/chrome/browser/component_updater/supervised_user_whitelist_installer.cc index 1602881..d4703e66 100644 --- a/chrome/browser/component_updater/supervised_user_whitelist_installer.cc +++ b/chrome/browser/component_updater/supervised_user_whitelist_installer.cc
@@ -182,8 +182,9 @@ data_decoder::JsonSanitizer::Sanitize( content::ServiceManagerConnection::GetForProcess()->GetConnector(), unsafe_json, - base::Bind(&OnWhitelistSanitizationResult, crx_id, task_runner, callback), - base::Bind(&OnWhitelistSanitizationError, whitelist_path)); + base::BindOnce(&OnWhitelistSanitizationResult, crx_id, task_runner, + callback), + base::BindOnce(&OnWhitelistSanitizationError, whitelist_path)); } void RemoveUnregisteredWhitelistsOnTaskRunner(
diff --git a/chrome/browser/extensions/api/autofill_private/autofill_private_event_router.cc b/chrome/browser/extensions/api/autofill_private/autofill_private_event_router.cc index c90d6a5..402330b 100644 --- a/chrome/browser/extensions/api/autofill_private/autofill_private_event_router.cc +++ b/chrome/browser/extensions/api/autofill_private/autofill_private_event_router.cc
@@ -50,7 +50,6 @@ personal_data_->RemoveObserver(this); } -// TODO(crbug.com/923868): Change the 2 calls to a single OnPersonalDataChanged. void AutofillPrivateEventRouter::OnPersonalDataChanged() { // Ignore any updates before data is loaded. This can happen in tests. if (!(personal_data_ && personal_data_->IsDataLoaded())) @@ -58,24 +57,19 @@ autofill_util::AddressEntryList addressList = extensions::autofill_util::GenerateAddressList(*personal_data_); - std::unique_ptr<base::ListValue> args( - api::autofill_private::OnAddressListChanged::Create(addressList) - .release()); - std::unique_ptr<Event> extension_event( - new Event(events::AUTOFILL_PRIVATE_ON_ADDRESS_LIST_CHANGED, - api::autofill_private::OnAddressListChanged::kEventName, - std::move(args))); - event_router_->BroadcastEvent(std::move(extension_event)); autofill_util::CreditCardEntryList creditCardList = extensions::autofill_util::GenerateCreditCardList(*personal_data_); - args.reset( - api::autofill_private::OnCreditCardListChanged::Create(creditCardList) + + std::unique_ptr<base::ListValue> args( + api::autofill_private::OnPersonalDataChanged::Create(addressList, creditCardList) .release()); - extension_event.reset( - new Event(events::AUTOFILL_PRIVATE_ON_CREDIT_CARD_LIST_CHANGED, - api::autofill_private::OnCreditCardListChanged::kEventName, + + std::unique_ptr<Event> extension_event( + new Event(events::AUTOFILL_PRIVATE_ON_PERSONAL_DATA_CHANGED, + api::autofill_private::OnPersonalDataChanged::kEventName, std::move(args))); + event_router_->BroadcastEvent(std::move(extension_event)); }
diff --git a/chrome/browser/extensions/api/history/history_api.cc b/chrome/browser/extensions/api/history/history_api.cc index 673a962..010b847 100644 --- a/chrome/browser/extensions/api/history/history_api.cc +++ b/chrome/browser/extensions/api/history/history_api.cc
@@ -307,20 +307,19 @@ history::HistoryService* hs = HistoryServiceFactory::GetForProfile( GetProfile(), ServiceAccessType::EXPLICIT_ACCESS); - hs->QueryHistory(search_text, - options, - base::Bind(&HistorySearchFunction::SearchComplete, - base::Unretained(this)), + hs->QueryHistory(search_text, options, + base::BindOnce(&HistorySearchFunction::SearchComplete, + base::Unretained(this)), &task_tracker_); AddRef(); // Balanced in SearchComplete(). return RespondLater(); // SearchComplete() will be called asynchronously. } -void HistorySearchFunction::SearchComplete(history::QueryResults* results) { +void HistorySearchFunction::SearchComplete(history::QueryResults results) { HistoryItemList history_item_vec; - if (results && !results->empty()) { - for (const auto& item : *results) + if (!results.empty()) { + for (const auto& item : results) history_item_vec.push_back(GetHistoryItem(item)); } Respond(ArgumentList(Search::Results::Create(history_item_vec)));
diff --git a/chrome/browser/extensions/api/history/history_api.h b/chrome/browser/extensions/api/history/history_api.h index 82c6cd00..9a0433db 100644 --- a/chrome/browser/extensions/api/history/history_api.h +++ b/chrome/browser/extensions/api/history/history_api.h
@@ -143,7 +143,7 @@ ResponseAction Run() override; // Callback for the history function to provide results. - void SearchComplete(history::QueryResults* results); + void SearchComplete(history::QueryResults results); }; class HistoryAddUrlFunction : public HistoryFunction {
diff --git a/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc b/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc index c00c75c3..75d783e8 100644 --- a/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc +++ b/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc
@@ -290,11 +290,11 @@ data_decoder::SafeJsonParser::Parse( content::ServiceManagerConnection::GetForProcess()->GetConnector(), manifest_str, - base::Bind( + base::BindOnce( &extensions::ManagementGetPermissionWarningsByManifestFunction:: OnParseSuccess, function), - base::Bind( + base::BindOnce( &extensions::ManagementGetPermissionWarningsByManifestFunction:: OnParseFailure, function));
diff --git a/chrome/browser/extensions/api/notifications/notifications_api.cc b/chrome/browser/extensions/api/notifications/notifications_api.cc index 23e8951..45ea951 100644 --- a/chrome/browser/extensions/api/notifications/notifications_api.cc +++ b/chrome/browser/extensions/api/notifications/notifications_api.cc
@@ -48,7 +48,6 @@ #include "ui/gfx/image/image_skia_operations.h" #include "ui/gfx/image/image_skia_rep.h" #include "ui/gfx/skia_util.h" -#include "ui/message_center/public/cpp/features.h" #include "ui/message_center/public/cpp/message_center_constants.h" #include "ui/message_center/public/cpp/notification.h" #include "ui/message_center/public/cpp/notification_delegate.h" @@ -362,9 +361,7 @@ } optional_fields.settings_button_handler = - base::FeatureList::IsEnabled(message_center::kNewStyleNotifications) - ? message_center::SettingsButtonHandler::INLINE - : message_center::SettingsButtonHandler::NONE; + message_center::SettingsButtonHandler::INLINE; // TODO(crbug.com/772004): Remove the manual limitation in favor of an IDL // annotation once supported.
diff --git a/chrome/browser/extensions/webstore_data_fetcher.cc b/chrome/browser/extensions/webstore_data_fetcher.cc index 7b9f00d..7a46a2a4 100644 --- a/chrome/browser/extensions/webstore_data_fetcher.cc +++ b/chrome/browser/extensions/webstore_data_fetcher.cc
@@ -124,8 +124,8 @@ data_decoder::SafeJsonParser::Parse( content::ServiceManagerConnection::GetForProcess()->GetConnector(), *response_body, - base::Bind(&WebstoreDataFetcher::OnJsonParseSuccess, AsWeakPtr()), - base::Bind(&WebstoreDataFetcher::OnJsonParseFailure, AsWeakPtr())); + base::BindOnce(&WebstoreDataFetcher::OnJsonParseSuccess, AsWeakPtr()), + base::BindOnce(&WebstoreDataFetcher::OnJsonParseFailure, AsWeakPtr())); } } // namespace extensions
diff --git a/chrome/browser/extensions/webstore_install_helper.cc b/chrome/browser/extensions/webstore_install_helper.cc index f5aac8a5..d12a3b1 100644 --- a/chrome/browser/extensions/webstore_install_helper.cc +++ b/chrome/browser/extensions/webstore_install_helper.cc
@@ -44,8 +44,9 @@ data_decoder::SafeJsonParser::Parse( content::ServiceManagerConnection::GetForProcess()->GetConnector(), - manifest_, base::Bind(&WebstoreInstallHelper::OnJSONParseSucceeded, this), - base::Bind(&WebstoreInstallHelper::OnJSONParseFailed, this)); + manifest_, + base::BindOnce(&WebstoreInstallHelper::OnJSONParseSucceeded, this), + base::BindOnce(&WebstoreInstallHelper::OnJSONParseFailed, this)); if (icon_url_.is_empty()) { icon_decode_complete_ = true;
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 12d8bd48..e1a80b9d 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -1863,8 +1863,8 @@ }, { "name": "enable-webrtc-srtp-aes-gcm", - // "owners": [ "your-team" ], - "expiry_milestone": 76 + "owners": [ "emadomara" ], + "expiry_milestone": 80 }, { "name": "enable-webrtc-stun-origin", @@ -2942,6 +2942,11 @@ "expiry_milestone": 76 }, { + "name": "use-search-click-for-right-click", + "owners": [ "zentaro" ], + "expiry_milestone": 80 + }, + { "name": "use-sync-sandbox", "owners": [ "//components/sync/OWNERS" ], // This flag is required for testing with the related
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 343776f1..07597426 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -1138,10 +1138,6 @@ "Have the Media Router connect to Cast devices on all IP addresses, not " "just RFC1918/RFC4193 private addresses."; -const char kMessageCenterNewStyleNotificationName[] = "New style notification"; -const char kMessageCenterNewStyleNotificationDescription[] = - "Enables the experiment style of material-design notification"; - const char kMimeHandlerViewInCrossProcessFrameName[] = "MimeHandlerView in cross-process frame"; const char kMimeHandlerViewInCrossProcessFrameDescription[] = @@ -1882,6 +1878,13 @@ "Enable simple user activation for APIs that are otherwise controlled by " "user gesture tokens."; +const char kUseSearchClickForRightClickName[] = + "Use Search+Click for right click"; +const char kUseSearchClickForRightClickDescription[] = + "When enabled search+click will be remapped to right click, allowing " + "webpages and apps to consume alt+click. When disabled the legacy " + "behavior of remapping alt+click to right click will remain unchanged."; + const char kV8VmFutureName[] = "Future V8 VM features"; const char kV8VmFutureDescription[] = "This enables upcoming and experimental V8 VM features. "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 19a7212..6a6efee5 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -698,9 +698,6 @@ extern const char kMediaRouterCastAllowAllIPsName[]; extern const char kMediaRouterCastAllowAllIPsDescription[]; -extern const char kMessageCenterNewStyleNotificationName[]; -extern const char kMessageCenterNewStyleNotificationDescription[]; - extern const char kMimeHandlerViewInCrossProcessFrameName[]; extern const char kMimeHandlerViewInCrossProcessFrameDescription[]; @@ -1116,6 +1113,9 @@ extern const char kUserActivationV2Name[]; extern const char kUserActivationV2Description[]; +extern const char kUseSearchClickForRightClickName[]; +extern const char kUseSearchClickForRightClickDescription[]; + extern const char kV8VmFutureName[]; extern const char kV8VmFutureDescription[];
diff --git a/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_browsertest.cc b/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_browsertest.cc index bfa84fd0..4b270f0 100644 --- a/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_browsertest.cc +++ b/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_browsertest.cc
@@ -17,6 +17,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/find_bar/find_tab_helper.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/common/pdf_util.h" #include "chrome/test/base/ui_test_utils.h" #include "components/guest_view/browser/guest_view_manager.h" #include "components/guest_view/browser/guest_view_manager_delegate.h" @@ -48,6 +49,7 @@ #include "ui/views/controls/webview/webview.h" #include "ui/views/view.h" #include "ui/views/widget/widget.h" +#include "url/url_constants.h" #if defined(USE_AURA) #include "ui/aura/window.h" #endif @@ -620,6 +622,43 @@ } } +IN_PROC_BROWSER_TEST_P(ChromeMimeHandlerViewCrossProcessTest, + UMAPDFLoadStatsFullPage) { + base::HistogramTester histogram_tester; + GURL data_url("data:application/pdf,foo"); + ui_test_utils::NavigateToURL(browser(), data_url); + auto* guest = GetGuestViewManager()->WaitForSingleGuestCreated(); + while (guest->IsLoading()) { + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout()); + run_loop.Run(); + } + SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); + histogram_tester.ExpectBucketCount( + "PDF.LoadStatus", PDFLoadStatus::kLoadedFullPagePdfWithPdfium, 1); +} + +IN_PROC_BROWSER_TEST_P(ChromeMimeHandlerViewCrossProcessTest, + UMAPDFLoadStatsEmbedded) { + base::HistogramTester histogram_tester; + ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)); + ASSERT_TRUE(content::ExecJs( + browser()->tab_strip_model()->GetWebContentsAt(0), + "document.write('<iframe></iframe>');" + "document.querySelector('iframe').src = 'data:application/pdf, foo';")); + auto* guest = GetGuestViewManager()->WaitForSingleGuestCreated(); + while (guest->IsLoading()) { + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout()); + run_loop.Run(); + } + SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); + histogram_tester.ExpectBucketCount( + "PDF.LoadStatus", PDFLoadStatus::kLoadedEmbeddedPdfWithPdfium, 1); +} + INSTANTIATE_TEST_SUITE_P(, ChromeMimeHandlerViewCrossProcessTest, testing::Bool());
diff --git a/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_guest_delegate.cc b/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_guest_delegate.cc index e22f0b4..6a8129b 100644 --- a/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_guest_delegate.cc +++ b/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_guest_delegate.cc
@@ -6,7 +6,9 @@ #include <utility> +#include "base/metrics/histogram_functions.h" #include "chrome/browser/renderer_context_menu/render_view_context_menu.h" +#include "chrome/common/pdf_util.h" #include "components/renderer_context_menu/context_menu_delegate.h" namespace extensions { @@ -30,4 +32,16 @@ return true; } +void ChromeMimeHandlerViewGuestDelegate::RecordLoadMetric( + bool in_main_frame, + const std::string& mime_type) { + if (mime_type != kPDFMimeType) + return; + base::UmaHistogramEnumeration( + "PDF.LoadStatus", + in_main_frame ? PDFLoadStatus::kLoadedFullPagePdfWithPdfium + : PDFLoadStatus::kLoadedEmbeddedPdfWithPdfium, + PDFLoadStatus::kPdfLoadStatusCount); +} + } // namespace extensions
diff --git a/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_guest_delegate.h b/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_guest_delegate.h index 1a59017..0820c3a7 100644 --- a/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_guest_delegate.h +++ b/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_guest_delegate.h
@@ -23,6 +23,8 @@ // MimeHandlerViewGuestDelegate. bool HandleContextMenu(content::WebContents* web_contents, const content::ContextMenuParams& params) override; + void RecordLoadMetric(bool in_main_frame, + const std::string& mime_type) override; private: DISALLOW_COPY_AND_ASSIGN(ChromeMimeHandlerViewGuestDelegate);
diff --git a/chrome/browser/history/redirect_browsertest.cc b/chrome/browser/history/redirect_browsertest.cc index 6d49b95..b6331ad3 100644 --- a/chrome/browser/history/redirect_browsertest.cc +++ b/chrome/browser/history/redirect_browsertest.cc
@@ -55,9 +55,8 @@ std::vector<GURL> rv; history_service->QueryRedirectsFrom( url, - base::Bind(&RedirectTest::OnRedirectQueryComplete, - base::Unretained(this), - &rv), + base::BindOnce(&RedirectTest::OnRedirectQueryComplete, + base::Unretained(this), &rv), &tracker_); content::RunMessageLoop(); return rv; @@ -65,8 +64,8 @@ protected: void OnRedirectQueryComplete(std::vector<GURL>* rv, - const history::RedirectList* redirects) { - rv->insert(rv->end(), redirects->begin(), redirects->end()); + history::RedirectList redirects) { + rv->insert(rv->end(), redirects.begin(), redirects.end()); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated()); }
diff --git a/chrome/browser/importer/profile_writer_unittest.cc b/chrome/browser/importer/profile_writer_unittest.cc index 94734d9..9b8e29f 100644 --- a/chrome/browser/importer/profile_writer_unittest.cc +++ b/chrome/browser/importer/profile_writer_unittest.cc
@@ -12,6 +12,7 @@ #include "base/macros.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/bind_test_util.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/importer/importer_unittest_utils.h" @@ -98,18 +99,15 @@ profile, ServiceAccessType::EXPLICIT_ACCESS); history::QueryOptions options; base::CancelableTaskTracker history_task_tracker; + base::RunLoop loop; history_service->QueryHistory( - base::string16(), - options, - base::Bind(&ProfileWriterTest::HistoryQueryComplete, - base::Unretained(this)), + base::string16(), options, + base::BindLambdaForTesting([&](history::QueryResults results) { + history_count_ = results.size(); + loop.Quit(); + }), &history_task_tracker); - base::RunLoop().Run(); - } - - void HistoryQueryComplete(history::QueryResults* results) { - base::RunLoop::QuitCurrentWhenIdleDeprecated(); - history_count_ = results->size(); + loop.Run(); } protected:
diff --git a/chrome/browser/invalidation/profile_invalidation_provider_factory.cc b/chrome/browser/invalidation/profile_invalidation_provider_factory.cc index 3052b9b..1417d6a 100644 --- a/chrome/browser/invalidation/profile_invalidation_provider_factory.cc +++ b/chrome/browser/invalidation/profile_invalidation_provider_factory.cc
@@ -56,7 +56,7 @@ ->driver(), profile->GetPrefs(), base::BindRepeating( - data_decoder::SafeJsonParser::Parse, + &data_decoder::SafeJsonParser::Parse, content::ServiceManagerConnection::GetForProcess()->GetConnector()), content::BrowserContext::GetDefaultStoragePartition(profile) ->GetURLLoaderFactoryForBrowserProcess()
diff --git a/chrome/browser/media/router/data_decoder_util.cc b/chrome/browser/media/router/data_decoder_util.cc index b95db324..131bc46 100644 --- a/chrome/browser/media/router/data_decoder_util.cc +++ b/chrome/browser/media/router/data_decoder_util.cc
@@ -21,11 +21,11 @@ void DataDecoder::ParseJson( const std::string& unsafe_json, - const data_decoder::SafeJsonParser::SuccessCallback& success_callback, - const data_decoder::SafeJsonParser::ErrorCallback& error_callback) { - data_decoder::SafeJsonParser::ParseBatch(connector_.get(), unsafe_json, - success_callback, error_callback, - kDataDecoderServiceBatchId); + data_decoder::SafeJsonParser::SuccessCallback success_callback, + data_decoder::SafeJsonParser::ErrorCallback error_callback) { + data_decoder::SafeJsonParser::ParseBatch( + connector_.get(), unsafe_json, std::move(success_callback), + std::move(error_callback), kDataDecoderServiceBatchId); } } // namespace media_router
diff --git a/chrome/browser/media/router/data_decoder_util.h b/chrome/browser/media/router/data_decoder_util.h index bfded16f..ccb7ad7 100644 --- a/chrome/browser/media/router/data_decoder_util.h +++ b/chrome/browser/media/router/data_decoder_util.h
@@ -34,10 +34,9 @@ void ParseXml(const std::string& unsafe_xml, data_decoder::XmlParserCallback callback); - void ParseJson( - const std::string& unsafe_json, - const data_decoder::SafeJsonParser::SuccessCallback& success_callback, - const data_decoder::SafeJsonParser::ErrorCallback& error_callback); + void ParseJson(const std::string& unsafe_json, + data_decoder::SafeJsonParser::SuccessCallback success_callback, + data_decoder::SafeJsonParser::ErrorCallback error_callback); private: std::unique_ptr<service_manager::Connector> connector_;
diff --git a/chrome/browser/metrics/chrome_metrics_services_manager_client.cc b/chrome/browser/metrics/chrome_metrics_services_manager_client.cc index a2b6dc6dcc..902a34c 100644 --- a/chrome/browser/metrics/chrome_metrics_services_manager_client.cc +++ b/chrome/browser/metrics/chrome_metrics_services_manager_client.cc
@@ -174,8 +174,8 @@ static const char kTrialName[] = "MetricsAndCrashSampling"; scoped_refptr<base::FieldTrial> trial( base::FieldTrialList::FactoryGetFieldTrial( - kTrialName, 1000, "Default", base::FieldTrialList::kNoExpirationYear, - 1, 1, base::FieldTrial::ONE_TIME_RANDOMIZED, nullptr)); + kTrialName, 1000, "Default", base::FieldTrial::ONE_TIME_RANDOMIZED, + nullptr)); // On all channels except stable, we sample out at a minimal rate to ensure // the code paths are exercised in the wild before hitting stable.
diff --git a/chrome/browser/metrics/variations/force_field_trials_browsertest.cc b/chrome/browser/metrics/variations/force_field_trials_browsertest.cc index eccae3f..0bb6ca0 100644 --- a/chrome/browser/metrics/variations/force_field_trials_browsertest.cc +++ b/chrome/browser/metrics/variations/force_field_trials_browsertest.cc
@@ -50,8 +50,8 @@ // Creates a 50/50 trial with ONE_TIME_RANDOMIZED consistency. void CreateFiftyPercentTrial(const std::string& trial_name) { auto* trial = base::FieldTrialList::FactoryGetFieldTrial( - trial_name, 100, "Default", base::FieldTrialList::kNoExpirationYear, 1, - 1, base::FieldTrial::ONE_TIME_RANDOMIZED, nullptr); + trial_name, 100, "Default", base::FieldTrial::ONE_TIME_RANDOMIZED, + nullptr); trial->AppendGroup(kEnabledGroupName, 50); trial->AppendGroup(kDisabledGroupName, 50); }
diff --git a/chrome/browser/notifications/notification_platform_bridge_win.cc b/chrome/browser/notifications/notification_platform_bridge_win.cc index bb18548..e914dbce 100644 --- a/chrome/browser/notifications/notification_platform_bridge_win.cc +++ b/chrome/browser/notifications/notification_platform_bridge_win.cc
@@ -150,7 +150,7 @@ // Delete any remaining temp files in the image folder from the previous // sessions. DCHECK(notification_task_runner_); - content::BrowserThread::PostAfterStartupTask( + content::BrowserThread::PostBestEffortTask( FROM_HERE, notification_task_runner_, image_retainer_->GetCleanupTask()); }
diff --git a/chrome/browser/notifications/platform_notification_service_impl.cc b/chrome/browser/notifications/platform_notification_service_impl.cc index 529b141..443e304 100644 --- a/chrome/browser/notifications/platform_notification_service_impl.cc +++ b/chrome/browser/notifications/platform_notification_service_impl.cc
@@ -10,7 +10,6 @@ #include <vector> #include "base/bind.h" -#include "base/feature_list.h" #include "base/metrics/histogram_macros.h" #include "base/strings/utf_string_conversions.h" #include "base/task/post_task.h" @@ -30,8 +29,6 @@ #include "chrome/browser/ui/exclusive_access/exclusive_access_context.h" #include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/buildflags.h" -#include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" #include "components/content_settings/core/browser/host_content_settings_map.h" @@ -42,14 +39,11 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/platform_notification_context.h" #include "content/public/browser/storage_partition.h" -#include "extensions/buildflags/buildflags.h" #include "services/metrics/public/cpp/ukm_builders.h" #include "third_party/blink/public/common/notifications/notification_resources.h" #include "third_party/blink/public/common/notifications/platform_notification_data.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/base/l10n/l10n_util.h" -#include "ui/base/ui_base_features.h" -#include "ui/message_center/public/cpp/features.h" #include "ui/message_center/public/cpp/notification_types.h" #include "ui/message_center/public/cpp/notifier_id.h" #include "url/origin.h" @@ -410,9 +404,7 @@ message_center::RichNotificationData optional_fields; optional_fields.settings_button_handler = - base::FeatureList::IsEnabled(message_center::kNewStyleNotifications) - ? message_center::SettingsButtonHandler::INLINE - : message_center::SettingsButtonHandler::DELEGATE; + message_center::SettingsButtonHandler::INLINE; // TODO(peter): Handle different screen densities instead of always using the // 1x bitmap - crbug.com/585815.
diff --git a/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc b/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc index e67a862..00b93837 100644 --- a/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc +++ b/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc
@@ -170,7 +170,7 @@ #endif // BUILDFLAG(ENABLE_OFFLINE_PAGES) auto suggestions_fetcher = std::make_unique<RemoteSuggestionsFetcherImpl>( identity_manager, url_loader_factory, pref_service, language_histogram, - base::Bind( + base::BindRepeating( &data_decoder::SafeJsonParser::Parse, content::ServiceManagerConnection::GetForProcess()->GetConnector()), GetFetchEndpoint(), api_key, user_classifier);
diff --git a/chrome/browser/ntp_tiles/chrome_popular_sites_factory.cc b/chrome/browser/ntp_tiles/chrome_popular_sites_factory.cc index be9c9f0..6f3c5db 100644 --- a/chrome/browser/ntp_tiles/chrome_popular_sites_factory.cc +++ b/chrome/browser/ntp_tiles/chrome_popular_sites_factory.cc
@@ -22,7 +22,7 @@ g_browser_process->variations_service(), content::BrowserContext::GetDefaultStoragePartition(profile) ->GetURLLoaderFactoryForBrowserProcess(), - base::Bind( - data_decoder::SafeJsonParser::Parse, + base::BindRepeating( + &data_decoder::SafeJsonParser::Parse, content::ServiceManagerConnection::GetForProcess()->GetConnector())); }
diff --git a/chrome/browser/page_load_metrics/observers/loading_predictor_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/loading_predictor_page_load_metrics_observer_unittest.cc index 9faf283..7a997fd51 100644 --- a/chrome/browser/page_load_metrics/observers/loading_predictor_page_load_metrics_observer_unittest.cc +++ b/chrome/browser/page_load_metrics/observers/loading_predictor_page_load_metrics_observer_unittest.cc
@@ -9,7 +9,6 @@ #include "chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h" #include "chrome/browser/page_load_metrics/page_load_tracker.h" #include "chrome/browser/predictors/loading_data_collector.h" -#include "chrome/browser/predictors/resource_prefetch_common.h" #include "chrome/browser/predictors/resource_prefetch_predictor.h" #include "chrome/common/page_load_metrics/test/page_load_metrics_test_util.h" #include "chrome/test/base/testing_profile.h"
diff --git a/chrome/browser/permissions/OWNERS b/chrome/browser/permissions/OWNERS index fe7f49cf..d2e2d1c 100644 --- a/chrome/browser/permissions/OWNERS +++ b/chrome/browser/permissions/OWNERS
@@ -1,5 +1,6 @@ benwells@chromium.org dominickn@chromium.org +engedy@chromium.org felt@chromium.org mlamouri@chromium.org raymes@chromium.org
diff --git a/chrome/browser/plugins/plugins_resource_service.cc b/chrome/browser/plugins/plugins_resource_service.cc index 2f6b793..d7c3801 100644 --- a/chrome/browser/plugins/plugins_resource_service.cc +++ b/chrome/browser/plugins/plugins_resource_service.cc
@@ -87,9 +87,9 @@ g_browser_process->system_network_context_manager() ->GetSharedURLLoaderFactory(), switches::kDisableBackgroundNetworking, - base::Bind(data_decoder::SafeJsonParser::Parse, - content::ServiceManagerConnection::GetForProcess() - ->GetConnector()), + base::BindRepeating(&data_decoder::SafeJsonParser::Parse, + content::ServiceManagerConnection::GetForProcess() + ->GetConnector()), kPluginResourceServiceTrafficAnnotation, base::BindOnce(&content::GetNetworkConnectionTracker)) {}
diff --git a/chrome/browser/predictors/loading_data_collector.h b/chrome/browser/predictors/loading_data_collector.h index 334df71..f4fb67b 100644 --- a/chrome/browser/predictors/loading_data_collector.h +++ b/chrome/browser/predictors/loading_data_collector.h
@@ -11,7 +11,7 @@ #include "base/memory/weak_ptr.h" #include "chrome/browser/predictors/loading_predictor_config.h" -#include "chrome/browser/predictors/resource_prefetch_common.h" +#include "chrome/browser/predictors/navigation_id.h" #include "content/public/common/resource_load_info.mojom.h" #include "content/public/common/resource_type.h" #include "url/gurl.h"
diff --git a/chrome/browser/predictors/loading_predictor.cc b/chrome/browser/predictors/loading_predictor.cc index f2ae6c5..b7946bc6 100644 --- a/chrome/browser/predictors/loading_predictor.cc +++ b/chrome/browser/predictors/loading_predictor.cc
@@ -10,7 +10,7 @@ #include "base/metrics/histogram_macros.h" #include "chrome/browser/predictors/loading_data_collector.h" #include "chrome/browser/predictors/loading_stats_collector.h" -#include "chrome/browser/predictors/resource_prefetch_common.h" +#include "chrome/browser/predictors/navigation_id.h" #include "chrome/browser/predictors/resource_prefetch_predictor.h" #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/predictors/loading_predictor.h b/chrome/browser/predictors/loading_predictor.h index c609ec4..7296d34 100644 --- a/chrome/browser/predictors/loading_predictor.h +++ b/chrome/browser/predictors/loading_predictor.h
@@ -16,8 +16,8 @@ #include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "chrome/browser/predictors/loading_data_collector.h" +#include "chrome/browser/predictors/navigation_id.h" #include "chrome/browser/predictors/preconnect_manager.h" -#include "chrome/browser/predictors/resource_prefetch_common.h" #include "chrome/browser/predictors/resource_prefetch_predictor.h" #include "chrome/browser/profiles/profile.h" #include "components/keyed_service/core/keyed_service.h"
diff --git a/chrome/browser/predictors/loading_predictor_factory.cc b/chrome/browser/predictors/loading_predictor_factory.cc index 1166d85..3c5d737 100644 --- a/chrome/browser/predictors/loading_predictor_factory.cc +++ b/chrome/browser/predictors/loading_predictor_factory.cc
@@ -7,7 +7,6 @@ #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/predictors/loading_predictor.h" #include "chrome/browser/predictors/predictor_database_factory.h" -#include "chrome/browser/predictors/resource_prefetch_common.h" #include "chrome/browser/profiles/profile.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h"
diff --git a/chrome/browser/predictors/glowplug_key_value_data.h b/chrome/browser/predictors/loading_predictor_key_value_data.h similarity index 72% rename from chrome/browser/predictors/glowplug_key_value_data.h rename to chrome/browser/predictors/loading_predictor_key_value_data.h index 1e25a40..f4cbffe 100644 --- a/chrome/browser/predictors/glowplug_key_value_data.h +++ b/chrome/browser/predictors/loading_predictor_key_value_data.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_PREDICTORS_GLOWPLUG_KEY_VALUE_DATA_H_ -#define CHROME_BROWSER_PREDICTORS_GLOWPLUG_KEY_VALUE_DATA_H_ +#ifndef CHROME_BROWSER_PREDICTORS_LOADING_PREDICTOR_KEY_VALUE_DATA_H_ +#define CHROME_BROWSER_PREDICTORS_LOADING_PREDICTOR_KEY_VALUE_DATA_H_ #include <algorithm> #include <map> @@ -16,7 +16,7 @@ #include "base/location.h" #include "base/memory/ref_counted.h" #include "base/timer/timer.h" -#include "chrome/browser/predictors/glowplug_key_value_table.h" +#include "chrome/browser/predictors/loading_predictor_key_value_table.h" #include "chrome/browser/predictors/resource_prefetch_predictor_tables.h" #include "content/public/browser/browser_thread.h" @@ -25,20 +25,21 @@ namespace predictors { // The class provides a synchronous access to the data backed by -// GlowplugKeyValueTable<T>. The current implementation caches all the data in -// the memory. The cache size is limited by max_size parameter using Compare -// function to decide which entry should be evicted. +// LoadingPredictorKeyValueTable<T>. The current implementation caches all the +// data in the memory. The cache size is limited by max_size parameter using +// Compare function to decide which entry should be evicted. // // InitializeOnDBSequence() must be called on the DB sequence of the // ResourcePrefetchPredictorTables. All other methods must be called on UI // thread. template <typename T, typename Compare> -class GlowplugKeyValueData { +class LoadingPredictorKeyValueData { public: - GlowplugKeyValueData(scoped_refptr<ResourcePrefetchPredictorTables> tables, - GlowplugKeyValueTable<T>* backend, - size_t max_size, - base::TimeDelta flush_delay); + LoadingPredictorKeyValueData( + scoped_refptr<ResourcePrefetchPredictorTables> tables, + LoadingPredictorKeyValueTable<T>* backend, + size_t max_size, + base::TimeDelta flush_delay); // Must be called on the DB sequence of the ResourcePrefetchPredictorTables // before calling all other methods. @@ -74,7 +75,7 @@ void FlushDataToDisk(); scoped_refptr<ResourcePrefetchPredictorTables> tables_; - GlowplugKeyValueTable<T>* backend_table_; + LoadingPredictorKeyValueTable<T>* backend_table_; std::unique_ptr<std::map<std::string, T>> data_cache_; std::unordered_map<std::string, DeferredOperation> deferred_updates_; base::RepeatingTimer flush_timer_; @@ -82,13 +83,13 @@ const size_t max_size_; EntryCompare entry_compare_; - DISALLOW_COPY_AND_ASSIGN(GlowplugKeyValueData); + DISALLOW_COPY_AND_ASSIGN(LoadingPredictorKeyValueData); }; template <typename T, typename Compare> -GlowplugKeyValueData<T, Compare>::GlowplugKeyValueData( +LoadingPredictorKeyValueData<T, Compare>::LoadingPredictorKeyValueData( scoped_refptr<ResourcePrefetchPredictorTables> tables, - GlowplugKeyValueTable<T>* backend, + LoadingPredictorKeyValueTable<T>* backend, size_t max_size, base::TimeDelta flush_delay) : tables_(tables), @@ -99,11 +100,11 @@ } template <typename T, typename Compare> -void GlowplugKeyValueData<T, Compare>::InitializeOnDBSequence() { +void LoadingPredictorKeyValueData<T, Compare>::InitializeOnDBSequence() { DCHECK(tables_->GetTaskRunner()->RunsTasksInCurrentSequence()); auto data_map = std::make_unique<std::map<std::string, T>>(); tables_->ExecuteDBTaskOnDBSequence( - base::BindOnce(&GlowplugKeyValueTable<T>::GetAllData, + base::BindOnce(&LoadingPredictorKeyValueTable<T>::GetAllData, base::Unretained(backend_table_), data_map.get())); // To ensure invariant that data_cache_.size() <= max_size_. @@ -115,17 +116,19 @@ data_map->erase(entry_to_delete); } if (keys_to_delete.size() > 0) { - tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( - &GlowplugKeyValueTable<T>::DeleteData, base::Unretained(backend_table_), - std::vector<std::string>(keys_to_delete))); + tables_->ExecuteDBTaskOnDBSequence( + base::BindOnce(&LoadingPredictorKeyValueTable<T>::DeleteData, + base::Unretained(backend_table_), + std::vector<std::string>(keys_to_delete))); } data_cache_ = std::move(data_map); } template <typename T, typename Compare> -bool GlowplugKeyValueData<T, Compare>::TryGetData(const std::string& key, - T* data) const { +bool LoadingPredictorKeyValueData<T, Compare>::TryGetData( + const std::string& key, + T* data) const { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK(data_cache_); auto it = data_cache_->find(key); @@ -138,8 +141,9 @@ } template <typename T, typename Compare> -void GlowplugKeyValueData<T, Compare>::UpdateData(const std::string& key, - const T& data) { +void LoadingPredictorKeyValueData<T, Compare>::UpdateData( + const std::string& key, + const T& data) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK(data_cache_); auto it = data_cache_->find(key); @@ -161,12 +165,12 @@ FlushDataToDisk(); } else if (!flush_timer_.IsRunning()) { flush_timer_.Start(FROM_HERE, flush_delay_, this, - &GlowplugKeyValueData::FlushDataToDisk); + &LoadingPredictorKeyValueData::FlushDataToDisk); } } template <typename T, typename Compare> -void GlowplugKeyValueData<T, Compare>::DeleteData( +void LoadingPredictorKeyValueData<T, Compare>::DeleteData( const std::vector<std::string>& keys) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK(data_cache_); @@ -181,7 +185,7 @@ } template <typename T, typename Compare> -void GlowplugKeyValueData<T, Compare>::DeleteAllData() { +void LoadingPredictorKeyValueData<T, Compare>::DeleteAllData() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK(data_cache_); data_cache_->clear(); @@ -189,12 +193,13 @@ // Delete all the content of the database immediately because it was requested // by user. tables_->ScheduleDBTask( - FROM_HERE, base::BindOnce(&GlowplugKeyValueTable<T>::DeleteAllData, - base::Unretained(backend_table_))); + FROM_HERE, + base::BindOnce(&LoadingPredictorKeyValueTable<T>::DeleteAllData, + base::Unretained(backend_table_))); } template <typename T, typename Compare> -void GlowplugKeyValueData<T, Compare>::FlushDataToDisk() { +void LoadingPredictorKeyValueData<T, Compare>::FlushDataToDisk() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); if (deferred_updates_.empty()) return; @@ -207,9 +212,10 @@ auto it = data_cache_->find(key); if (it != data_cache_->end()) { tables_->ScheduleDBTask( - FROM_HERE, base::BindOnce(&GlowplugKeyValueTable<T>::UpdateData, - base::Unretained(backend_table_), key, - it->second)); + FROM_HERE, + base::BindOnce(&LoadingPredictorKeyValueTable<T>::UpdateData, + base::Unretained(backend_table_), key, + it->second)); } break; } @@ -221,7 +227,7 @@ if (!keys_to_delete.empty()) { tables_->ScheduleDBTask( FROM_HERE, - base::BindOnce(&GlowplugKeyValueTable<T>::DeleteData, + base::BindOnce(&LoadingPredictorKeyValueTable<T>::DeleteData, base::Unretained(backend_table_), keys_to_delete)); } @@ -230,4 +236,4 @@ } // namespace predictors -#endif // CHROME_BROWSER_PREDICTORS_GLOWPLUG_KEY_VALUE_DATA_H_ +#endif // CHROME_BROWSER_PREDICTORS_LOADING_PREDICTOR_KEY_VALUE_DATA_H_
diff --git a/chrome/browser/predictors/glowplug_key_value_table.cc b/chrome/browser/predictors/loading_predictor_key_value_table.cc similarity index 94% rename from chrome/browser/predictors/glowplug_key_value_table.cc rename to chrome/browser/predictors/loading_predictor_key_value_table.cc index 9d826a2..ab7b5c9 100644 --- a/chrome/browser/predictors/glowplug_key_value_table.cc +++ b/chrome/browser/predictors/loading_predictor_key_value_table.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/predictors/glowplug_key_value_table.h" +#include "chrome/browser/predictors/loading_predictor_key_value_table.h" #include "base/strings/stringprintf.h" #include "third_party/protobuf/src/google/protobuf/message_lite.h"
diff --git a/chrome/browser/predictors/glowplug_key_value_table.h b/chrome/browser/predictors/loading_predictor_key_value_table.h similarity index 72% rename from chrome/browser/predictors/glowplug_key_value_table.h rename to chrome/browser/predictors/loading_predictor_key_value_table.h index 562e349..c5c5939f 100644 --- a/chrome/browser/predictors/glowplug_key_value_table.h +++ b/chrome/browser/predictors/loading_predictor_key_value_table.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_PREDICTORS_GLOWPLUG_KEY_VALUE_TABLE_H_ -#define CHROME_BROWSER_PREDICTORS_GLOWPLUG_KEY_VALUE_TABLE_H_ +#ifndef CHROME_BROWSER_PREDICTORS_LOADING_PREDICTOR_KEY_VALUE_TABLE_H_ +#define CHROME_BROWSER_PREDICTORS_LOADING_PREDICTOR_KEY_VALUE_TABLE_H_ #include <map> #include <string> @@ -15,7 +15,7 @@ namespace protobuf { class MessageLite; } -} +} // namespace google namespace predictors { @@ -45,14 +45,14 @@ // Example: // tables_->ScheduleDBTask( // FROM_HERE, -// base::BindOnce(&GlowplugKeyValueTable<PrefetchData>::UpdateData, +// base::BindOnce(&LoadingPredictorKeyValueTable<PrefetchData>::UpdateData, // base::Unretained(table_), key, data)); template <typename T> -class GlowplugKeyValueTable { +class LoadingPredictorKeyValueTable { public: - explicit GlowplugKeyValueTable(const std::string& table_name); + explicit LoadingPredictorKeyValueTable(const std::string& table_name); // Virtual for testing. - virtual ~GlowplugKeyValueTable() {} + virtual ~LoadingPredictorKeyValueTable() {} virtual void GetAllData(std::map<std::string, T>* data_map, sql::Database* db) const; virtual void UpdateData(const std::string& key, @@ -65,16 +65,18 @@ private: const std::string table_name_; - DISALLOW_COPY_AND_ASSIGN(GlowplugKeyValueTable); + DISALLOW_COPY_AND_ASSIGN(LoadingPredictorKeyValueTable); }; template <typename T> -GlowplugKeyValueTable<T>::GlowplugKeyValueTable(const std::string& table_name) +LoadingPredictorKeyValueTable<T>::LoadingPredictorKeyValueTable( + const std::string& table_name) : table_name_(table_name) {} template <typename T> -void GlowplugKeyValueTable<T>::GetAllData(std::map<std::string, T>* data_map, - sql::Database* db) const { +void LoadingPredictorKeyValueTable<T>::GetAllData( + std::map<std::string, T>* data_map, + sql::Database* db) const { sql::Statement reader(db->GetUniqueStatement( ::predictors::internal::GetSelectAllSql(table_name_).c_str())); while (reader.Step()) { @@ -87,9 +89,9 @@ } template <typename T> -void GlowplugKeyValueTable<T>::UpdateData(const std::string& key, - const T& data, - sql::Database* db) { +void LoadingPredictorKeyValueTable<T>::UpdateData(const std::string& key, + const T& data, + sql::Database* db) { sql::Statement inserter(db->GetUniqueStatement( ::predictors::internal::GetReplaceSql(table_name_).c_str())); ::predictors::internal::BindDataToStatement(key, data, &inserter); @@ -97,8 +99,9 @@ } template <typename T> -void GlowplugKeyValueTable<T>::DeleteData(const std::vector<std::string>& keys, - sql::Database* db) { +void LoadingPredictorKeyValueTable<T>::DeleteData( + const std::vector<std::string>& keys, + sql::Database* db) { sql::Statement deleter(db->GetUniqueStatement( ::predictors::internal::GetDeleteSql(table_name_).c_str())); for (const auto& key : keys) { @@ -109,7 +112,7 @@ } template <typename T> -void GlowplugKeyValueTable<T>::DeleteAllData(sql::Database* db) { +void LoadingPredictorKeyValueTable<T>::DeleteAllData(sql::Database* db) { sql::Statement deleter(db->GetUniqueStatement( ::predictors::internal::GetDeleteAllSql(table_name_).c_str())); deleter.Run(); @@ -117,4 +120,4 @@ } // namespace predictors -#endif // CHROME_BROWSER_PREDICTORS_GLOWPLUG_KEY_VALUE_TABLE_H_ +#endif // CHROME_BROWSER_PREDICTORS_LOADING_PREDICTOR_KEY_VALUE_TABLE_H_
diff --git a/chrome/browser/predictors/resource_prefetch_common.cc b/chrome/browser/predictors/navigation_id.cc similarity index 96% rename from chrome/browser/predictors/resource_prefetch_common.cc rename to chrome/browser/predictors/navigation_id.cc index 5f3020ac..43befd57 100644 --- a/chrome/browser/predictors/resource_prefetch_common.cc +++ b/chrome/browser/predictors/navigation_id.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/predictors/resource_prefetch_common.h" +#include "chrome/browser/predictors/navigation_id.h" #include <string> #include <tuple>
diff --git a/chrome/browser/predictors/resource_prefetch_common.h b/chrome/browser/predictors/navigation_id.h similarity index 86% rename from chrome/browser/predictors/resource_prefetch_common.h rename to chrome/browser/predictors/navigation_id.h index 8edd401b..7c2c112 100644 --- a/chrome/browser/predictors/resource_prefetch_common.h +++ b/chrome/browser/predictors/navigation_id.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_PREDICTORS_RESOURCE_PREFETCH_COMMON_H_ -#define CHROME_BROWSER_PREDICTORS_RESOURCE_PREFETCH_COMMON_H_ +#ifndef CHROME_BROWSER_PREDICTORS_NAVIGATION_ID_H_ +#define CHROME_BROWSER_PREDICTORS_NAVIGATION_ID_H_ #include <stddef.h> @@ -44,4 +44,4 @@ } // namespace predictors -#endif // CHROME_BROWSER_PREDICTORS_RESOURCE_PREFETCH_COMMON_H_ +#endif // CHROME_BROWSER_PREDICTORS_NAVIGATION_ID_H_
diff --git a/chrome/browser/predictors/resource_prefetch_predictor.h b/chrome/browser/predictors/resource_prefetch_predictor.h index 3e87439..10030184 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor.h +++ b/chrome/browser/predictors/resource_prefetch_predictor.h
@@ -19,9 +19,9 @@ #include "base/scoped_observer.h" #include "base/task/cancelable_task_tracker.h" #include "base/time/time.h" -#include "chrome/browser/predictors/glowplug_key_value_data.h" #include "chrome/browser/predictors/loading_predictor_config.h" -#include "chrome/browser/predictors/resource_prefetch_common.h" +#include "chrome/browser/predictors/loading_predictor_key_value_data.h" +#include "chrome/browser/predictors/navigation_id.h" #include "chrome/browser/predictors/resource_prefetch_predictor_tables.h" #include "components/history/core/browser/history_db_task.h" #include "components/history/core/browser/history_service_observer.h" @@ -110,9 +110,10 @@ }; using RedirectDataMap = - GlowplugKeyValueData<RedirectData, internal::LastVisitTimeCompare>; + LoadingPredictorKeyValueData<RedirectData, + internal::LastVisitTimeCompare>; using OriginDataMap = - GlowplugKeyValueData<OriginData, internal::LastVisitTimeCompare>; + LoadingPredictorKeyValueData<OriginData, internal::LastVisitTimeCompare>; using NavigationMap = std::map<NavigationID, std::unique_ptr<PageRequestSummary>>;
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_tables.cc b/chrome/browser/predictors/resource_prefetch_predictor_tables.cc index da75f0c..3b1aadb 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor_tables.cc +++ b/chrome/browser/predictors/resource_prefetch_predictor_tables.cc
@@ -86,10 +86,11 @@ ResourcePrefetchPredictorTables::ResourcePrefetchPredictorTables( scoped_refptr<base::SequencedTaskRunner> db_task_runner) : PredictorTableBase(db_task_runner) { - host_redirect_table_ = std::make_unique<GlowplugKeyValueTable<RedirectData>>( - kHostRedirectTableName); - origin_table_ = - std::make_unique<GlowplugKeyValueTable<OriginData>>(kOriginTableName); + host_redirect_table_ = + std::make_unique<LoadingPredictorKeyValueTable<RedirectData>>( + kHostRedirectTableName); + origin_table_ = std::make_unique<LoadingPredictorKeyValueTable<OriginData>>( + kOriginTableName); } ResourcePrefetchPredictorTables::~ResourcePrefetchPredictorTables() = default; @@ -134,11 +135,11 @@ std::move(task).Run(DB()); } -GlowplugKeyValueTable<RedirectData>* +LoadingPredictorKeyValueTable<RedirectData>* ResourcePrefetchPredictorTables::host_redirect_table() { return host_redirect_table_.get(); } -GlowplugKeyValueTable<OriginData>* +LoadingPredictorKeyValueTable<OriginData>* ResourcePrefetchPredictorTables::origin_table() { return origin_table_.get(); }
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_tables.h b/chrome/browser/predictors/resource_prefetch_predictor_tables.h index c69f1ef..21af1f0 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor_tables.h +++ b/chrome/browser/predictors/resource_prefetch_predictor_tables.h
@@ -14,9 +14,8 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/sequenced_task_runner.h" -#include "chrome/browser/predictors/glowplug_key_value_table.h" +#include "chrome/browser/predictors/loading_predictor_key_value_table.h" #include "chrome/browser/predictors/predictor_table_base.h" -#include "chrome/browser/predictors/resource_prefetch_common.h" #include "chrome/browser/predictors/resource_prefetch_predictor.pb.h" namespace base { @@ -40,8 +39,8 @@ virtual void ExecuteDBTaskOnDBSequence(DBTask task); - virtual GlowplugKeyValueTable<RedirectData>* host_redirect_table(); - virtual GlowplugKeyValueTable<OriginData>* origin_table(); + virtual LoadingPredictorKeyValueTable<RedirectData>* host_redirect_table(); + virtual LoadingPredictorKeyValueTable<OriginData>* origin_table(); // Removes the redirects with more than |max_consecutive_misses| consecutive // misses from |data|. @@ -88,8 +87,9 @@ static int GetDatabaseVersion(sql::Database* db); static bool SetDatabaseVersion(sql::Database* db, int version); - std::unique_ptr<GlowplugKeyValueTable<RedirectData>> host_redirect_table_; - std::unique_ptr<GlowplugKeyValueTable<OriginData>> origin_table_; + std::unique_ptr<LoadingPredictorKeyValueTable<RedirectData>> + host_redirect_table_; + std::unique_ptr<LoadingPredictorKeyValueTable<OriginData>> origin_table_; DISALLOW_COPY_AND_ASSIGN(ResourcePrefetchPredictorTables); };
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_tables_unittest.cc b/chrome/browser/predictors/resource_prefetch_predictor_tables_unittest.cc index ddbb97ba..cafa2003 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor_tables_unittest.cc +++ b/chrome/browser/predictors/resource_prefetch_predictor_tables_unittest.cc
@@ -125,12 +125,12 @@ "http://google.com"}; std::vector<std::string> hosts_to_delete = {"microsoft.com"}; tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( - &GlowplugKeyValueTable<RedirectData>::DeleteData, + &LoadingPredictorKeyValueTable<RedirectData>::DeleteData, base::Unretained(tables_->host_redirect_table()), hosts_to_delete)); hosts_to_delete = {"twitter.com"}; tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( - &GlowplugKeyValueTable<OriginData>::DeleteData, + &LoadingPredictorKeyValueTable<OriginData>::DeleteData, base::Unretained(tables_->origin_table()), hosts_to_delete)); RedirectDataMap actual_host_redirect_data; @@ -156,7 +156,7 @@ 2, 0); tables_->ExecuteDBTaskOnDBSequence( - base::BindOnce(&GlowplugKeyValueTable<RedirectData>::UpdateData, + base::BindOnce(&LoadingPredictorKeyValueTable<RedirectData>::UpdateData, base::Unretained(tables_->host_redirect_table()), microsoft.primary_key(), microsoft)); @@ -164,7 +164,7 @@ InitializeOriginStat(twitter.add_origins(), "https://dogs.twitter.com", 10, 1, 0, 12., false, true); tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( - &GlowplugKeyValueTable<OriginData>::UpdateData, + &LoadingPredictorKeyValueTable<OriginData>::UpdateData, base::Unretained(tables_->origin_table()), twitter.host(), twitter)); RedirectDataMap actual_host_redirect_data; @@ -296,11 +296,11 @@ } void ResourcePrefetchPredictorTablesTest::DeleteAllData() { + tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( + &LoadingPredictorKeyValueTable<RedirectData>::DeleteAllData, + base::Unretained(tables_->host_redirect_table()))); tables_->ExecuteDBTaskOnDBSequence( - base::BindOnce(&GlowplugKeyValueTable<RedirectData>::DeleteAllData, - base::Unretained(tables_->host_redirect_table()))); - tables_->ExecuteDBTaskOnDBSequence( - base::BindOnce(&GlowplugKeyValueTable<OriginData>::DeleteAllData, + base::BindOnce(&LoadingPredictorKeyValueTable<OriginData>::DeleteAllData, base::Unretained(tables_->origin_table()))); } @@ -308,10 +308,10 @@ RedirectDataMap* host_redirect_data, OriginDataMap* origin_data) const { tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( - &GlowplugKeyValueTable<RedirectData>::GetAllData, + &LoadingPredictorKeyValueTable<RedirectData>::GetAllData, base::Unretained(tables_->host_redirect_table()), host_redirect_data)); tables_->ExecuteDBTaskOnDBSequence( - base::BindOnce(&GlowplugKeyValueTable<OriginData>::GetAllData, + base::BindOnce(&LoadingPredictorKeyValueTable<OriginData>::GetAllData, base::Unretained(tables_->origin_table()), origin_data)); } @@ -333,11 +333,11 @@ std::make_pair(microsoft.primary_key(), microsoft)); tables_->ExecuteDBTaskOnDBSequence( - base::BindOnce(&GlowplugKeyValueTable<RedirectData>::UpdateData, + base::BindOnce(&LoadingPredictorKeyValueTable<RedirectData>::UpdateData, base::Unretained(tables_->host_redirect_table()), bbc.primary_key(), bbc)); tables_->ExecuteDBTaskOnDBSequence( - base::BindOnce(&GlowplugKeyValueTable<RedirectData>::UpdateData, + base::BindOnce(&LoadingPredictorKeyValueTable<RedirectData>::UpdateData, base::Unretained(tables_->host_redirect_table()), microsoft.primary_key(), microsoft)); } @@ -362,10 +362,10 @@ test_origin_data_.insert({"abc.xyz", alphabet}); tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( - &GlowplugKeyValueTable<OriginData>::UpdateData, + &LoadingPredictorKeyValueTable<OriginData>::UpdateData, base::Unretained(tables_->origin_table()), twitter.host(), twitter)); tables_->ExecuteDBTaskOnDBSequence(base::BindOnce( - &GlowplugKeyValueTable<OriginData>::UpdateData, + &LoadingPredictorKeyValueTable<OriginData>::UpdateData, base::Unretained(tables_->origin_table()), alphabet.host(), alphabet)); } }
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc b/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc index 25e083e..9b318b3 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc +++ b/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc
@@ -38,9 +38,10 @@ using OriginDataMap = std::map<std::string, OriginData>; template <typename T> -class FakeGlowplugKeyValueTable : public GlowplugKeyValueTable<T> { +class FakeLoadingPredictorKeyValueTable + : public LoadingPredictorKeyValueTable<T> { public: - FakeGlowplugKeyValueTable() : GlowplugKeyValueTable<T>("") {} + FakeLoadingPredictorKeyValueTable() : LoadingPredictorKeyValueTable<T>("") {} void GetAllData(std::map<std::string, T>* data_map, sql::Database* db) const override { *data_map = data_; @@ -75,16 +76,16 @@ std::move(task).Run(nullptr); } - GlowplugKeyValueTable<RedirectData>* host_redirect_table() override { + LoadingPredictorKeyValueTable<RedirectData>* host_redirect_table() override { return &host_redirect_table_; } - GlowplugKeyValueTable<OriginData>* origin_table() override { + LoadingPredictorKeyValueTable<OriginData>* origin_table() override { return &origin_table_; } - FakeGlowplugKeyValueTable<RedirectData> host_redirect_table_; - FakeGlowplugKeyValueTable<OriginData> origin_table_; + FakeLoadingPredictorKeyValueTable<RedirectData> host_redirect_table_; + FakeLoadingPredictorKeyValueTable<OriginData> origin_table_; protected: ~MockResourcePrefetchPredictorTables() override = default;
diff --git a/chrome/browser/previews/previews_lite_page_browsertest.cc b/chrome/browser/previews/previews_lite_page_browsertest.cc index 8d16663..10ab94a 100644 --- a/chrome/browser/previews/previews_lite_page_browsertest.cc +++ b/chrome/browser/previews/previews_lite_page_browsertest.cc
@@ -1323,9 +1323,9 @@ base::RunLoop loop; history_service->QueryRedirectsFrom( HttpsLitePageURL(kRedirectNonPreview), - base::BindLambdaForTesting([&](const history::RedirectList* redirects) { - EXPECT_FALSE(redirects->empty()); - for (const GURL& url : *redirects) { + base::BindLambdaForTesting([&](history::RedirectList redirects) { + EXPECT_FALSE(redirects.empty()); + for (const GURL& url : redirects) { EXPECT_FALSE(previews::IsLitePageRedirectPreviewURL(url)); } loop.Quit();
diff --git a/chrome/browser/printing/cloud_print/privet_http.h b/chrome/browser/printing/cloud_print/privet_http.h index c92d33ad..75bb2bd 100644 --- a/chrome/browser/printing/cloud_print/privet_http.h +++ b/chrome/browser/printing/cloud_print/privet_http.h
@@ -157,7 +157,7 @@ virtual void Start() = 0; // Required print data. MUST be called before calling Start(). - virtual void SetData(const scoped_refptr<base::RefCountedMemory>& data) = 0; + virtual void SetData(scoped_refptr<base::RefCountedMemory> data) = 0; // Optional attributes for /submitdoc. Call before calling Start(). // |ticket| should be in CJT format.
diff --git a/chrome/browser/printing/cloud_print/privet_http_impl.cc b/chrome/browser/printing/cloud_print/privet_http_impl.cc index 0114bbf9..fd82147 100644 --- a/chrome/browser/printing/cloud_print/privet_http_impl.cc +++ b/chrome/browser/printing/cloud_print/privet_http_impl.cc
@@ -637,7 +637,7 @@ } void PrivetLocalPrintOperationImpl::SetData( - const scoped_refptr<base::RefCountedMemory>& data) { + scoped_refptr<base::RefCountedMemory> data) { DCHECK(!started_); data_ = data; }
diff --git a/chrome/browser/printing/cloud_print/privet_http_impl.h b/chrome/browser/printing/cloud_print/privet_http_impl.h index 1fd28cb..7c70752 100644 --- a/chrome/browser/printing/cloud_print/privet_http_impl.h +++ b/chrome/browser/printing/cloud_print/privet_http_impl.h
@@ -171,7 +171,7 @@ // PrivetLocalPrintOperation: void Start() override; - void SetData(const scoped_refptr<base::RefCountedMemory>& data) override; + void SetData(scoped_refptr<base::RefCountedMemory> data) override; void SetTicket(base::Value ticket) override; void SetCapabilities(const std::string& capabilities) override; void SetUsername(const std::string& user) override;
diff --git a/chrome/browser/printing/pdf_to_emf_converter.cc b/chrome/browser/printing/pdf_to_emf_converter.cc index e84f1bc..90f43cf3 100644 --- a/chrome/browser/printing/pdf_to_emf_converter.cc +++ b/chrome/browser/printing/pdf_to_emf_converter.cc
@@ -115,7 +115,7 @@ // 2. Utility converts the page, and sends back the data in a memory region. class PdfConverterImpl : public PdfConverter { public: - PdfConverterImpl(const scoped_refptr<base::RefCountedMemory>& data, + PdfConverterImpl(scoped_refptr<base::RefCountedMemory> data, const PdfRenderSettings& conversion_settings, StartCallback start_callback); ~PdfConverterImpl() override; @@ -156,7 +156,7 @@ DISALLOW_COPY_AND_ASSIGN(GetPageCallbackData); }; - void Initialize(const scoped_refptr<base::RefCountedMemory>& data); + void Initialize(scoped_refptr<base::RefCountedMemory> data); void GetPage(int page_number, const PdfConverter::GetPageCallback& get_page_callback) override; @@ -239,10 +239,9 @@ return true; } -PdfConverterImpl::PdfConverterImpl( - const scoped_refptr<base::RefCountedMemory>& data, - const PdfRenderSettings& settings, - StartCallback start_callback) +PdfConverterImpl::PdfConverterImpl(scoped_refptr<base::RefCountedMemory> data, + const PdfRenderSettings& settings, + StartCallback start_callback) : settings_(settings), start_callback_(std::move(start_callback)), weak_ptr_factory_(this) { @@ -258,8 +257,7 @@ RecordConversionMetrics(); } -void PdfConverterImpl::Initialize( - const scoped_refptr<base::RefCountedMemory>& data) { +void PdfConverterImpl::Initialize(scoped_refptr<base::RefCountedMemory> data) { if (simulate_failure_initializing_conversion_) { OnFailed(std::string("Failed to create PDF data mapping.")); return; @@ -422,7 +420,7 @@ // static std::unique_ptr<PdfConverter> PdfConverter::StartPdfConverter( - const scoped_refptr<base::RefCountedMemory>& data, + scoped_refptr<base::RefCountedMemory> data, const PdfRenderSettings& conversion_settings, StartCallback start_callback) { return std::make_unique<PdfConverterImpl>(data, conversion_settings,
diff --git a/chrome/browser/printing/pdf_to_emf_converter.h b/chrome/browser/printing/pdf_to_emf_converter.h index 5aa61f7..0808982 100644 --- a/chrome/browser/printing/pdf_to_emf_converter.h +++ b/chrome/browser/printing/pdf_to_emf_converter.h
@@ -27,7 +27,7 @@ // Starts conversion of PDF provided as |data|. Calls |start_callback| // with positive |page_count|. |page_count| is 0 if initialization failed. static std::unique_ptr<PdfConverter> StartPdfConverter( - const scoped_refptr<base::RefCountedMemory>& data, + scoped_refptr<base::RefCountedMemory> data, const PdfRenderSettings& conversion_settings, StartCallback start_callback);
diff --git a/chrome/browser/printing/print_dialog_cloud_win.cc b/chrome/browser/printing/print_dialog_cloud_win.cc index f1cc30c..66eeefd 100644 --- a/chrome/browser/printing/print_dialog_cloud_win.cc +++ b/chrome/browser/printing/print_dialog_cloud_win.cc
@@ -43,7 +43,7 @@ class PrintDataSetter : public content::WebContentsObserver { public: PrintDataSetter(content::WebContents* web_contents, - const scoped_refptr<base::RefCountedMemory>& data, + scoped_refptr<base::RefCountedMemory> data, const base::string16& print_job_title, const base::string16& print_ticket, const std::string& file_type) @@ -89,7 +89,7 @@ const base::string16& print_job_title, const base::string16& print_ticket, const std::string& file_type, - const scoped_refptr<base::RefCountedMemory>& data) { + scoped_refptr<base::RefCountedMemory> data) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); Profile* profile = Profile::FromBrowserContext(browser_context); chrome::ScopedTabbedBrowserDisplayer displayer(profile);
diff --git a/chrome/browser/printing/print_job.cc b/chrome/browser/printing/print_job.cc index 918423d5..61163cb 100644 --- a/chrome/browser/printing/print_job.cc +++ b/chrome/browser/printing/print_job.cc
@@ -94,7 +94,7 @@ } void PrintJob::StartConversionToNativeFormat( - const scoped_refptr<base::RefCountedMemory>& print_data, + scoped_refptr<base::RefCountedMemory> print_data, const gfx::Size& page_size, const gfx::Rect& content_area, const gfx::Point& physical_offsets) { @@ -243,7 +243,7 @@ page_size_(page_size), content_area_(content_area) {} - void Start(const scoped_refptr<base::RefCountedMemory>& data, + void Start(scoped_refptr<base::RefCountedMemory> data, const PdfRenderSettings& conversion_settings, PdfConverter::StartCallback start_callback) { converter_ = PdfConverter::StartPdfConverter(data, conversion_settings, @@ -281,7 +281,7 @@ }; void PrintJob::StartPdfToEmfConversion( - const scoped_refptr<base::RefCountedMemory>& bytes, + scoped_refptr<base::RefCountedMemory> bytes, const gfx::Size& page_size, const gfx::Rect& content_area) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -350,7 +350,7 @@ } void PrintJob::StartPdfToTextConversion( - const scoped_refptr<base::RefCountedMemory>& bytes, + scoped_refptr<base::RefCountedMemory> bytes, const gfx::Size& page_size) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK(!pdf_conversion_state_); @@ -367,7 +367,7 @@ } void PrintJob::StartPdfToPostScriptConversion( - const scoped_refptr<base::RefCountedMemory>& bytes, + scoped_refptr<base::RefCountedMemory> bytes, const gfx::Rect& content_area, const gfx::Point& physical_offsets, bool ps_level2) {
diff --git a/chrome/browser/printing/print_job.h b/chrome/browser/printing/print_job.h index ff5ecf2..6c0e5f5 100644 --- a/chrome/browser/printing/print_job.h +++ b/chrome/browser/printing/print_job.h
@@ -57,7 +57,7 @@ #if defined(OS_WIN) void StartConversionToNativeFormat( - const scoped_refptr<base::RefCountedMemory>& print_data, + scoped_refptr<base::RefCountedMemory> print_data, const gfx::Size& page_size, const gfx::Rect& content_area, const gfx::Point& physical_offsets); @@ -147,18 +147,18 @@ #if defined(OS_WIN) virtual void StartPdfToEmfConversion( - const scoped_refptr<base::RefCountedMemory>& bytes, + scoped_refptr<base::RefCountedMemory> bytes, const gfx::Size& page_size, const gfx::Rect& content_area); virtual void StartPdfToPostScriptConversion( - const scoped_refptr<base::RefCountedMemory>& bytes, + scoped_refptr<base::RefCountedMemory> bytes, const gfx::Rect& content_area, const gfx::Point& physical_offsets, bool ps_level2); virtual void StartPdfToTextConversion( - const scoped_refptr<base::RefCountedMemory>& bytes, + scoped_refptr<base::RefCountedMemory> bytes, const gfx::Size& page_size); void OnPdfConversionStarted(int page_count);
diff --git a/chrome/browser/printing/print_preview_data_service.cc b/chrome/browser/printing/print_preview_data_service.cc index 60194e29..e932c1b78 100644 --- a/chrome/browser/printing/print_preview_data_service.cc +++ b/chrome/browser/printing/print_preview_data_service.cc
@@ -15,7 +15,7 @@ namespace { #if DCHECK_IS_ON() -void ValidatePreviewData(const scoped_refptr<base::RefCountedMemory>& data) { +void ValidatePreviewData(scoped_refptr<base::RefCountedMemory> data) { // PDFs are generally much bigger. This is just a sanity check on size. DCHECK(data); DCHECK_GE(data->size(), 50U);
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc index 007b003..309477ec 100644 --- a/chrome/browser/printing/print_view_manager_base.cc +++ b/chrome/browser/printing/print_view_manager_base.cc
@@ -151,7 +151,7 @@ #endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) void PrintViewManagerBase::PrintDocument( - const scoped_refptr<base::RefCountedMemory>& print_data, + scoped_refptr<base::RefCountedMemory> print_data, const gfx::Size& page_size, const gfx::Rect& content_area, const gfx::Point& offsets) { @@ -171,7 +171,7 @@ #if BUILDFLAG(ENABLE_PRINT_PREVIEW) void PrintViewManagerBase::OnPrintSettingsDone( - const scoped_refptr<base::RefCountedMemory>& print_data, + scoped_refptr<base::RefCountedMemory> print_data, int page_count, PrinterHandler::PrintCallback callback, scoped_refptr<printing::PrinterQuery> printer_query) { @@ -211,7 +211,7 @@ } void PrintViewManagerBase::StartLocalPrintJob( - const scoped_refptr<base::RefCountedMemory>& print_data, + scoped_refptr<base::RefCountedMemory> print_data, int page_count, scoped_refptr<printing::PrinterQuery> printer_query, PrinterHandler::PrintCallback callback) {
diff --git a/chrome/browser/printing/print_view_manager_base.h b/chrome/browser/printing/print_view_manager_base.h index a2569836..cf07479 100644 --- a/chrome/browser/printing/print_view_manager_base.h +++ b/chrome/browser/printing/print_view_manager_base.h
@@ -123,17 +123,15 @@ // Helpers for PrintForPrintPreview(); #if BUILDFLAG(ENABLE_PRINT_PREVIEW) - void OnPrintSettingsDone( - const scoped_refptr<base::RefCountedMemory>& print_data, - int page_count, - PrinterHandler::PrintCallback callback, - scoped_refptr<PrinterQuery> printer_query); + void OnPrintSettingsDone(scoped_refptr<base::RefCountedMemory> print_data, + int page_count, + PrinterHandler::PrintCallback callback, + scoped_refptr<PrinterQuery> printer_query); - void StartLocalPrintJob( - const scoped_refptr<base::RefCountedMemory>& print_data, - int page_count, - scoped_refptr<PrinterQuery> printer_query, - PrinterHandler::PrintCallback callback); + void StartLocalPrintJob(scoped_refptr<base::RefCountedMemory> print_data, + int page_count, + scoped_refptr<PrinterQuery> printer_query, + PrinterHandler::PrintCallback callback); #endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) // Processes a NOTIFY_PRINT_JOB_EVENT notification. @@ -150,7 +148,7 @@ // Starts printing the |document| in |print_job_| with the given |print_data|. // This method assumes PrintJobHasDocument() has been called, and |print_data| // contains valid data. - void PrintDocument(const scoped_refptr<base::RefCountedMemory>& print_data, + void PrintDocument(scoped_refptr<base::RefCountedMemory> print_data, const gfx::Size& page_size, const gfx::Rect& content_area, const gfx::Point& offsets);
diff --git a/chrome/browser/printing/test_print_job.cc b/chrome/browser/printing/test_print_job.cc index 6e929b6..af1941d 100644 --- a/chrome/browser/printing/test_print_job.cc +++ b/chrome/browser/printing/test_print_job.cc
@@ -51,7 +51,7 @@ #if defined(OS_WIN) void TestPrintJob::StartPdfToEmfConversion( - const scoped_refptr<base::RefCountedMemory>& bytes, + scoped_refptr<base::RefCountedMemory> bytes, const gfx::Size& page_size, const gfx::Rect& content_area) { page_size_ = page_size; @@ -60,7 +60,7 @@ } void TestPrintJob::StartPdfToPostScriptConversion( - const scoped_refptr<base::RefCountedMemory>& bytes, + scoped_refptr<base::RefCountedMemory> bytes, const gfx::Rect& content_area, const gfx::Point& physical_offsets, bool ps_level2) { @@ -71,7 +71,7 @@ } void TestPrintJob::StartPdfToTextConversion( - const scoped_refptr<base::RefCountedMemory>& bytes, + scoped_refptr<base::RefCountedMemory> bytes, const gfx::Size& page_size) { page_size_ = page_size; type_ = PrintSettings::PrinterType::TYPE_TEXTONLY;
diff --git a/chrome/browser/printing/test_print_job.h b/chrome/browser/printing/test_print_job.h index 0c779de1..d854317 100644 --- a/chrome/browser/printing/test_print_job.h +++ b/chrome/browser/printing/test_print_job.h
@@ -56,20 +56,18 @@ #if defined(OS_WIN) // These functions fill in the corresponding member variables based on the // arguments passed in. - void StartPdfToEmfConversion( - const scoped_refptr<base::RefCountedMemory>& bytes, - const gfx::Size& page_size, - const gfx::Rect& content_area) override; + void StartPdfToEmfConversion(scoped_refptr<base::RefCountedMemory> bytes, + const gfx::Size& page_size, + const gfx::Rect& content_area) override; void StartPdfToPostScriptConversion( - const scoped_refptr<base::RefCountedMemory>& bytes, + scoped_refptr<base::RefCountedMemory> bytes, const gfx::Rect& content_area, const gfx::Point& physical_offsets, bool ps_level2) override; - void StartPdfToTextConversion( - const scoped_refptr<base::RefCountedMemory>& bytes, - const gfx::Size& page_size) override; + void StartPdfToTextConversion(scoped_refptr<base::RefCountedMemory> bytes, + const gfx::Size& page_size) override; #endif // defined(OS_WIN) private:
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc index 86d3ae5..48d16c0 100644 --- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc +++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -66,6 +66,7 @@ #include "chrome/browser/send_tab_to_self/send_tab_to_self_util.h" #include "chrome/browser/sessions/session_service_factory.h" #include "chrome/browser/sessions/tab_restore_service_factory.h" +#include "chrome/browser/sharing/sharing_service_factory.h" #include "chrome/browser/signin/about_signin_internals_factory.h" #include "chrome/browser/signin/account_consistency_mode_manager_factory.h" #include "chrome/browser/signin/account_investigator_factory.h" @@ -375,6 +376,7 @@ #if BUILDFLAG(ENABLE_SESSION_SERVICE) SessionServiceFactory::GetInstance(); #endif + SharingServiceFactory::GetInstance(); ShortcutsBackendFactory::GetInstance(); SigninProfileAttributesUpdaterFactory::GetInstance();
diff --git a/chrome/browser/resources/app_management/expandable_app_list.html b/chrome/browser/resources/app_management/expandable_app_list.html index 357bba4..6fe1a79 100644 --- a/chrome/browser/resources/app_management/expandable_app_list.html +++ b/chrome/browser/resources/app_management/expandable_app_list.html
@@ -11,8 +11,19 @@ <dom-module id="app-management-expandable-app-list"> <template> <style include="app-management-shared-css"> + #app-list-header { + align-items: center; + display: flex; + padding: 16px 12px; + } + #app-list-title { - padding: 16px 24px; + font-size: var(--cr-title-text_-_font-size); + margin-inline-start: 12px; + } + + #back-button { + margin-inline-start: 0; } #collapse { @@ -22,7 +33,12 @@ } </style> <div class="card-container"> - <div id="app-list-title" class="header-text">[[listTitle]]</div> + <div id="app-list-header"> + <cr-icon-button class="icon-arrow-back" id="back-button" + on-click="onClickBack_" aria-label="$i18n{back}"> + </cr-icon-button> + <div id="app-list-title" class="header-text">[[listTitle]]</div> + </div> <iron-collapse id="collapse"> <slot></slot> </iron-collapse>
diff --git a/chrome/browser/resources/app_management/expandable_app_list.js b/chrome/browser/resources/app_management/expandable_app_list.js index c7a6f4b..62bb0cc 100644 --- a/chrome/browser/resources/app_management/expandable_app_list.js +++ b/chrome/browser/resources/app_management/expandable_app_list.js
@@ -133,4 +133,11 @@ loadTimeData.getString('lessApps') : loadTimeData.getStringF('moreApps', numApps - this.collapsedSize); }, + + onClickBack_: function() { + this.dispatchEvent(new CustomEvent('click-back-button', { + bubbles: true, + composed: true, + })); + } });
diff --git a/chrome/browser/resources/app_management/main_view.js b/chrome/browser/resources/app_management/main_view.js index de2073cb..49b1fc7 100644 --- a/chrome/browser/resources/app_management/main_view.js +++ b/chrome/browser/resources/app_management/main_view.js
@@ -37,6 +37,10 @@ }, }, + listeners: { + 'click-back-button': 'onClickBackButton', + }, + attached: function() { this.watch('apps_', state => state.apps); this.watch('notificationAppIds_', state => state.notifications.allowedIds); @@ -55,6 +59,11 @@ }, /** @private */ + onClickBackButton: function() { + window.location.href = `chrome://settings`; + }, + + /** @private */ onClickNotificationSublabel_: function() { this.dispatch(app_management.actions.changePage(PageType.NOTIFICATIONS)); },
diff --git a/chrome/browser/resources/chromeos/camera/BUILD.gn b/chrome/browser/resources/chromeos/camera/BUILD.gn index 57e3d082..09e7daa 100644 --- a/chrome/browser/resources/chromeos/camera/BUILD.gn +++ b/chrome/browser/resources/chromeos/camera/BUILD.gn
@@ -69,6 +69,8 @@ "src/images/camera_button_timer_on_10s.svg", "src/images/camera_button_timer_on_3s.svg", "src/images/camera_focus_aim.svg", + "src/images/camera_intro_banner_close.svg", + "src/images/camera_intro_banner_icon.svg", "src/images/camera_mode_photo.svg", "src/images/camera_mode_portrait.svg", "src/images/camera_mode_square.svg", @@ -82,7 +84,6 @@ "src/images/camera_shutter_video_start_hover.svg", "src/images/camera_shutter_video_stop.svg", "src/images/camera_shutter_video_stop_hover.svg", - "src/images/dialog_intro_icon.svg", "src/images/settings_button_back.svg", "src/images/settings_button_expand.svg", "src/images/settings_feedback.svg",
diff --git a/chrome/browser/resources/chromeos/camera/Makefile b/chrome/browser/resources/chromeos/camera/Makefile index 09db0f0..1770fc8 100644 --- a/chrome/browser/resources/chromeos/camera/Makefile +++ b/chrome/browser/resources/chromeos/camera/Makefile
@@ -91,6 +91,8 @@ src/images/camera_button_timer_on_10s.svg \ src/images/camera_button_timer_on_3s.svg \ src/images/camera_focus_aim.svg \ + src/images/camera_intro_banner_close.svg \ + src/images/camera_intro_banner_icon.svg \ src/images/camera_mode_photo.svg \ src/images/camera_mode_portrait.svg \ src/images/camera_mode_square.svg \ @@ -104,7 +106,6 @@ src/images/camera_shutter_video_start_hover.svg \ src/images/camera_shutter_video_stop.svg \ src/images/camera_shutter_video_stop_hover.svg \ - src/images/dialog_intro_icon.svg \ src/images/settings_button_back.svg \ src/images/settings_button_expand.svg \ src/images/settings_feedback.svg \
diff --git a/chrome/browser/resources/chromeos/camera/src/_locales/en/messages.json b/chrome/browser/resources/chromeos/camera/src/_locales/en/messages.json index a5c31c9..d7b0866 100644 --- a/chrome/browser/resources/chromeos/camera/src/_locales/en/messages.json +++ b/chrome/browser/resources/chromeos/camera/src/_locales/en/messages.json
@@ -231,16 +231,20 @@ "message": "Photos and videos taken with the camera will be moved to the Downloads folder. You can access them in Files.\n\nApps with storage permissions will have access to your photos and videos.", "description": "Message shown before moving all photos and videos stored in the Camera App to the Downloads folder." }, - "DIALOG_INTRO_TITLE": { + "BANNER_TITLE": { "message": "A whole new look", - "description": "Title of dialog shown for introducing new camera App UI." + "description": "Title of banner shown for introducing new camera App UI." }, - "DIALOG_INTRO_MSG": { + "BANNER_MSG": { "message": "Your camera now supports new modes and your photos and videos will be available under your Downloads folders.", - "description": "Message in the dialog shown for introducing new camera App UI." + "description": "Message in the banner shown for introducing new camera App UI." }, - "DIALOG_GOT_IT_BUTTON": { - "message": "Got it", - "description": "Label for the got it button in the dialog for introducing new camera App UI." + "BANNER_CLOSE_BUTTON": { + "message": "Close", + "description": "Label for close introducing new camera App UI banner button." + }, + "BANNER_LEARN_MORE_BUTTON": { + "message": "Learn more", + "description": "Label for learn more about new camera App UI button." } } \ No newline at end of file
diff --git a/chrome/browser/resources/chromeos/camera/src/css/main.css b/chrome/browser/resources/chromeos/camera/src/css/main.css index f4f76d6..966a20c 100644 --- a/chrome/browser/resources/chromeos/camera/src/css/main.css +++ b/chrome/browser/resources/chromeos/camera/src/css/main.css
@@ -448,7 +448,6 @@ #videoresolutionsettings, #browser, #message-dialog, -#intro-dialog, #warning { bottom: 0; left: 0; @@ -469,7 +468,6 @@ body.videoresolutionsettings #videoresolutionsettings, body.browser #browser, body.message-dialog #message-dialog, -body.intro-dialog #intro-dialog, body.warning #warning { opacity: 1; transition: opacity 100ms; @@ -912,6 +910,70 @@ } } +#banner { + background: white; + border-radius: 8px; + bottom: -130px; + display: none; + padding: 26px 29px; + width: 460px; +} + +#banner.animate { + animation: emerge 12000ms ease-out; + display: block; +} + +@keyframes emerge { + 0%, + 100% { + bottom: -130; + } + 10%, + 90% { + bottom: 31px; + } +} + +#banner-title { + color: rgb(26, 115, 232); + margin-bottom: 10px; +} + +#banner-title-icon { + background-image: url(../images/camera_intro_banner_icon.svg); + display: inline-block; + height: 20px; + margin-right: 10px; + vertical-align: middle; + width: 20px; +} + +#banner-title-text { + font: 450 18px 'Google Sans', sans-serif; + vertical-align: middle; +} + +#banner-msg { + color: rgb(95, 99, 104); + font: 375 15px/22px 'Roboto'; +} + +#banner-learn-more { + color: rgb(26, 115, 232); + cursor: pointer; +} + +#banner-close { + background-image: url(../images/camera_intro_banner_close.svg); + display: block; + height: 20px; + position: absolute; + right: 15px; + top: 15px; + width: 20px; +} + .menu { background: rgba(0, 0, 0, 0.75); display: flex; @@ -1143,49 +1205,6 @@ border: none; } -#intro-dialog .dialog-popup { - align-items: center; - justify-content: center; - padding: 32px 50px; - text-align: center; - width: 360px; -} - -#intro-dialog .dialog-title-icon { - background-image: url(../images/dialog_intro_icon.svg); - background-size: cover; - height: 32px; - width: 32px; -} - -#intro-dialog .dialog-title { - color: rgb(32, 33, 36); - font: normal 28px/36px 'Google Sans', sans-serif; - margin-top: 20px; -} - -#intro-dialog .dialog-msg { - color: rgb(95, 99, 104); - font: normal 13px/20px 'Roboto'; - margin-top: 12px; - padding: 0; -} - -#intro-dialog .dialog-buttons { - justify-content: center; - margin-top: 32px; -} - -#intro-dialog .dialog-positive-button { - background: rgb(26, 115, 232); - border: none; - color: white; - font: 500 13px/20px 'Roboto', sans-serif; - height: 32px; - margin: 0; - padding: 0 16px; -} - #spinner { background-image: url(../images/spinner.svg); height: 32px;
diff --git a/chrome/browser/resources/chromeos/camera/src/images/camera_intro_banner_close.svg b/chrome/browser/resources/chromeos/camera/src/images/camera_intro_banner_close.svg new file mode 100644 index 0000000..5a0d39bf --- /dev/null +++ b/chrome/browser/resources/chromeos/camera/src/images/camera_intro_banner_close.svg
@@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="20px" height="20px" viewBox="10 10 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <!-- Generator: Sketch 54.1 (76490) - https://sketchapp.com --> + <title>ic_close</title> + <desc>Created with Sketch.</desc> + <defs> + <polygon id="path-1" points="16 5.41 14.59 4 10 8.59 5.41 4 4 5.41 8.59 10 4 14.59 5.41 16 10 11.41 14.59 16 16 14.59 11.41 10"></polygon> + </defs> + <g id="ic_close" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g> + <rect id="Tap-target" x="0" y="0" width="40" height="40"></rect> + <g id="dense/navigation/close" transform="translate(10.000000, 10.000000)"> + <mask id="mask-2" fill="white"> + <use xlink:href="#path-1"></use> + </mask> + <use id="Color-fill" fill="#5F6368" fill-rule="evenodd" xlink:href="#path-1"></use> + </g> + </g> + </g> +</svg>
diff --git a/chrome/browser/resources/chromeos/camera/src/images/dialog_intro_icon.svg b/chrome/browser/resources/chromeos/camera/src/images/camera_intro_banner_icon.svg similarity index 100% rename from chrome/browser/resources/chromeos/camera/src/images/dialog_intro_icon.svg rename to chrome/browser/resources/chromeos/camera/src/images/camera_intro_banner_icon.svg
diff --git a/chrome/browser/resources/chromeos/camera/src/js/main.js b/chrome/browser/resources/chromeos/camera/src/js/main.js index 4e0383f..2a07b40 100644 --- a/chrome/browser/resources/chromeos/camera/src/js/main.js +++ b/chrome/browser/resources/chromeos/camera/src/js/main.js
@@ -65,7 +65,6 @@ this.browserView_, new cca.views.Warning(), new cca.views.Dialog('#message-dialog'), - new cca.views.Dialog('#intro-dialog'), ]); }; @@ -164,7 +163,6 @@ } this.model_.load(); cca.nav.open('camera'); - this.openIntroDialog_(); }).catch((error) => { console.error(error); if (error && error.message == 'no-migrate') { @@ -188,19 +186,6 @@ }; /** - * Tries to open dialog for introducing new CCA. - * @private - */ -cca.App.prototype.openIntroDialog_ = function() { - chrome.storage.local.get(['isIntroDialogShown'], (values) => { - if (!values['isIntroDialogShown']) { - cca.nav.open('intro-dialog'); - chrome.storage.local.set({isIntroDialogShown: true}); - } - }); -}; - -/** * @type {cca.App} Singleton of the App object. * @private */
diff --git a/chrome/browser/resources/chromeos/camera/src/js/util.js b/chrome/browser/resources/chromeos/camera/src/js/util.js index cc53ffc..ccc9de4a 100644 --- a/chrome/browser/resources/chromeos/camera/src/js/util.js +++ b/chrome/browser/resources/chromeos/camera/src/js/util.js
@@ -858,3 +858,11 @@ // width matches screen width here as workarounds. return chrome.app.window.current().outerBounds.width >= screen.width; }; + +/** + * Opens help. + */ +cca.util.openHelp = function() { + window.open( + 'https://support.google.com/chromebook/?p=camera_usage_on_chromebook'); +};
diff --git a/chrome/browser/resources/chromeos/camera/src/js/views/camera.js b/chrome/browser/resources/chromeos/camera/src/js/views/camera.js index baf23e0..f3e65b59 100644 --- a/chrome/browser/resources/chromeos/camera/src/js/views/camera.js +++ b/chrome/browser/resources/chromeos/camera/src/js/views/camera.js
@@ -68,6 +68,16 @@ this.stop_.bind(this)); /** + * @type {HTMLElement} + */ + this.banner_ = document.querySelector('#banner'); + + /** + * @type {HTMLButtonElement} + */ + this.bannerLearnMore_ = document.querySelector('#banner-learn-more'); + + /** * Modes for the camera. * @type {cca.views.camera.Modes} * @private @@ -128,6 +138,14 @@ document.querySelectorAll('#stop-takephoto, #stop-recordvideo') .forEach((btn) => btn.addEventListener('click', () => this.endTake_())); + document.querySelector('#banner-close').addEventListener('click', () => { + cca.util.animateCancel(this.banner_); + }); + + document.querySelector('#banner-learn-more').addEventListener('click', () => { + cca.util.openHelp(); + }); + // Monitor the states to stop camera when locked/minimized. chrome.idle.onStateChanged.addListener((newState) => { this.locked_ = (newState == 'locked'); @@ -148,9 +166,20 @@ * @override */ cca.views.Camera.prototype.focus = function() { - // Avoid focusing invisible shutters. - document.querySelectorAll('.shutter') - .forEach((btn) => btn.offsetParent && btn.focus()); + (async () => { + const values = await new Promise((resolve) => { + chrome.storage.local.get(['isIntroShown'], resolve); + }); + if (!values.isIntroShown) { + chrome.storage.local.set({isIntroShown: true}); + cca.util.animateOnce(this.banner_); + this.bannerLearnMore_.focus({preventScroll: true}); + } else { + // Avoid focusing invisible shutters. + document.querySelectorAll('.shutter') + .forEach((btn) => btn.offsetParent && btn.focus()); + } + })(); };
diff --git a/chrome/browser/resources/chromeos/camera/src/js/views/settings.js b/chrome/browser/resources/chromeos/camera/src/js/views/settings.js index 469e9f9..0c15b6c6 100644 --- a/chrome/browser/resources/chromeos/camera/src/js/views/settings.js +++ b/chrome/browser/resources/chromeos/camera/src/js/views/settings.js
@@ -60,7 +60,7 @@ 'settings-timerdur': () => this.openSubSettings('timersettings'), 'settings-resolution': () => this.openSubSettings('resolutionsettings'), 'settings-feedback': () => this.openFeedback(), - 'settings-help': () => this.openHelp_(), + 'settings-help': () => cca.util.openHelp(), }); // End of properties, seal the object. @@ -95,15 +95,6 @@ }; /** - * Opens help. - * @private - */ -cca.views.MasterSettings.prototype.openHelp_ = function() { - window.open( - 'https://support.google.com/chromebook/?p=camera_usage_on_chromebook'); -}; - -/** * Creates the controller of resolution settings view. * @param {cca.ResolutionEventBroker} resolBroker * @extends {cca.views.BaseSettings}
diff --git a/chrome/browser/resources/chromeos/camera/src/strings/camera_strings.grd b/chrome/browser/resources/chromeos/camera/src/strings/camera_strings.grd index fb32abe..9ba4fd6d 100644 --- a/chrome/browser/resources/chromeos/camera/src/strings/camera_strings.grd +++ b/chrome/browser/resources/chromeos/camera/src/strings/camera_strings.grd
@@ -273,14 +273,17 @@ <message desc="Label for switch to take portrait photo mode button." name="IDS_LABEL_SWITCH_TAKE_PORTRAIT_PHOTO_BUTTON"> Portrait </message> - <message desc="Title of dialog shown for introducing new camera App UI." name="IDS_DIALOG_INTRO_TITLE"> + <message desc="Title of banner shown for introducing new camera App UI." name="IDS_BANNER_TITLE"> A whole new look </message> - <message desc="Message in the dialog shown for introducing new camera App UI." name="IDS_DIALOG_INTRO_MSG"> + <message desc="Message in the banner shown for introducing new camera App UI." name="IDS_BANNER_MSG"> Your camera now supports new modes and your photos and videos will be available under your Downloads folders. </message> - <message desc="Label for the got it button in the dialog for introducing new camera App UI." name="IDS_DIALOG_GOT_IT_BUTTON"> - Got it + <message desc="Label for close introducing new camera App UI banner button." name="IDS_BANNER_CLOSE_BUTTON"> + Close + </message> + <message desc="Label for learn more about new camera App UI button." name="IDS_BANNER_LEARN_MORE_BUTTON"> + Learn more </message> </messages> </release>
diff --git a/chrome/browser/resources/chromeos/camera/src/strings/camera_strings_grd/ID_BANNER_CLOSE_BUTTON.png.sha1 b/chrome/browser/resources/chromeos/camera/src/strings/camera_strings_grd/ID_BANNER_CLOSE_BUTTON.png.sha1 new file mode 100644 index 0000000..a43b35a --- /dev/null +++ b/chrome/browser/resources/chromeos/camera/src/strings/camera_strings_grd/ID_BANNER_CLOSE_BUTTON.png.sha1
@@ -0,0 +1 @@ +a2a866ad16b589216fdb369e10e2c0ca3bc15ac0 \ No newline at end of file
diff --git a/chrome/browser/resources/chromeos/camera/src/strings/camera_strings_grd/ID_BANNER_LEARN_MORE.png.sha1 b/chrome/browser/resources/chromeos/camera/src/strings/camera_strings_grd/ID_BANNER_LEARN_MORE.png.sha1 new file mode 100644 index 0000000..a43b35a --- /dev/null +++ b/chrome/browser/resources/chromeos/camera/src/strings/camera_strings_grd/ID_BANNER_LEARN_MORE.png.sha1
@@ -0,0 +1 @@ +a2a866ad16b589216fdb369e10e2c0ca3bc15ac0 \ No newline at end of file
diff --git a/chrome/browser/resources/chromeos/camera/src/strings/camera_strings_grd/ID_BANNER_MSG.png.sha1 b/chrome/browser/resources/chromeos/camera/src/strings/camera_strings_grd/ID_BANNER_MSG.png.sha1 new file mode 100644 index 0000000..a43b35a --- /dev/null +++ b/chrome/browser/resources/chromeos/camera/src/strings/camera_strings_grd/ID_BANNER_MSG.png.sha1
@@ -0,0 +1 @@ +a2a866ad16b589216fdb369e10e2c0ca3bc15ac0 \ No newline at end of file
diff --git a/chrome/browser/resources/chromeos/camera/src/strings/camera_strings_grd/ID_BANNER_TITLE.png.sha1 b/chrome/browser/resources/chromeos/camera/src/strings/camera_strings_grd/ID_BANNER_TITLE.png.sha1 new file mode 100644 index 0000000..a43b35a --- /dev/null +++ b/chrome/browser/resources/chromeos/camera/src/strings/camera_strings_grd/ID_BANNER_TITLE.png.sha1
@@ -0,0 +1 @@ +a2a866ad16b589216fdb369e10e2c0ca3bc15ac0 \ No newline at end of file
diff --git a/chrome/browser/resources/chromeos/camera/src/views/main.html b/chrome/browser/resources/chromeos/camera/src/views/main.html index 232dd7b..63ecad1 100644 --- a/chrome/browser/resources/chromeos/camera/src/views/main.html +++ b/chrome/browser/resources/chromeos/camera/src/views/main.html
@@ -61,6 +61,19 @@ </div> <div class="centered-overlay" id="camera-mode"></div> </div> + <div id="banner" class="horizontal-center-stripe" aria-live="polite"> + <div id="banner-title"> + <div id="banner-title-icon"></div> + <span id="banner-title-text" i18n-content="banner_title"></span> + </div> + <div id="banner-msg"> + <span i18n-content="banner_msg"></span> + <button id="banner-learn-more" + i18n-content="banner_learn_more_button"> + </button> + </div> + <button id="banner-close" i18n-label="banner_close_button"></button> + </div> <div id="modes-group" class="buttons right-stripe"> <div class="mode-item"> <input type="radio" name="mode" @@ -332,17 +345,6 @@ </div> </div> </div> - <div id="intro-dialog" class="dialog"> - <div class="dialog-popup" role="dialog" aria-labelledby="dialog-msg"> - <div class="dialog-title-icon"></div> - <div class="dialog-title" i18n-content="dialog_intro_title"></div> - <div class="dialog-msg" i18n-content="dialog_intro_msg"></div> - <div class="dialog-buttons"> - <button class="dialog-positive-button" tabindex="0" - i18n-content="dialog_got_it_button"></button> - </div> - </div> - </div> <div class="centered-overlay" id="toast" aria-live="polite"></div> <div id="tooltip" aria-hidden="true"></div> <audio id="sound-tick" src="../sounds/tick.ogg" data-timeout="200">
diff --git a/chrome/browser/resources/chromeos/login/custom_elements_login.html b/chrome/browser/resources/chromeos/login/custom_elements_login.html index 8d4a561..0770d227 100644 --- a/chrome/browser/resources/chromeos/login/custom_elements_login.html +++ b/chrome/browser/resources/chromeos/login/custom_elements_login.html
@@ -4,6 +4,7 @@ <include src="gaia_input_form.html"> <include src="gaia_input.html"> <include src="gaia_password_changed.html"> +<include src="screen_gaia_signin.html"> <include src="hd-iron-icon.html"> <include src="offline_gaia.html"> <include src="saml_confirm_password.html">
diff --git a/chrome/browser/resources/chromeos/login/custom_elements_login.js b/chrome/browser/resources/chromeos/login/custom_elements_login.js index 7b2213f2..a400a60 100644 --- a/chrome/browser/resources/chromeos/login/custom_elements_login.js +++ b/chrome/browser/resources/chromeos/login/custom_elements_login.js
@@ -10,6 +10,7 @@ // <include src="gaia_input_form.js"> // <include src="gaia_input.js"> // <include src="gaia_password_changed.js"> +// <include src="screen_gaia_signin.js"> // <include src="hd-iron-icon.js"> // <include src="offline_gaia.js"> // <include src="saml_confirm_password.js">
diff --git a/chrome/browser/resources/chromeos/login/custom_elements_oobe.html b/chrome/browser/resources/chromeos/login/custom_elements_oobe.html index 0253c63d..4e7ca93 100644 --- a/chrome/browser/resources/chromeos/login/custom_elements_oobe.html +++ b/chrome/browser/resources/chromeos/login/custom_elements_oobe.html
@@ -4,6 +4,7 @@ <include src="gaia_input_form.html"> <include src="gaia_input.html"> <include src="gaia_password_changed.html"> +<include src="screen_gaia_signin.html"> <include src="hd-iron-icon.html"> <include src="network_select_login.html"> <include src="notification_card.html">
diff --git a/chrome/browser/resources/chromeos/login/custom_elements_oobe.js b/chrome/browser/resources/chromeos/login/custom_elements_oobe.js index 9a2c065..7eeeca0f 100644 --- a/chrome/browser/resources/chromeos/login/custom_elements_oobe.js +++ b/chrome/browser/resources/chromeos/login/custom_elements_oobe.js
@@ -17,6 +17,7 @@ // <include src="gaia_input_form.js"> // <include src="gaia_input.js"> // <include src="gaia_password_changed.js"> +// <include src="screen_gaia_signin.js"> // <include src="hd-iron-icon.js"> // <include src="network_select_login.js"> // <include src="notification_card.js">
diff --git a/chrome/browser/resources/chromeos/login/md_login.html b/chrome/browser/resources/chromeos/login/md_login.html index 04e2673..844aba8 100644 --- a/chrome/browser/resources/chromeos/login/md_login.html +++ b/chrome/browser/resources/chromeos/login/md_login.html
@@ -61,7 +61,6 @@ <link rel="stylesheet" href="screen_app_launch_splash.css"> <link rel="stylesheet" href="screen_arc_kiosk_splash.css"> <link rel="stylesheet" href="screen_arc_terms_of_service.css"> -<link rel="stylesheet" href="screen_gaia_signin.css"> <link rel="stylesheet" href="screen_error_message.css"> <link rel="stylesheet" href="screen_tpm_error.css"> <link rel="stylesheet" href="screen_password_changed.css">
diff --git a/chrome/browser/resources/chromeos/login/md_login.js b/chrome/browser/resources/chromeos/login/md_login.js index de43f1bf..f523887 100644 --- a/chrome/browser/resources/chromeos/login/md_login.js +++ b/chrome/browser/resources/chromeos/login/md_login.js
@@ -31,7 +31,6 @@ // <include src="screen_arc_kiosk_splash.js"> // <include src="screen_arc_terms_of_service.js"> // <include src="screen_error_message.js"> -// <include src="screen_gaia_signin.js"> // <include src="screen_password_changed.js"> // <include src="screen_tpm_error.js"> // <include src="screen_wrong_hwid.js"> @@ -73,7 +72,6 @@ cr.ui.login.DisplayManager.initialize(); login.WrongHWIDScreen.register(); login.AccountPickerScreen.register(); - login.GaiaSigninScreen.register(); login.ResetScreen.register(); login.AutolaunchScreen.register(); login.KioskEnableScreen.register();
diff --git a/chrome/browser/resources/chromeos/login/md_login_screens.html b/chrome/browser/resources/chromeos/login/md_login_screens.html index 76413753..f66f4c2 100644 --- a/chrome/browser/resources/chromeos/login/md_login_screens.html +++ b/chrome/browser/resources/chromeos/login/md_login_screens.html
@@ -7,7 +7,8 @@ <include src="../../../../../ui/login/account_picker/chromeos_screen_account_picker.html"> <include src="screen_arc_terms_of_service.html"> <include src="screen_error_message.html"> -<include src="screen_gaia_signin.html"> +<gaia-signin id="gaia-signin" class="step right hidden" hidden> +</gaia-signin> <include src="screen_password_changed.html"> <include src="screen_tpm_error.html"> <include src="screen_wrong_hwid.html">
diff --git a/chrome/browser/resources/chromeos/login/oobe.html b/chrome/browser/resources/chromeos/login/oobe.html index 79111f9a..3ad80e1 100644 --- a/chrome/browser/resources/chromeos/login/oobe.html +++ b/chrome/browser/resources/chromeos/login/oobe.html
@@ -67,7 +67,6 @@ <link rel="stylesheet" href="screen_app_launch_splash.css"> <link rel="stylesheet" href="screen_arc_kiosk_splash.css"> <link rel="stylesheet" href="screen_arc_terms_of_service.css"> -<link rel="stylesheet" href="screen_gaia_signin.css"> <link rel="stylesheet" href="screen_error_message.css"> <link rel="stylesheet" href="screen_tpm_error.css"> <link rel="stylesheet" href="screen_password_changed.css">
diff --git a/chrome/browser/resources/chromeos/login/oobe.js b/chrome/browser/resources/chromeos/login/oobe.js index 155b9c9..b580e396 100644 --- a/chrome/browser/resources/chromeos/login/oobe.js +++ b/chrome/browser/resources/chromeos/login/oobe.js
@@ -32,7 +32,6 @@ // <include src="screen_arc_kiosk_splash.js"> // <include src="screen_arc_terms_of_service.js"> // <include src="screen_error_message.js"> -// <include src="screen_gaia_signin.js"> // <include src="screen_password_changed.js"> // <include src="screen_tpm_error.js"> // <include src="screen_wrong_hwid.js"> @@ -82,7 +81,6 @@ login.AutolaunchScreen.register(); login.KioskEnableScreen.register(); login.AccountPickerScreen.register(); - login.GaiaSigninScreen.register(); login.OAuthEnrollmentScreen.register(); login.ErrorMessageScreen.register(); login.TPMErrorMessageScreen.register();
diff --git a/chrome/browser/resources/chromeos/login/oobe_network.html b/chrome/browser/resources/chromeos/login/oobe_network.html index 03f133d..d32689b4 100644 --- a/chrome/browser/resources/chromeos/login/oobe_network.html +++ b/chrome/browser/resources/chromeos/login/oobe_network.html
@@ -25,7 +25,7 @@ </div> <div slot="bottom-buttons" class="layout horizontal justified"> <oobe-back-button on-tap="onBackClicked_"></oobe-back-button> - <oobe-next-button disabled="[[!isConnected_]]" + <oobe-next-button id="nextButton" disabled="[[!isConnected_]]" on-tap="onNextClicked_"></oobe-next-button> </div> </oobe-dialog>
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen.css b/chrome/browser/resources/chromeos/login/oobe_screen.css index 138004b..835911d 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen.css +++ b/chrome/browser/resources/chromeos/login/oobe_screen.css
@@ -82,18 +82,6 @@ visibility: hidden; } -.step-loading { - align-items: center; - bottom: 0; - display: flex; - justify-content: center; - left: 0; - min-height: 0; - position: absolute; - right: 0; - top: 0; -} - /* Fixes performance problem caused by http://crbug.com/229405 . */ .step.hidden .throbber, .step.hidden .spinner,
diff --git a/chrome/browser/resources/chromeos/login/oobe_screens.html b/chrome/browser/resources/chromeos/login/oobe_screens.html index e93d553..1101982 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screens.html +++ b/chrome/browser/resources/chromeos/login/oobe_screens.html
@@ -18,7 +18,8 @@ <include src="../../../../../ui/login/account_picker/chromeos_screen_account_picker.html"> <include src="screen_error_message.html"> <include src="screen_arc_terms_of_service.html"> -<include src="screen_gaia_signin.html"> +<gaia-signin id="gaia-signin" class="step right hidden" hidden> +</gaia-signin> <include src="screen_password_changed.html"> <include src="screen_tpm_error.html"> <include src="screen_wrong_hwid.html">
diff --git a/chrome/browser/resources/chromeos/login/screen_gaia_signin.css b/chrome/browser/resources/chromeos/login/screen_gaia_signin.css index 2c79b05..9823f25 100644 --- a/chrome/browser/resources/chromeos/login/screen_gaia_signin.css +++ b/chrome/browser/resources/chromeos/login/screen_gaia_signin.css
@@ -2,12 +2,12 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ -#gaia-signin { +:host { height: 528px; width: 448px; } -#gaia-signin.v2 { +:host(.v2) { height: unset; padding: unset; width: unset; @@ -48,7 +48,7 @@ transition: opacity 500ms ease-out; } -#gaia-signin .step-contents { +:host .step-contents { -webkit-box-pack: center; display: -webkit-box; height: 100%; @@ -77,15 +77,27 @@ font-size: 13px; } -#gaia-signin.whitelist-error .step-contents, -#gaia-signin.whitelist-error .gaia-dialog { +:host(.whitelist-error) .step-contents, +:host(.whitelist-error) .gaia-dialog { visibility: hidden; } -#gaia-signin.whitelist-error .step-loading { +:host(.whitelist-error) .step-loading { visibility: hidden; } +.step-loading { + align-items: center; + bottom: 0; + display: flex; + justify-content: center; + left: 0; + min-height: 0; + position: absolute; + right: 0; + top: 0; +} + #gaia-whitelist-error { bottom: 0; display: block; @@ -96,15 +108,21 @@ visibility: hidden; } -#gaia-signin.whitelist-error #gaia-whitelist-error { +:host(.whitelist-error) #gaia-whitelist-error { visibility: visible; } -#gaia-signin.v2 #gaia-step-contents { +:host(.loading) .step-contents, +:host(.loading) .step-controls, +:host(.loading) .step-extra-controls { + visibility: hidden; +} + +:host(.v2) #gaia-step-contents { display: none; } -#gaia-signin.v2.saml #signin-frame { +:host(.v2.saml) #signin-frame { height: 516px; padding-top: 44px; }
diff --git a/chrome/browser/resources/chromeos/login/screen_gaia_signin.html b/chrome/browser/resources/chromeos/login/screen_gaia_signin.html index 67762a2f..d8ef48207 100644 --- a/chrome/browser/resources/chromeos/login/screen_gaia_signin.html +++ b/chrome/browser/resources/chromeos/login/screen_gaia_signin.html
@@ -1,46 +1,55 @@ -<link rel="import" href="chrome://oobe/custom_elements.html"> +<!-- Copyright 2019 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> -<div class="step right hidden" id="gaia-signin" role="group" - aria-live="polite" hidden> - <oobe-dialog id="signin-frame-dialog" class="gaia-dialog" role="dialog" - has-buttons no-header no-footer-padding no-buttons-padding hidden> - <div id="signin-frame-container-v2" slot="footer" - class="flex layout vertical"> - <webview id="signin-frame" name="signin-frame" hidden></webview> - </div> - <div id="gaia-screen-navigation-buttons" - slot="bottom-buttons" class="relative flex layout horizontal center"> - <div id="buttons-container" class="fit"> - <oobe-back-button id="signin-back-button"></oobe-back-button> - <div class="flex"> - </div> +<dom-module id="gaia-signin"> + <link rel="stylesheet" href="oobe_dialog_host.css"> + <link rel="stylesheet" href="oobe_flex_layout.css"> + <link rel="stylesheet" href="screen_gaia_signin.css"> + + <template> + + <oobe-dialog id="signin-frame-dialog" class="gaia-dialog" role="dialog" + has-buttons no-header no-footer-padding no-buttons-padding hidden> + <div id="signin-frame-container-v2" slot="footer" + class="flex layout vertical"> + <webview id="signin-frame" name="signin-frame" hidden></webview> </div> - <div id="gaia-screen-buttons-overlay" class="fit" hidden></div> + <div id="gaia-screen-navigation-buttons" + slot="bottom-buttons" class="relative flex layout horizontal center"> + <div id="buttons-container" class="fit"> + <oobe-back-button id="signin-back-button"></oobe-back-button> + <div class="flex"> + </div> + </div> + <div id="gaia-screen-buttons-overlay" class="fit" hidden></div> + </div> + </oobe-dialog> + <offline-gaia id="offline-gaia" class="gaia-dialog" hidden> + </offline-gaia> + <offline-ad-login id="offline-ad-auth" class="gaia-dialog" hidden + i18n-values="ad-welcome-message:loginWelcomeMessage"> + </offline-ad-login> + <div id="gaia-step-contents" class="step-contents"> + <div id="gaia-signin-form-container"> + <saml-interstitial id="saml-interstitial" class="fit gaia-dialog" + hidden> + </saml-interstitial> + </div> </div> - </oobe-dialog> - <offline-gaia id="offline-gaia" class="gaia-dialog" hidden> - </offline-gaia> - <offline-ad-login id="offline-ad-auth" class="gaia-dialog" hidden - i18n-values="ad-welcome-message:loginWelcomeMessage"> - </offline-ad-login> - <div id="gaia-step-contents" class="step-contents"> - <div id="gaia-signin-form-container"> - <saml-interstitial id="saml-interstitial" class="fit gaia-dialog" - hidden> - </saml-interstitial> + <div id="gaia-loading" class="step-loading gaia-dialog" hidden> + <throbber-notice i18n-values="text:gaiaLoading"></throbber-notice> </div> - </div> - <div id="gaia-loading" class="step-loading gaia-dialog" hidden> - <throbber-notice i18n-values="text:gaiaLoading"></throbber-notice> - </div> - <notification-card id="gaia-whitelist-error" type="fail" class="gaia-dialog" - i18n-values="button-label:tryAgainButton; - link-label:learnMoreButton"> - </notification-card> - <div id="saml-notice-container" hidden> - <span id="saml-notice-recording-indicator" hidden> - <img src="chrome://theme/IDR_TAB_RECORDING_INDICATOR"> - </span> - <span id="saml-notice-message"></span> - </div> -</div> + <notification-card id="gaia-whitelist-error" type="fail" class="gaia-dialog" + i18n-values="button-label:tryAgainButton; + link-label:learnMoreButton"> + </notification-card> + <div id="saml-notice-container" hidden> + <span id="saml-notice-recording-indicator" hidden> + <img src="chrome://theme/IDR_TAB_RECORDING_INDICATOR"> + </span> + <span id="saml-notice-message"></span> + </div> + + </template> +</dom-module>
diff --git a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js index 2702ee3..b8de7e3b 100644 --- a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js +++ b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
@@ -6,1229 +6,1261 @@ * @fileoverview Oobe signin screen implementation. */ -login.createScreen('GaiaSigninScreen', 'gaia-signin', function() { - // GAIA animation guard timer. Started when GAIA page is loaded - // (Authenticator 'ready' event) and is intended to guard against edge cases - // when 'showView' message is not generated/received. - /** @const */ var GAIA_ANIMATION_GUARD_MILLISEC = 300; +'use strict'; - // Maximum Gaia loading time in seconds. - /** @const */ var MAX_GAIA_LOADING_TIME_SEC = 60; +(function() { - // The help topic regarding user not being in the whitelist. - /** @const */ var HELP_CANT_ACCESS_ACCOUNT = 188036; +// GAIA animation guard timer. Started when GAIA page is loaded +// (Authenticator 'ready' event) and is intended to guard against edge cases +// when 'showView' message is not generated/received. +/** @const */ var GAIA_ANIMATION_GUARD_MILLISEC = 300; - // Amount of time the user has to be idle for before showing the online login - // page. - /** @const */ var IDLE_TIME_UNTIL_EXIT_OFFLINE_IN_MILLISECONDS = 180 * 1000; +// Maximum Gaia loading time in seconds. +/** @const */ var MAX_GAIA_LOADING_TIME_SEC = 60; - // Approximate amount of time between checks to see if we should go to the - // online login page when we're in the offline login page and the device is - // online. - /** @const */ var IDLE_TIME_CHECK_FREQUENCY = 5 * 1000; +// The help topic regarding user not being in the whitelist. +/** @const */ var HELP_CANT_ACCESS_ACCOUNT = 188036; - // Amount of time allowed for video based SAML logins, to prevent a site - // from keeping the camera on indefinitely. This is a hard deadline and - // it will not be extended by user activity. - /** @const */ var VIDEO_LOGIN_TIMEOUT = 90 * 1000; +// Amount of time the user has to be idle for before showing the online login +// page. +/** @const */ var IDLE_TIME_UNTIL_EXIT_OFFLINE_IN_MILLISECONDS = 180 * 1000; - // Horizontal padding for the error bubble. - /** @const */ var BUBBLE_HORIZONTAL_PADDING = 65; +// Approximate amount of time between checks to see if we should go to the +// online login page when we're in the offline login page and the device is +// online. +/** @const */ var IDLE_TIME_CHECK_FREQUENCY = 5 * 1000; - // Vertical padding for the error bubble. - /** @const */ var BUBBLE_VERTICAL_PADDING = -213; +// Amount of time allowed for video based SAML logins, to prevent a site +// from keeping the camera on indefinitely. This is a hard deadline and +// it will not be extended by user activity. +/** @const */ var VIDEO_LOGIN_TIMEOUT = 90 * 1000; + +// Horizontal padding for the error bubble. +/** @const */ var BUBBLE_HORIZONTAL_PADDING = 65; + +// Vertical padding for the error bubble. +/** @const */ var BUBBLE_VERTICAL_PADDING = -213; + +/** + * The modes this screen can be in. + * @enum {integer} + */ +var ScreenMode = { + DEFAULT: 0, // Default GAIA login flow. + OFFLINE: 1, // GAIA offline login. + SAML_INTERSTITIAL: 2, // Interstitial page before SAML redirection. + AD_AUTH: 3 // Offline Active Directory login flow. +}; + +Polymer({ + is: 'gaia-signin', + + behaviors: [LoginScreenBehavior, OobeDialogHostBehavior], + + EXTERNAL_API: [ + 'loadAuthExtension', + 'doReload', + 'monitorOfflineIdle', + 'updateControlsState', + 'showWhitelistCheckFailedError', + 'invalidateAd', + ], + + properties: {}, /** - * The modes this screen can be in. - * @enum {integer} + * Saved authenticator load params. + * @type {?string} + * @private */ - var ScreenMode = { - DEFAULT: 0, // Default GAIA login flow. - OFFLINE: 1, // GAIA offline login. - SAML_INTERSTITIAL: 2, // Interstitial page before SAML redirection. - AD_AUTH: 3 // Offline Active Directory login flow. - }; + authenticatorParams_: null, - return { - EXTERNAL_API: [ - 'loadAuthExtension', - 'doReload', - 'monitorOfflineIdle', - 'updateControlsState', - 'showWhitelistCheckFailedError', - 'invalidateAd', - ], + /** + * Current mode of this screen. + * @type {integer} + * @private + */ + screenMode_: ScreenMode.DEFAULT, - /** - * Saved authenticator load params. - * @type {?string} - * @private - */ - authenticatorParams_: null, + /** + * Email of the user, which is logging in using offline mode. + * @type {string} + */ + email: '', - /** - * Current mode of this screen. - * @type {integer} - * @private - */ - screenMode_: ScreenMode.DEFAULT, + /** + * Timer id of pending load. + * @type {number} + * @private + */ + loadingTimer_: undefined, - /** - * Email of the user, which is logging in using offline mode. - * @type {string} - */ - email: '', + /** + * Timer id of a guard timer that is fired in case 'showView' message + * is not received from GAIA. + * @type {number} + * @private + */ + loadAnimationGuardTimer_: undefined, - /** - * Timer id of pending load. - * @type {number} - * @private - */ - loadingTimer_: undefined, + /** + * Timer id of the video login timer. + * @type {number} + * @private + */ + videoTimer_: undefined, - /** - * Timer id of a guard timer that is fired in case 'showView' message - * is not received from GAIA. - * @type {number} - * @private - */ - loadAnimationGuardTimer_: undefined, + /** + * Whether we've processed 'showView' message - either from GAIA or from + * guard timer. + * @type {boolean} + * @private + */ + showViewProcessed_: false, - /** - * Timer id of the video login timer. - * @type {number} - * @private - */ - videoTimer_: undefined, + /** + * Whether we've processed 'authCompleted' message. + * @type {boolean} + * @private + */ + authCompleted_: false, - /** - * Whether we've processed 'showView' message - either from GAIA or from - * guard timer. - * @type {boolean} - * @private - */ - showViewProcessed_: false, + /** + * Value contained in the last received 'backButton' event. + * @type {boolean} + * @private + */ + lastBackMessageValue_: false, - /** - * Whether we've processed 'authCompleted' message. - * @type {boolean} - * @private - */ - authCompleted_: false, + /** + * Flag for tests that saml page was loaded. + * @type {boolean} + */ + samlInterstitialPageReady: false, - /** - * Value contained in the last received 'backButton' event. - * @type {boolean} - * @private - */ - lastBackMessageValue_: false, + /** + * SAML password confirmation attempt count. + * @type {number} + */ + samlPasswordConfirmAttempt_: 0, - /** - * Flag for tests that saml page was loaded. - * @type {boolean} - */ - samlInterstitialPageReady: false, + /** + * Do we currently have a setTimeout task running that tries to bring us + * back to the online login page after the user has idled for awhile? If so, + * then this id will be non-negative. + */ + tryToGoToOnlineLoginPageCallbackId_: -1, - /** - * Whether the dialog could be closed. - * This is being checked in cancel() when user clicks on signin-back-button - * (normal gaia flow) or the "Back" button in other authentication frames. - * @type {boolean} - */ - get closable() { - return Oobe.getInstance().hasUserPods || this.isOffline(); - }, + /** + * The most recent period of time that the user has interacted. This is + * only updated when the offline page is active and the device is online. + */ + mostRecentUserActivity_: Date.now(), - /** - * Returns true if the screen is at the beginning of flow (i.e. the email - * page). - * @type {boolean} - */ - isAtTheBeginning: function() { - return !this.canGoBack_() && !this.isSAML() && - !this.classList.contains('whitelist-error') && !this.authCompleted_; - }, + /** + * The UI component that hosts IdP pages. + * @type {!cr.login.Authenticator|undefined} + */ + authenticator_: undefined, - /** - * Updates visibility of UI control buttons. - */ - updateControlsState: function() { - let showGuestInOobe = !this.closable && this.isAtTheBeginning(); - chrome.send('showGuestInOobe', [showGuestInOobe]); - }, + /** @override */ + ready: function() { + this.authenticator_ = new cr.login.Authenticator(this.getSigninFrame_()); + this.authenticator_.addEventListener('ready', this.onAuthReady_.bind(this)); - /** - * Returns whether it's possible to rewind the sign-in frame one step back - * (as opposed to cancelling the sign-in flow). - * @type {boolean} - * @private - */ - canGoBack_: function() { - var isWhitelistError = this.classList.contains('whitelist-error'); - return this.lastBackMessageValue_ && !isWhitelistError && - !this.authCompleted_ && !this.loading && !this.isSAML(); - }, - - /** - * SAML password confirmation attempt count. - * @type {number} - */ - samlPasswordConfirmAttempt_: 0, - - /** - * Do we currently have a setTimeout task running that tries to bring us - * back to the online login page after the user has idled for awhile? If so, - * then this id will be non-negative. - */ - tryToGoToOnlineLoginPageCallbackId_: -1, - - /** - * The most recent period of time that the user has interacted. This is - * only updated when the offline page is active and the device is online. - */ - mostRecentUserActivity_: Date.now(), - - - /** @override */ - decorate: function() { - this.authenticator_ = new cr.login.Authenticator($('signin-frame')); - this.authenticator_.addEventListener( - 'ready', this.onAuthReady_.bind(this)); - - var that = this; - [this.authenticator_, $('offline-gaia'), $('offline-ad-auth')].forEach( - function(frame) { - // Ignore events from currently inactive frame. - var frameFilter = function(callback) { - return function(e) { - var currentFrame = null; - switch (that.screenMode_) { - case ScreenMode.DEFAULT: - case ScreenMode.SAML_INTERSTITIAL: - currentFrame = that.authenticator_; - break; - case ScreenMode.OFFLINE: - currentFrame = $('offline-gaia'); - break; - case ScreenMode.AD_AUTH: - currentFrame = $('offline-ad-auth'); - break; - } - if (frame === currentFrame) - callback.call(that, e); - }; + var that = this; + var $that = this.$; + [this.authenticator_, this.$['offline-gaia'], this.$['offline-ad-auth']] + .forEach(function(frame) { + // Ignore events from currently inactive frame. + var frameFilter = function(callback) { + return function(e) { + var currentFrame = null; + switch (that.screenMode_) { + case ScreenMode.DEFAULT: + case ScreenMode.SAML_INTERSTITIAL: + currentFrame = that.authenticator_; + break; + case ScreenMode.OFFLINE: + currentFrame = $that['offline-gaia']; + break; + case ScreenMode.AD_AUTH: + currentFrame = $that['offline-ad-auth']; + break; + } + if (frame === currentFrame) + callback.call(that, e); }; + }; - frame.addEventListener( - 'authCompleted', frameFilter(that.onAuthCompletedMessage_)); - frame.addEventListener( - 'backButton', frameFilter(that.onBackButton_)); - frame.addEventListener( - 'dialogShown', frameFilter(that.onDialogShown_)); - frame.addEventListener( - 'dialogHidden', frameFilter(that.onDialogHidden_)); - frame.addEventListener( - 'menuItemClicked', frameFilter(that.onMenuItemClicked_)); - }); - - this.authenticator_.addEventListener( - 'showView', this.onShowView_.bind(this)); - this.authenticator_.confirmPasswordCallback = - this.onAuthConfirmPassword_.bind(this); - this.authenticator_.noPasswordCallback = - this.onAuthNoPassword_.bind(this); - this.authenticator_.insecureContentBlockedCallback = - this.onInsecureContentBlocked_.bind(this); - this.authenticator_.missingGaiaInfoCallback = - this.missingGaiaInfo_.bind(this); - this.authenticator_.samlApiUsedCallback = this.samlApiUsed_.bind(this); - this.authenticator_.getIsSamlUserPasswordlessCallback = - this.getIsSamlUserPasswordless_.bind(this); - this.authenticator_.addEventListener( - 'authDomainChange', this.onAuthDomainChange_.bind(this)); - this.authenticator_.addEventListener( - 'authFlowChange', this.onAuthFlowChange_.bind(this)); - this.authenticator_.addEventListener( - 'videoEnabledChange', this.onVideoEnabledChange_.bind(this)); - - this.authenticator_.addEventListener( - 'loadAbort', this.onLoadAbortMessage_.bind(this)); - this.authenticator_.addEventListener( - 'identifierEntered', this.onIdentifierEnteredMessage_.bind(this)); - - $('signin-back-button') - .addEventListener('tap', this.onBackButtonClicked_.bind(this)); - $('offline-gaia') - .addEventListener('offline-gaia-cancel', this.cancel.bind(this)); - - $('gaia-whitelist-error').addEventListener('buttonclick', function() { - this.showWhitelistCheckFailedError(false); - }.bind(this)); - - $('gaia-whitelist-error').addEventListener('linkclick', function() { - chrome.send('launchHelpApp', [HELP_CANT_ACCESS_ACCOUNT]); - }); - - // Register handlers for the saml interstitial page events. - $('saml-interstitial') - .addEventListener('samlPageNextClicked', function() { - this.screenMode = ScreenMode.DEFAULT; - this.loadAuthenticator_(true /* doSamlRedirect */); - }.bind(this)); - $('saml-interstitial') - .addEventListener('samlPageChangeAccountClicked', function() { - // The user requests to change the account. We must clear the email - // field of the auth params. - this.authenticatorParams_.email = ''; - this.screenMode = ScreenMode.DEFAULT; - this.loadAuthenticator_(false /* doSamlRedirect */); - }.bind(this)); - - $('offline-ad-auth').addEventListener('cancel', function() { - this.cancel(); - }.bind(this)); - }, - - /** - * Handles clicks on "Back" button. - */ - onBackButtonClicked_: function() { - if (!this.canGoBack_()) { - this.cancel(); - } else { - this.getSigninFrame_().back(); - } - }, - - /** - * Loads the authenticator and updates the UI to reflect the loading state. - * @param {boolean} doSamlRedirect If the authenticator should do - * authentication by automatic redirection to the SAML-based enrollment - * enterprise domain IdP. - */ - loadAuthenticator_: function(doSamlRedirect) { - this.loading = true; - this.startLoadingTimer_(); - - this.authenticatorParams_.doSamlRedirect = doSamlRedirect; - this.authenticator_.load( - cr.login.Authenticator.AuthMode.DEFAULT, this.authenticatorParams_); - }, - - /** - * Returns true if offline version of Gaia is used. - * @type {boolean} - */ - isOffline: function() { - return this.screenMode_ == ScreenMode.OFFLINE; - }, - - /** - * Sets the current screen mode and updates the visible elements - * accordingly. - * @param {integer} value The screen mode. - */ - set screenMode(value) { - this.screenMode_ = value; - switch (this.screenMode_) { - case ScreenMode.DEFAULT: - $('signin-frame-dialog').hidden = false; - $('signin-frame').hidden = false; - $('offline-gaia').hidden = true; - $('saml-interstitial').hidden = true; - $('offline-ad-auth').hidden = true; - break; - case ScreenMode.OFFLINE: - $('signin-frame-dialog').hidden = true; - $('signin-frame').hidden = true; - $('offline-gaia').hidden = false; - $('saml-interstitial').hidden = true; - $('offline-ad-auth').hidden = true; - break; - case ScreenMode.AD_AUTH: - $('signin-frame-dialog').hidden = true; - $('signin-frame').hidden = true; - $('offline-gaia').hidden = true; - $('saml-interstitial').hidden = true; - $('offline-ad-auth').hidden = false; - break; - case ScreenMode.SAML_INTERSTITIAL: - $('signin-frame-dialog').hidden = true; - $('signin-frame').hidden = true; - $('offline-gaia').hidden = true; - $('saml-interstitial').hidden = false; - $('offline-ad-auth').hidden = true; - break; - } - this.updateSigninFrameContainers_(); - chrome.send('updateOfflineLogin', [this.isOffline()]); - this.updateControlsState(); - }, - - /** - * This enables or disables trying to go back to the online login page - * after the user is idle for a few minutes, assuming that we're currently - * in the offline one. This is only applicable when the offline page is - * currently active. It is intended that when the device goes online, this - * gets called with true; when it goes offline, this gets called with - * false. - */ - monitorOfflineIdle: function(shouldMonitor) { - var ACTIVITY_EVENTS = ['click', 'mousemove', 'keypress']; - var self = this; - - // updateActivityTime_ is used as a callback for addEventListener, so we - // need the exact reference for removeEventListener. Because the callback - // needs to access the |this| as scoped inside of this function, we create - // a closure that uses the appropriate |this|. - // - // Unfourtantely, we cannot define this function inside of the JSON object - // as then we have to no way to create to capture the correct |this| - // reference. We define it here instead. - if (!self.updateActivityTime_) { - self.updateActivityTime_ = function() { - self.mostRecentUserActivity_ = Date.now(); - }; - } - - // Begin monitoring. - if (shouldMonitor) { - // If we're not using the offline login page or we're already - // monitoring, then we don't need to do anything. - if (!self.isOffline() || - self.tryToGoToOnlineLoginPageCallbackId_ !== -1) { - return; - } - - self.mostRecentUserActivity_ = Date.now(); - ACTIVITY_EVENTS.forEach(function(event) { - document.addEventListener(event, self.updateActivityTime_); + frame.addEventListener( + 'authCompleted', frameFilter(that.onAuthCompletedMessage_)); + frame.addEventListener('backButton', frameFilter(that.onBackButton_)); + frame.addEventListener( + 'dialogShown', frameFilter(that.onDialogShown_)); + frame.addEventListener( + 'dialogHidden', frameFilter(that.onDialogHidden_)); + frame.addEventListener( + 'menuItemClicked', frameFilter(that.onMenuItemClicked_)); }); - self.tryToGoToOnlineLoginPageCallbackId_ = setInterval(function() { - // If we're not in the offline page or the signin page, then we want - // to terminate monitoring. - if (!self.isOffline() || - Oobe.getInstance().currentScreen.id != 'gaia-signin') { - self.monitorOfflineIdle(false); - return; - } + this.authenticator_.addEventListener( + 'showView', this.onShowView_.bind(this)); + this.authenticator_.confirmPasswordCallback = + this.onAuthConfirmPassword_.bind(this); + this.authenticator_.noPasswordCallback = this.onAuthNoPassword_.bind(this); + this.authenticator_.insecureContentBlockedCallback = + this.onInsecureContentBlocked_.bind(this); + this.authenticator_.missingGaiaInfoCallback = + this.missingGaiaInfo_.bind(this); + this.authenticator_.samlApiUsedCallback = this.samlApiUsed_.bind(this); + this.authenticator_.getIsSamlUserPasswordlessCallback = + this.getIsSamlUserPasswordless_.bind(this); + this.authenticator_.addEventListener( + 'authDomainChange', this.onAuthDomainChange_.bind(this)); + this.authenticator_.addEventListener( + 'authFlowChange', this.onAuthFlowChange_.bind(this)); + this.authenticator_.addEventListener( + 'videoEnabledChange', this.onVideoEnabledChange_.bind(this)); - var idleDuration = Date.now() - self.mostRecentUserActivity_; - if (idleDuration > IDLE_TIME_UNTIL_EXIT_OFFLINE_IN_MILLISECONDS) { - self.monitorOfflineIdle(false); - Oobe.resetSigninUI(true); - } - }, IDLE_TIME_CHECK_FREQUENCY); - } + this.authenticator_.addEventListener( + 'loadAbort', this.onLoadAbortMessage_.bind(this)); + this.authenticator_.addEventListener( + 'identifierEntered', this.onIdentifierEnteredMessage_.bind(this)); - // Stop monitoring. - else { - // We're not monitoring, so we don't need to do anything. - if (self.tryToGoToOnlineLoginPageCallbackId_ === -1) - return; + this.$['signin-back-button'].addEventListener( + 'tap', this.onBackButtonClicked_.bind(this)); + this.$['offline-gaia'].addEventListener( + 'offline-gaia-cancel', this.cancel.bind(this)); - ACTIVITY_EVENTS.forEach(function(event) { - document.removeEventListener(event, self.updateActivityTime_); - }); - clearInterval(self.tryToGoToOnlineLoginPageCallbackId_); - self.tryToGoToOnlineLoginPageCallbackId_ = -1; - } - }, + this.$['gaia-whitelist-error'].addEventListener('buttonclick', function() { + this.showWhitelistCheckFailedError(false); + }.bind(this)); - /** - * Shows/hides loading UI. - * @param {boolean} show True to show loading UI. - * @private - */ - showLoadingUI_: function(show) { - $('gaia-loading').hidden = !show; + this.$['gaia-whitelist-error'].addEventListener('linkclick', function() { + chrome.send('launchHelpApp', [HELP_CANT_ACCESS_ACCOUNT]); + }); - // Only set hidden for offline-gaia or saml-interstitial and not set it on - // the 'sign-frame' webview element. Setting it on webview not only hides - // but also affects its loading events. - if (this.screenMode_ != ScreenMode.DEFAULT) - this.getSigninFrame_().hidden = show; - this.getSigninFrame_().classList.toggle('show', !show); - this.classList.toggle('loading', show); - this.updateControlsState(); - }, - - /** - * Handler for Gaia loading timeout. - * @private - */ - onLoadingTimeOut_: function() { - if (this != Oobe.getInstance().currentScreen) - return; - this.loadingTimer_ = undefined; - chrome.send('showLoadingTimeoutError'); - }, - - /** - * Clears loading timer. - * @private - */ - clearLoadingTimer_: function() { - if (this.loadingTimer_) { - clearTimeout(this.loadingTimer_); - this.loadingTimer_ = undefined; - } - }, - - /** - * Sets up loading timer. - * @private - */ - startLoadingTimer_: function() { - this.clearLoadingTimer_(); - this.loadingTimer_ = setTimeout( - this.onLoadingTimeOut_.bind(this), MAX_GAIA_LOADING_TIME_SEC * 1000); - }, - - /** - * Handler for GAIA animation guard timer. - * @private - */ - onLoadAnimationGuardTimer_: function() { - this.loadAnimationGuardTimer_ = undefined; - this.onShowView_(); - }, - - /** - * Clears GAIA animation guard timer. - * @private - */ - clearLoadAnimationGuardTimer_: function() { - if (this.loadAnimationGuardTimer_) { - clearTimeout(this.loadAnimationGuardTimer_); - this.loadAnimationGuardTimer_ = undefined; - } - }, - - /** - * Sets up GAIA animation guard timer. - * @private - */ - startLoadAnimationGuardTimer_: function() { - this.clearLoadAnimationGuardTimer_(); - this.loadAnimationGuardTimer_ = setTimeout( - this.onLoadAnimationGuardTimer_.bind(this), - GAIA_ANIMATION_GUARD_MILLISEC); - }, - - /** - * Whether Gaia is loading. - * @type {boolean} - */ - get loading() { - return !$('gaia-loading').hidden; - }, - set loading(loading) { - if (loading == this.loading) - return; - - this.showLoadingUI_(loading); - }, - - /** - * Event handler that is invoked just before the frame is shown. - * @param {string} data Screen init payload. Url of auth extension start - * page. - */ - onBeforeShow: function(data) { - this.screenMode = ScreenMode.DEFAULT; - this.loading = true; - chrome.send('loginUIStateChanged', ['gaia-signin', true]); - Oobe.getInstance().setSigninUIState(SIGNIN_UI_STATE.GAIA_SIGNIN); - - // Ensure that GAIA signin (or loading UI) is actually visible. - window.requestAnimationFrame(function() { - chrome.send('loginVisible', ['gaia-loading']); - }); - - // Re-enable navigation in case it was disabled before refresh. - this.navigationDisabled_ = false; - - this.lastBackMessageValue_ = false; - this.updateControlsState(); - - $('offline-ad-auth').onBeforeShow(); - return $('signin-frame-dialog').onBeforeShow(); - }, - - set navigationDisabled_(value) { - $('gaia-screen-buttons-overlay').hidden = !value; - $('signin-back-button').disabled = value; - }, - - getSigninFrame_: function() { - switch (this.screenMode_) { - case ScreenMode.DEFAULT: - return $('signin-frame'); - case ScreenMode.OFFLINE: - return $('offline-gaia'); - case ScreenMode.AD_AUTH: - return $('offline-ad-auth'); - case ScreenMode.SAML_INTERSTITIAL: - return $('saml-interstitial'); - } - }, - - focusSigninFrame: function() { - this.getSigninFrame_().focus(); - }, - - onAfterShow: function() { - if (!this.loading) - this.focusSigninFrame(); - }, - - /** - * Event handler that is invoked just before the screen is hidden. - */ - onBeforeHide: function() { - chrome.send('loginUIStateChanged', ['gaia-signin', false]); - Oobe.getInstance().setSigninUIState(SIGNIN_UI_STATE.HIDDEN); - $('offline-gaia').switchToEmailCard(false /* animated */); - }, - - /** - * Copies attributes between nodes. - * @param {!Object} fromNode source to copy attributes from - * @param {!Object} toNode target to copy attributes to - * @param {!Set<string>} skipAttributes specifies attributes to be skipped - * @private - */ - copyAttributes_: function(fromNode, toNode, skipAttributes) { - for (var i = 0; i < fromNode.attributes.length; ++i) { - var attribute = fromNode.attributes[i]; - if (!skipAttributes.has(attribute.nodeName)) - toNode.setAttribute(attribute.nodeName, attribute.nodeValue); - } - }, - - /** - * Changes the 'partition' attribute of the sign-in frame. If the sign-in - * frame has already navigated, this function re-creates it. - * @param {string} newWebviewPartitionName the new partition - * @private - */ - setSigninFramePartition_: function(newWebviewPartitionName) { - var signinFrame = $('signin-frame'); - - if (!signinFrame.src) { - // We have not navigated anywhere yet. Note that a webview's src - // attribute does not allow a change back to "". - signinFrame.partition = newWebviewPartitionName; - } else if (signinFrame.partition != newWebviewPartitionName) { - // The webview has already navigated. We have to re-create it. - var signinFrameParent = signinFrame.parentElement; - - // Copy all attributes except for partition and src from the previous - // webview. Use the specified |newWebviewPartitionName|. - var newSigninFrame = document.createElement('webview'); - this.copyAttributes_( - signinFrame, newSigninFrame, new Set(['src', 'partition'])); - newSigninFrame.partition = newWebviewPartitionName; - - signinFrameParent.replaceChild(newSigninFrame, signinFrame); - - // Make sure the authenticator uses the new webview from now on. - this.authenticator_.rebindWebview($('signin-frame')); - } - }, - - /** - * Loads the authentication extension into the iframe. - * @param {Object} data Extension parameters bag. - * @private - */ - loadAuthExtension: function(data) { - // Redirect the webview to the blank page in order to stop the SAML IdP - // page from working in a background (see crbug.com/613245). - if (this.screenMode_ == ScreenMode.DEFAULT && - data.screenMode != ScreenMode.DEFAULT) { - this.authenticator_.resetWebview(); - } - - this.setSigninFramePartition_(data.webviewPartitionName); - - // This triggers updateSigninFrameContainers_() - this.screenMode = data.screenMode; - this.email = ''; - this.authCompleted_ = false; - this.lastBackMessageValue_ = false; - - // Reset SAML - $('saml-notice-container').hidden = true; - this.samlPasswordConfirmAttempt_ = 0; - - this.updateSigninFrameContainers_(); - - var params = {}; - for (var i in cr.login.Authenticator.SUPPORTED_PARAMS) { - var name = cr.login.Authenticator.SUPPORTED_PARAMS[i]; - if (data[name]) - params[name] = data[name]; - } - - params.doSamlRedirect = - (this.screenMode_ == ScreenMode.SAML_INTERSTITIAL); - params.menuGuestMode = data.guestSignin; - params.menuKeyboardOptions = false; - params.menuEnterpriseEnrollment = - !(data.enterpriseManagedDevice || data.hasDeviceOwner); - params.isFirstUser = - !(data.enterpriseManagedDevice || data.hasDeviceOwner); - params.obfuscatedOwnerId = data.obfuscatedOwnerId; - - this.authenticatorParams_ = params; - - switch (this.screenMode_) { - case ScreenMode.DEFAULT: + // Register handlers for the saml interstitial page events. + this.$['saml-interstitial'].addEventListener( + 'samlPageNextClicked', function() { + this.screenMode = ScreenMode.DEFAULT; + this.loadAuthenticator_(true /* doSamlRedirect */); + }.bind(this)); + this.$['saml-interstitial'].addEventListener( + 'samlPageChangeAccountClicked', function() { + // The user requests to change the account. We must clear the email + // field of the auth params. + this.authenticatorParams_.email = ''; + this.screenMode = ScreenMode.DEFAULT; this.loadAuthenticator_(false /* doSamlRedirect */); - break; + }.bind(this)); - case ScreenMode.OFFLINE: - this.loadOffline(params); - break; + this.$['offline-ad-auth'].addEventListener('cancel', function() { + this.cancel(); + }.bind(this)); - case ScreenMode.AD_AUTH: - this.loadAdAuth(params); - break; + this.initializeLoginScreen('GaiaSigninScreen', { + resetAllowed: true, + }); + }, - case ScreenMode.SAML_INTERSTITIAL: - $('saml-interstitial').domain = data.enterpriseDisplayDomain; - if (this.loading) - this.loading = false; - // This event is for the browser tests. - this.samlInterstitialPageReady = true; - $('saml-interstitial').fire('samlInterstitialPageReady'); - break; - } - this.updateControlsState(); - chrome.send('authExtensionLoaded'); - }, + /** + * Whether the dialog could be closed. + * This is being checked in cancel() when user clicks on signin-back-button + * (normal gaia flow) or the "Back" button in other authentication frames. + * @type {boolean} + */ + get closable() { + return Oobe.getInstance().hasUserPods || this.isOffline(); + }, - /** - * Displays correct screen container for given mode and APi version. - */ - updateSigninFrameContainers_: function() { - let oldState = this.classList.contains('v2'); - this.classList.toggle('v2', false); - if (this.screenMode_ == ScreenMode.DEFAULT || - this.screenMode_ == ScreenMode.OFFLINE || - this.screenMode_ == ScreenMode.AD_AUTH) { - this.classList.toggle('v2', true); - } - if (this != Oobe.getInstance().currentScreen) - return; - // Switching between signin-frame-dialog and gaia-step-contents - // updates screen size. - if (oldState != this.classList.contains('v2')) - Oobe.getInstance().updateScreenSize(this); - }, + /** + * Returns true if the screen is at the beginning of flow (i.e. the email + * page). + * @type {boolean} + */ + isAtTheBeginning: function() { + return !this.canGoBack_() && !this.isSAML() && + !this.classList.contains('whitelist-error') && !this.authCompleted_; + }, - /** - * Whether the current auth flow is SAML. - */ - isSAML: function() { - return this.authenticator_.authFlow == - cr.login.Authenticator.AuthFlow.SAML; - }, + /** + * Updates visibility of UI control buttons. + */ + updateControlsState: function() { + let showGuestInOobe = !this.closable && this.isAtTheBeginning(); + chrome.send('showGuestInOobe', [showGuestInOobe]); + }, - /** - * Helper function to update the title bar. - */ - updateSamlNotice_: function() { - if (this.authenticator_.videoEnabled) { - $('saml-notice-message').textContent = loadTimeData.getStringF( - 'samlNoticeWithVideo', this.authenticator_.authDomain); - $('saml-notice-recording-indicator').hidden = false; - $('saml-notice-container').style.justifyContent = 'flex-start'; - } else { - $('saml-notice-message').textContent = loadTimeData.getStringF( - 'samlNotice', this.authenticator_.authDomain); - $('saml-notice-recording-indicator').hidden = true; - $('saml-notice-container').style.justifyContent = 'center'; - } - }, + /** + * Returns whether it's possible to rewind the sign-in frame one step back (as + * opposed to cancelling the sign-in flow). + * @type {boolean} + * @private + */ + canGoBack_: function() { + var isWhitelistError = this.classList.contains('whitelist-error'); + return this.lastBackMessageValue_ && !isWhitelistError && + !this.authCompleted_ && !this.loading && !this.isSAML(); + }, - /** - * Clean up from a video-enabled SAML flow. - */ - clearVideoTimer_: function() { - if (this.videoTimer_ !== undefined) { - clearTimeout(this.videoTimer_); - this.videoTimer_ = undefined; - } - }, - - /** - * Invoked when the authDomain property is changed on the authenticator. - */ - onAuthDomainChange_: function() { - this.updateSamlNotice_(); - }, - - /** - * Invoked when the videoEnabled property is changed on the authenticator. - */ - onVideoEnabledChange_: function() { - this.updateSamlNotice_(); - if (this.authenticator_.videoEnabled && this.videoTimer_ === undefined) { - this.videoTimer_ = - setTimeout(this.cancel.bind(this), VIDEO_LOGIN_TIMEOUT); - } else { - this.clearVideoTimer_(); - } - }, - - /** - * Invoked when the authFlow property is changed on the authenticator. - */ - onAuthFlowChange_: function() { - var isSAML = this.isSAML(); - - $('saml-notice-container').hidden = !isSAML; - this.classList.toggle('saml', isSAML); - - if (Oobe.getInstance().currentScreen === this) { - Oobe.getInstance().updateScreenSize(this); - } - - this.updateControlsState(); - }, - - /** - * Invoked when the authenticator emits 'ready' event or when another - * authentication frame is completely loaded. - * @private - */ - onAuthReady_: function() { - this.showViewProcessed_ = false; - this.startLoadAnimationGuardTimer_(); - this.clearLoadingTimer_(); - this.loading = false; - - if (!$('offline-gaia').hidden) - $('offline-gaia').focus(); - }, - - /** - * Invoked when a frame emits 'dialogShown' event. - * @private - */ - onDialogShown_: function() { - this.navigationDisabled_ = true; - }, - - /** - * Invoked when a frame emits 'dialogHidden' event. - * @private - */ - onDialogHidden_: function() { - this.navigationDisabled_ = false; - }, - - /** - * Invoked when user activates menu item. - * @private - */ - onMenuItemClicked_: function(e) { - if (e.detail == 'gm') { - Oobe.disableSigninUI(); - chrome.send('launchIncognito'); - } else if (e.detail == 'ee') { - cr.ui.Oobe.handleAccelerator(ACCELERATOR_ENROLLMENT); - } - }, - - /** - * Invoked when the authenticator requests whether the specified user is a - * user without a password (neither a manually entered one nor one provided - * via Credentials Passing API). - * @param {string} email - * @param {string} gaiaId - * @param {function(boolean)} callback - * @private - */ - getIsSamlUserPasswordless_: function(email, gaiaId, callback) { - cr.sendWithPromise('getIsSamlUserPasswordless', email, gaiaId) - .then(callback); - }, - - /** - * Invoked when a frame emits 'backButton' event. - * @private - */ - onBackButton_: function(e) { - this.getSigninFrame_().focus(); - this.lastBackMessageValue_ = !!e.detail; - this.updateControlsState(); - }, - - /** - * Invoked when the authenticator emits 'showView' event or when - * corresponding guard time fires. - * @private - */ - onShowView_: function(e) { - if (this.showViewProcessed_) - return; - - this.showViewProcessed_ = true; - this.clearLoadAnimationGuardTimer_(); - this.getSigninFrame_().classList.toggle('show', true); - this.onLoginUIVisible_(); - }, - - /** - * Called when UI is shown. - * @private - */ - onLoginUIVisible_: function() { - // Show deferred error bubble. - if (this.errorBubble_) { - this.showErrorBubble(this.errorBubble_[0], this.errorBubble_[1]); - this.errorBubble_ = undefined; - } - - chrome.send('loginWebuiReady'); - chrome.send('loginVisible', ['gaia-signin']); - }, - - /** - * Invoked when the user has successfully authenticated via SAML, the - * principals API was not used and the authenticator needs the user to - * confirm the scraped password. - * @param {string} email The authenticated user's e-mail. - * @param {number} passwordCount The number of passwords that were scraped. - * @private - */ - onAuthConfirmPassword_: function(email, passwordCount) { - this.loading = true; - - if (this.samlPasswordConfirmAttempt_ == 0) - chrome.send('scrapedPasswordCount', [passwordCount]); - - if (this.samlPasswordConfirmAttempt_ < 2) { - login.ConfirmPasswordScreen.show( - email, false /* manual password entry */, - this.samlPasswordConfirmAttempt_, - this.onConfirmPasswordCollected_.bind(this)); - } else { - chrome.send('scrapedPasswordVerificationFailed'); - this.showFatalAuthError( - loadTimeData.getString('fatalErrorMessageVerificationFailed'), - loadTimeData.getString('fatalErrorTryAgainButton')); - } - }, - - /** - * Invoked when the confirm password screen is dismissed. - * @private - */ - onConfirmPasswordCollected_: function(password) { - this.samlPasswordConfirmAttempt_++; - this.authenticator_.verifyConfirmedPassword(password); - - // Shows signin UI again without changing states. - Oobe.showScreen({id: SCREEN_GAIA_SIGNIN}); - }, - - /** - * Inovked when the user has successfully authenticated via SAML, the - * principals API was not used and no passwords could be scraped. - * The user will be asked to pick a manual password for the device. - * @param {string} email The authenticated user's e-mail. - */ - onAuthNoPassword_: function(email) { - chrome.send('scrapedPasswordCount', [0]); - login.ConfirmPasswordScreen.show( - email, true /* manual password entry */, - this.samlPasswordConfirmAttempt_, - this.onManualPasswordCollected_.bind(this)); - }, - - /** - * Invoked when the dialog where the user enters a manual password for the - * device, when password scraping fails. - * @param {string} password The password the user entered. Not necessarily - * the same as their SAML password. - */ - onManualPasswordCollected_: function(password) { - this.authenticator_.completeAuthWithManualPassword(password); - }, - - /** - * Invoked when the authentication flow had to be aborted because content - * served over an unencrypted connection was detected. Shows a fatal error. - * This method is only called on Chrome OS, where the entire authentication - * flow is required to be encrypted. - * @param {string} url The URL that was blocked. - */ - onInsecureContentBlocked_: function(url) { - this.showFatalAuthError( - loadTimeData.getStringF('fatalErrorMessageInsecureURL', url), - loadTimeData.getString('fatalErrorDoneButton')); - }, - - /** - * Shows the fatal auth error. - * @param {string} message The error message to show. - * @param {string} buttonLabel The label to display on dismiss button. - */ - showFatalAuthError: function(message, buttonLabel) { - login.FatalErrorScreen.show(message, buttonLabel, Oobe.showSigninUI); - }, - - /** - * Show fatal auth error when information is missing from GAIA. - */ - missingGaiaInfo_: function() { - this.showFatalAuthError( - loadTimeData.getString('fatalErrorMessageNoAccountDetails'), - loadTimeData.getString('fatalErrorTryAgainButton')); - }, - - /** - * Record that SAML API was used during sign-in. - */ - samlApiUsed_: function() { - chrome.send('usingSAMLAPI'); - }, - - /** - * Invoked when auth is completed successfully. - * @param {!Object} credentials Credentials of the completed authentication. - * @private - */ - onAuthCompleted_: function(credentials) { - if (this.screenMode_ == ScreenMode.AD_AUTH) { - this.email = credentials.username; - chrome.send( - 'completeAdAuthentication', - [credentials.username, credentials.password]); - } else if (credentials.useOffline) { - this.email = credentials.email; - chrome.send( - 'completeOfflineAuthentication', - [credentials.email, credentials.password]); - } else { - chrome.send('completeAuthentication', [ - credentials.gaiaId, credentials.email, credentials.password, - credentials.usingSAML, credentials.services, - credentials.passwordAttributes - ]); - } - - this.loading = true; - // Hide the back button and the border line as they are not useful - // when the loading screen is shown. - $('signin-back-button').hidden = true; - $('signin-frame-dialog').setAttribute('hide-shadow', true); - - // Clear any error messages that were shown before login. - Oobe.clearErrors(); - - this.clearVideoTimer_(); - this.authCompleted_ = true; - this.updateControlsState(); - }, - - /** - * Invoked when onAuthCompleted message received. - * @param {!Object} e Payload of the received HTML5 message. - * @private - */ - onAuthCompletedMessage_: function(e) { - this.onAuthCompleted_(e.detail); - }, - - /** - * Invoked when onLoadAbort message received. - * @param {!Object} e Payload of the received HTML5 message. - * @private - */ - onLoadAbortMessage_: function(e) { - this.onWebviewError(e.detail); - }, - - /** - * Invoked when identifierEntered message received. - * @param {!Object} e Payload of the received HTML5 message. - * @private - */ - onIdentifierEnteredMessage_: function(e) { - this.onIdentifierEntered(e.detail); - }, - - /** - * Clears input fields and switches to input mode. - * @param {boolean} takeFocus True to take focus. - * @param {boolean} forceOnline Whether online sign-in should be forced. - * If |forceOnline| is false previously used sign-in type will be used. - */ - reset: function(takeFocus, forceOnline) { - // Reload and show the sign-in UI if needed. - this.authenticator_.resetStates(); - if (takeFocus) { - if (!forceOnline && this.isOffline()) { - Oobe.getInstance().setSigninUIState(SIGNIN_UI_STATE.GAIA_SIGNIN); - // Do nothing, since offline version is reloaded after an error comes. - } else { - Oobe.showSigninUI(); - } - } - }, - - /** - * Reloads extension frame. - */ - doReload: function() { - if (this.screenMode_ != ScreenMode.DEFAULT) - return; - this.authenticator_.reload(); - this.loading = true; - this.startLoadingTimer_(); - this.lastBackMessageValue_ = false; - this.authCompleted_ = false; - this.updateControlsState(); - }, - - /** - * Shows sign-in error bubble. - * @param {number} loginAttempts Number of login attemps tried. - * @param {HTMLElement} content Content to show in bubble. - */ - showErrorBubble: function(loginAttempts, error) { - if (this.isOffline()) { - // Reload offline version of the sign-in extension, which will show - // error itself. - chrome.send('offlineLogin', [this.email]); - } else if (!this.loading) { - // TODO(dzhioev): investigate if this branch ever get hit. - $('bubble').showContentForElement( - $('gaia-signin-form-container'), cr.ui.Bubble.Attachment.BOTTOM, - error, BUBBLE_HORIZONTAL_PADDING, BUBBLE_VERTICAL_PADDING); - } else { - // Defer the bubble until the frame has been loaded. - this.errorBubble_ = [loginAttempts, error]; - } - }, - - /** - * Called when user canceled signin. - */ - cancel: function() { - this.clearVideoTimer_(); - - const isWhitelistError = this.classList.contains('whitelist-error'); - // TODO(crbug.com/470893): Figure out whether/which of these exit - // conditions are useful. - if (this.screenMode_ == ScreenMode.SAML_INTERSTITIAL || - isWhitelistError || this.authCompleted_) { - return; - } - - if (this.screenMode_ == ScreenMode.AD_AUTH) - chrome.send('cancelAdAuthentication'); - - if (this.closable) - Oobe.showUserPods(); - else - Oobe.resetSigninUI(true); - }, - - /** - * Handler for webview error handling. - * @param {!Object} data Additional information about error event like: - * {string} error Error code such as "ERR_INTERNET_DISCONNECTED". - * {string} url The URL that failed to load. - */ - onWebviewError: function(data) { - chrome.send('webviewLoadAborted', [data.error]); - }, - - /** - * Handler for identifierEntered event. - * @param {!Object} data The identifier entered by user: - * {string} accountIdentifier User identifier. - */ - onIdentifierEntered: function(data) { - chrome.send('identifierEntered', [data.accountIdentifier]); - }, - - /** - * Sets enterprise info strings for offline gaia. - * Also sets callback and sends message whether we already have email and - * should switch to the password screen with error. - */ - loadOffline: function(params) { - this.loading = true; - this.startLoadingTimer_(); - var offlineLogin = $('offline-gaia'); - if ('enterpriseDisplayDomain' in params) - offlineLogin.domain = params['enterpriseDisplayDomain']; - if ('emailDomain' in params) - offlineLogin.emailDomain = '@' + params['emailDomain']; - offlineLogin.setEmail(params.email); - this.onAuthReady_(); - }, - - loadAdAuth: function(params) { - this.loading = true; - this.startLoadingTimer_(); - var adAuthUI = this.getSigninFrame_(); - adAuthUI.realm = params['realm']; - - if ('emailDomain' in params) - adAuthUI.userRealm = '@' + params['emailDomain']; - - adAuthUI.userName = params['email']; - adAuthUI.focus(); - this.onAuthReady_(); - }, - - /** - * Show/Hide error when user is not in whitelist. When UI is hidden - * GAIA is reloaded. - * @param {boolean} show Show/hide error UI. - * @param {!Object} opt_data Optional additional information. - */ - showWhitelistCheckFailedError: function(show, opt_data) { - if (show) { - var isManaged = opt_data && opt_data.enterpriseManaged; - $('gaia-whitelist-error').textContent = loadTimeData.getValue( - isManaged ? 'whitelistErrorEnterprise' : 'whitelistErrorConsumer'); - // To make animations correct, we need to make sure Gaia is completely - // reloaded. Otherwise ChromeOS overlays hide and Gaia page is shown - // somewhere in the middle of animations. - if (this.screenMode_ == ScreenMode.DEFAULT) - this.authenticator_.resetWebview(); - } - - this.classList.toggle('whitelist-error', show); - this.loading = !show; - - if (show) - $('gaia-whitelist-error').submitButton.focus(); - else - Oobe.showSigninUI(); - - this.updateControlsState(); - }, - - invalidateAd: function(username, errorState) { - if (this.screenMode_ != ScreenMode.AD_AUTH) - return; - var adAuthUI = this.getSigninFrame_(); - adAuthUI.userName = username; - adAuthUI.errorState = errorState; - this.authCompleted_ = false; - this.loading = false; + /** + * Handles clicks on "Back" button. + */ + onBackButtonClicked_: function() { + if (!this.canGoBack_()) { + this.cancel(); + } else { + this.getActiveFrame_().back(); } - }; + }, + + /** + * Loads the authenticator and updates the UI to reflect the loading state. + * @param {boolean} doSamlRedirect If the authenticator should do + * authentication by automatic redirection to the SAML-based enrollment + * enterprise domain IdP. + */ + loadAuthenticator_: function(doSamlRedirect) { + this.loading = true; + this.startLoadingTimer_(); + + this.authenticatorParams_.doSamlRedirect = doSamlRedirect; + this.authenticator_.load( + cr.login.Authenticator.AuthMode.DEFAULT, this.authenticatorParams_); + }, + + /** + * Returns true if offline version of Gaia is used. + * @type {boolean} + */ + isOffline: function() { + return this.screenMode_ == ScreenMode.OFFLINE; + }, + + /** + * Sets the current screen mode and updates the visible elements + * accordingly. + * @param {integer} value The screen mode. + */ + set screenMode(value) { + this.screenMode_ = value; + switch (this.screenMode_) { + case ScreenMode.DEFAULT: + this.$['signin-frame-dialog'].hidden = false; + this.getSigninFrame_().hidden = false; + this.$['offline-gaia'].hidden = true; + this.$['saml-interstitial'].hidden = true; + this.$['offline-ad-auth'].hidden = true; + break; + case ScreenMode.OFFLINE: + this.$['signin-frame-dialog'].hidden = true; + this.getSigninFrame_().hidden = true; + this.$['offline-gaia'].hidden = false; + this.$['saml-interstitial'].hidden = true; + this.$['offline-ad-auth'].hidden = true; + break; + case ScreenMode.AD_AUTH: + this.$['signin-frame-dialog'].hidden = true; + this.getSigninFrame_().hidden = true; + this.$['offline-gaia'].hidden = true; + this.$['saml-interstitial'].hidden = true; + this.$['offline-ad-auth'].hidden = false; + break; + case ScreenMode.SAML_INTERSTITIAL: + this.$['signin-frame-dialog'].hidden = true; + this.getSigninFrame_().hidden = true; + this.$['offline-gaia'].hidden = true; + this.$['saml-interstitial'].hidden = false; + this.$['offline-ad-auth'].hidden = true; + break; + } + this.updateSigninFrameContainers_(); + chrome.send('updateOfflineLogin', [this.isOffline()]); + this.updateControlsState(); + }, + + /** + * This enables or disables trying to go back to the online login page + * after the user is idle for a few minutes, assuming that we're currently + * in the offline one. This is only applicable when the offline page is + * currently active. It is intended that when the device goes online, this + * gets called with true; when it goes offline, this gets called with + * false. + */ + monitorOfflineIdle: function(shouldMonitor) { + var ACTIVITY_EVENTS = ['click', 'mousemove', 'keypress']; + var self = this; + + // updateActivityTime_ is used as a callback for addEventListener, so we + // need the exact reference for removeEventListener. Because the callback + // needs to access the |this| as scoped inside of this function, we create + // a closure that uses the appropriate |this|. + // + // Unfourtantely, we cannot define this function inside of the JSON object + // as then we have to no way to create to capture the correct |this| + // reference. We define it here instead. + if (!self.updateActivityTime_) { + self.updateActivityTime_ = function() { + self.mostRecentUserActivity_ = Date.now(); + }; + } + + // Begin monitoring. + if (shouldMonitor) { + // If we're not using the offline login page or we're already + // monitoring, then we don't need to do anything. + if (!self.isOffline() || + self.tryToGoToOnlineLoginPageCallbackId_ !== -1) { + return; + } + + self.mostRecentUserActivity_ = Date.now(); + ACTIVITY_EVENTS.forEach(function(event) { + document.addEventListener(event, self.updateActivityTime_); + }); + + self.tryToGoToOnlineLoginPageCallbackId_ = setInterval(function() { + // If we're not in the offline page or the signin page, then we want + // to terminate monitoring. + if (!self.isOffline() || + Oobe.getInstance().currentScreen.id != 'gaia-signin') { + self.monitorOfflineIdle(false); + return; + } + + var idleDuration = Date.now() - self.mostRecentUserActivity_; + if (idleDuration > IDLE_TIME_UNTIL_EXIT_OFFLINE_IN_MILLISECONDS) { + self.monitorOfflineIdle(false); + Oobe.resetSigninUI(true); + } + }, IDLE_TIME_CHECK_FREQUENCY); + } + + // Stop monitoring. + else { + // We're not monitoring, so we don't need to do anything. + if (self.tryToGoToOnlineLoginPageCallbackId_ === -1) + return; + + ACTIVITY_EVENTS.forEach(function(event) { + document.removeEventListener(event, self.updateActivityTime_); + }); + clearInterval(self.tryToGoToOnlineLoginPageCallbackId_); + self.tryToGoToOnlineLoginPageCallbackId_ = -1; + } + }, + + /** + * Shows/hides loading UI. + * @param {boolean} show True to show loading UI. + * @private + */ + showLoadingUI_: function(show) { + this.$['gaia-loading'].hidden = !show; + + // Only set hidden for offline-gaia or saml-interstitial and not set it on + // the 'sign-frame' webview element. Setting it on webview not only hides + // but also affects its loading events. + if (this.screenMode_ != ScreenMode.DEFAULT) + this.getActiveFrame_().hidden = show; + this.getActiveFrame_().classList.toggle('show', !show); + this.classList.toggle('loading', show); + this.updateControlsState(); + }, + + /** + * Handler for Gaia loading timeout. + * @private + */ + onLoadingTimeOut_: function() { + if (Oobe.getInstance().currentScreen.id != 'gaia-signin') + return; + this.loadingTimer_ = undefined; + chrome.send('showLoadingTimeoutError'); + }, + + /** + * Clears loading timer. + * @private + */ + clearLoadingTimer_: function() { + if (this.loadingTimer_) { + clearTimeout(this.loadingTimer_); + this.loadingTimer_ = undefined; + } + }, + + /** + * Sets up loading timer. + * @private + */ + startLoadingTimer_: function() { + this.clearLoadingTimer_(); + this.loadingTimer_ = setTimeout( + this.onLoadingTimeOut_.bind(this), MAX_GAIA_LOADING_TIME_SEC * 1000); + }, + + /** + * Handler for GAIA animation guard timer. + * @private + */ + onLoadAnimationGuardTimer_: function() { + this.loadAnimationGuardTimer_ = undefined; + this.onShowView_(); + }, + + /** + * Clears GAIA animation guard timer. + * @private + */ + clearLoadAnimationGuardTimer_: function() { + if (this.loadAnimationGuardTimer_) { + clearTimeout(this.loadAnimationGuardTimer_); + this.loadAnimationGuardTimer_ = undefined; + } + }, + + /** + * Sets up GAIA animation guard timer. + * @private + */ + startLoadAnimationGuardTimer_: function() { + this.clearLoadAnimationGuardTimer_(); + this.loadAnimationGuardTimer_ = setTimeout( + this.onLoadAnimationGuardTimer_.bind(this), + GAIA_ANIMATION_GUARD_MILLISEC); + }, + + /** + * Whether Gaia is loading. + * @type {boolean} + */ + get loading() { + return !this.$['gaia-loading'].hidden; + }, + set loading(loading) { + if (loading == this.loading) + return; + + this.showLoadingUI_(loading); + }, + + /** + * Event handler that is invoked just before the frame is shown. + */ + onBeforeShow: function() { + this.behaviors.forEach((behavior) => { + if (behavior.onBeforeShow) + behavior.onBeforeShow.call(this); + }); + + this.screenMode = ScreenMode.DEFAULT; + this.loading = true; + chrome.send('loginUIStateChanged', ['gaia-signin', true]); + Oobe.getInstance().setSigninUIState(SIGNIN_UI_STATE.GAIA_SIGNIN); + + // Ensure that GAIA signin (or loading UI) is actually visible. + window.requestAnimationFrame(function() { + chrome.send('loginVisible', ['gaia-loading']); + }); + + // Re-enable navigation in case it was disabled before refresh. + this.navigationDisabled_ = false; + + this.lastBackMessageValue_ = false; + this.updateControlsState(); + + this.$['offline-ad-auth'].onBeforeShow(); + this.$['signin-frame-dialog'].onBeforeShow(); + }, + + set navigationDisabled_(value) { + this.$['gaia-screen-buttons-overlay'].hidden = !value; + this.$['signin-back-button'].disabled = value; + }, + + /** + * @return {!Element} + * @private + */ + getSigninFrame_: function() { + // Note: Can't use |this.$|, since it returns cached references to elements + // originally present in DOM, while the signin-frame is dynamically + // recreated (see setSigninFramePartition_()). + const signinFrame = this.shadowRoot.getElementById('signin-frame'); + assert(signinFrame); + return signinFrame; + }, + + /** @private */ + getActiveFrame_: function() { + switch (this.screenMode_) { + case ScreenMode.DEFAULT: + return this.getSigninFrame_(); + case ScreenMode.OFFLINE: + return this.$['offline-gaia']; + case ScreenMode.AD_AUTH: + return this.$['offline-ad-auth']; + case ScreenMode.SAML_INTERSTITIAL: + return this.$['saml-interstitial']; + } + }, + + /** @private */ + focusActiveFrame_: function() { + this.getActiveFrame_().focus(); + }, + + /** Event handler that is invoked after the screen is shown. */ + onAfterShow: function() { + if (!this.loading) + this.focusActiveFrame_(); + }, + + /** + * Event handler that is invoked just before the screen is hidden. + */ + onBeforeHide: function() { + chrome.send('loginUIStateChanged', ['gaia-signin', false]); + Oobe.getInstance().setSigninUIState(SIGNIN_UI_STATE.HIDDEN); + this.$['offline-gaia'].switchToEmailCard(false /* animated */); + }, + + /** + * Copies attributes between nodes. + * @param {!Object} fromNode source to copy attributes from + * @param {!Object} toNode target to copy attributes to + * @param {!Set<string>} skipAttributes specifies attributes to be skipped + * @private + */ + copyAttributes_: function(fromNode, toNode, skipAttributes) { + for (var i = 0; i < fromNode.attributes.length; ++i) { + var attribute = fromNode.attributes[i]; + if (!skipAttributes.has(attribute.nodeName)) + toNode.setAttribute(attribute.nodeName, attribute.nodeValue); + } + }, + + /** + * Changes the 'partition' attribute of the sign-in frame. If the sign-in + * frame has already navigated, this function re-creates it. + * @param {string} newWebviewPartitionName the new partition + * @private + */ + setSigninFramePartition_: function(newWebviewPartitionName) { + var signinFrame = this.getSigninFrame_(); + + if (!signinFrame.src) { + // We have not navigated anywhere yet. Note that a webview's src + // attribute does not allow a change back to "". + signinFrame.partition = newWebviewPartitionName; + } else if (signinFrame.partition != newWebviewPartitionName) { + // The webview has already navigated. We have to re-create it. + var signinFrameParent = signinFrame.parentElement; + + // Copy all attributes except for partition and src from the previous + // webview. Use the specified |newWebviewPartitionName|. + var newSigninFrame = document.createElement('webview'); + this.copyAttributes_( + signinFrame, newSigninFrame, new Set(['src', 'partition'])); + newSigninFrame.partition = newWebviewPartitionName; + + signinFrameParent.replaceChild(newSigninFrame, signinFrame); + + // Make sure the authenticator uses the new webview from now on. + this.authenticator_.rebindWebview(newSigninFrame); + } + }, + + /** + * Loads the authentication extension into the iframe. + * @param {Object} data Extension parameters bag. + * @private + */ + loadAuthExtension: function(data) { + // Redirect the webview to the blank page in order to stop the SAML IdP + // page from working in a background (see crbug.com/613245). + if (this.screenMode_ == ScreenMode.DEFAULT && + data.screenMode != ScreenMode.DEFAULT) { + this.authenticator_.resetWebview(); + } + + this.setSigninFramePartition_(data.webviewPartitionName); + + // This triggers updateSigninFrameContainers_() + this.screenMode = data.screenMode; + this.email = ''; + this.authCompleted_ = false; + this.lastBackMessageValue_ = false; + + // Reset SAML + this.$['saml-notice-container'].hidden = true; + this.samlPasswordConfirmAttempt_ = 0; + + this.updateSigninFrameContainers_(); + + var params = {}; + for (var i in cr.login.Authenticator.SUPPORTED_PARAMS) { + var name = cr.login.Authenticator.SUPPORTED_PARAMS[i]; + if (data[name]) + params[name] = data[name]; + } + + params.doSamlRedirect = (this.screenMode_ == ScreenMode.SAML_INTERSTITIAL); + params.menuGuestMode = data.guestSignin; + params.menuKeyboardOptions = false; + params.menuEnterpriseEnrollment = + !(data.enterpriseManagedDevice || data.hasDeviceOwner); + params.isFirstUser = !(data.enterpriseManagedDevice || data.hasDeviceOwner); + params.obfuscatedOwnerId = data.obfuscatedOwnerId; + + this.authenticatorParams_ = params; + + switch (this.screenMode_) { + case ScreenMode.DEFAULT: + this.loadAuthenticator_(false /* doSamlRedirect */); + break; + + case ScreenMode.OFFLINE: + this.loadOffline(params); + break; + + case ScreenMode.AD_AUTH: + this.loadAdAuth(params); + break; + + case ScreenMode.SAML_INTERSTITIAL: + this.$['saml-interstitial'].domain = data.enterpriseDisplayDomain; + if (this.loading) + this.loading = false; + // This event is for the browser tests. + this.samlInterstitialPageReady = true; + this.$['saml-interstitial'].fire('samlInterstitialPageReady'); + break; + } + this.updateControlsState(); + chrome.send('authExtensionLoaded'); + }, + + /** + * Displays correct screen container for given mode and APi version. + */ + updateSigninFrameContainers_: function() { + let oldState = this.classList.contains('v2'); + this.classList.toggle('v2', false); + if (this.screenMode_ == ScreenMode.DEFAULT || + this.screenMode_ == ScreenMode.OFFLINE || + this.screenMode_ == ScreenMode.AD_AUTH) { + this.classList.toggle('v2', true); + } + if (Oobe.getInstance().currentScreen.id != 'gaia-signin') + return; + // Switching between signin-frame-dialog and gaia-step-contents + // updates screen size. + if (oldState != this.classList.contains('v2')) + Oobe.getInstance().updateScreenSize(this); + }, + + /** + * Whether the current auth flow is SAML. + */ + isSAML: function() { + return this.authenticator_.authFlow == cr.login.Authenticator.AuthFlow.SAML; + }, + + /** + * Helper function to update the title bar. + */ + updateSamlNotice_: function() { + if (this.authenticator_.videoEnabled) { + this.$['saml-notice-message'].textContent = loadTimeData.getStringF( + 'samlNoticeWithVideo', this.authenticator_.authDomain); + this.$['saml-notice-recording-indicator'].hidden = false; + this.$['saml-notice-container'].style.justifyContent = 'flex-start'; + } else { + this.$['saml-notice-message'].textContent = + loadTimeData.getStringF('samlNotice', this.authenticator_.authDomain); + this.$['saml-notice-recording-indicator'].hidden = true; + this.$['saml-notice-container'].style.justifyContent = 'center'; + } + }, + + /** + * Clean up from a video-enabled SAML flow. + */ + clearVideoTimer_: function() { + if (this.videoTimer_ !== undefined) { + clearTimeout(this.videoTimer_); + this.videoTimer_ = undefined; + } + }, + + /** + * Invoked when the authDomain property is changed on the authenticator. + */ + onAuthDomainChange_: function() { + this.updateSamlNotice_(); + }, + + /** + * Invoked when the videoEnabled property is changed on the authenticator. + */ + onVideoEnabledChange_: function() { + this.updateSamlNotice_(); + if (this.authenticator_.videoEnabled && this.videoTimer_ === undefined) { + this.videoTimer_ = + setTimeout(this.cancel.bind(this), VIDEO_LOGIN_TIMEOUT); + } else { + this.clearVideoTimer_(); + } + }, + + /** + * Invoked when the authFlow property is changed on the authenticator. + */ + onAuthFlowChange_: function() { + var isSAML = this.isSAML(); + + this.$['saml-notice-container'].hidden = !isSAML; + this.classList.toggle('saml', isSAML); + + if (Oobe.getInstance().currentScreen.id == 'gaia-signin') { + Oobe.getInstance().updateScreenSize(this); + } + + this.updateControlsState(); + }, + + /** + * Invoked when the authenticator emits 'ready' event or when another + * authentication frame is completely loaded. + * @private + */ + onAuthReady_: function() { + this.showViewProcessed_ = false; + this.startLoadAnimationGuardTimer_(); + this.clearLoadingTimer_(); + this.loading = false; + + if (!this.$['offline-gaia'].hidden) + this.$['offline-gaia'].focus(); + }, + + /** + * Invoked when a fra,e emits 'dialogShown' event. + * @private + */ + onDialogShown_: function() { + this.navigationDisabled_ = true; + }, + + /** + * Invoked when a frame emits 'dialogHidden' event. + * @private + */ + onDialogHidden_: function() { + this.navigationDisabled_ = false; + }, + + /** + * Invoked when user activates menu item. + * @private + */ + onMenuItemClicked_: function(e) { + if (e.detail == 'gm') { + Oobe.disableSigninUI(); + chrome.send('launchIncognito'); + } else if (e.detail == 'ee') { + cr.ui.Oobe.handleAccelerator(ACCELERATOR_ENROLLMENT); + } + }, + + /** + * Invoked when the authenticator requests whether the specified user is a + * user without a password (neither a manually entered one nor one provided + * via Credentials Passing API). + * @param {string} email + * @param {string} gaiaId + * @param {function(boolean)} callback + * @private + */ + getIsSamlUserPasswordless_: function(email, gaiaId, callback) { + cr.sendWithPromise('getIsSamlUserPasswordless', email, gaiaId) + .then(callback); + }, + + /** + * Invoked when a frame emits 'backButton' event. + * @private + */ + onBackButton_: function(e) { + this.getActiveFrame_().focus(); + this.lastBackMessageValue_ = !!e.detail; + this.updateControlsState(); + }, + + /** + * Invoked when the authenticator emits 'showView' event or when corresponding + * guard time fires. + * @private + */ + onShowView_: function(e) { + if (this.showViewProcessed_) + return; + + this.showViewProcessed_ = true; + this.clearLoadAnimationGuardTimer_(); + this.getActiveFrame_().classList.toggle('show', true); + this.onLoginUIVisible_(); + }, + + /** + * Called when UI is shown. + * @private + */ + onLoginUIVisible_: function() { + // Show deferred error bubble. + if (this.errorBubble_) { + this.showErrorBubble(this.errorBubble_[0], this.errorBubble_[1]); + this.errorBubble_ = undefined; + } + + chrome.send('loginWebuiReady'); + chrome.send('loginVisible', ['gaia-signin']); + }, + + /** + * Invoked when the user has successfully authenticated via SAML, the + * principals API was not used and the authenticator needs the user to confirm + * the scraped password. + * @param {string} email The authenticated user's e-mail. + * @param {number} passwordCount The number of passwords that were scraped. + * @private + */ + onAuthConfirmPassword_: function(email, passwordCount) { + this.loading = true; + + if (this.samlPasswordConfirmAttempt_ == 0) + chrome.send('scrapedPasswordCount', [passwordCount]); + + if (this.samlPasswordConfirmAttempt_ < 2) { + login.ConfirmPasswordScreen.show( + email, false /* manual password entry */, + this.samlPasswordConfirmAttempt_, + this.onConfirmPasswordCollected_.bind(this)); + } else { + chrome.send('scrapedPasswordVerificationFailed'); + this.showFatalAuthError( + loadTimeData.getString('fatalErrorMessageVerificationFailed'), + loadTimeData.getString('fatalErrorTryAgainButton')); + } + }, + + /** + * Invoked when the confirm password screen is dismissed. + * @private + */ + onConfirmPasswordCollected_: function(password) { + this.samlPasswordConfirmAttempt_++; + this.authenticator_.verifyConfirmedPassword(password); + + // Shows signin UI again without changing states. + Oobe.showScreen({id: SCREEN_GAIA_SIGNIN}); + }, + + /** + * Inovked when the user has successfully authenticated via SAML, the + * principals API was not used and no passwords could be scraped. + * The user will be asked to pick a manual password for the device. + * @param {string} email The authenticated user's e-mail. + */ + onAuthNoPassword_: function(email) { + chrome.send('scrapedPasswordCount', [0]); + login.ConfirmPasswordScreen.show( + email, true /* manual password entry */, + this.samlPasswordConfirmAttempt_, + this.onManualPasswordCollected_.bind(this)); + }, + + /** + * Invoked when the dialog where the user enters a manual password for the + * device, when password scraping fails. + * @param {string} password The password the user entered. Not necessarily + * the same as their SAML password. + */ + onManualPasswordCollected_: function(password) { + this.authenticator_.completeAuthWithManualPassword(password); + }, + + /** + * Invoked when the authentication flow had to be aborted because content + * served over an unencrypted connection was detected. Shows a fatal error. + * This method is only called on Chrome OS, where the entire authentication + * flow is required to be encrypted. + * @param {string} url The URL that was blocked. + */ + onInsecureContentBlocked_: function(url) { + this.showFatalAuthError( + loadTimeData.getStringF('fatalErrorMessageInsecureURL', url), + loadTimeData.getString('fatalErrorDoneButton')); + }, + + /** + * Shows the fatal auth error. + * @param {string} message The error message to show. + * @param {string} buttonLabel The label to display on dismiss button. + */ + showFatalAuthError: function(message, buttonLabel) { + login.FatalErrorScreen.show(message, buttonLabel, Oobe.showSigninUI); + }, + + /** + * Show fatal auth error when information is missing from GAIA. + */ + missingGaiaInfo_: function() { + this.showFatalAuthError( + loadTimeData.getString('fatalErrorMessageNoAccountDetails'), + loadTimeData.getString('fatalErrorTryAgainButton')); + }, + + /** + * Record that SAML API was used during sign-in. + */ + samlApiUsed_: function() { + chrome.send('usingSAMLAPI'); + }, + + /** + * Invoked when auth is completed successfully. + * @param {!Object} credentials Credentials of the completed authentication. + * @private + */ + onAuthCompleted_: function(credentials) { + if (this.screenMode_ == ScreenMode.AD_AUTH) { + this.email = credentials.username; + chrome.send( + 'completeAdAuthentication', + [credentials.username, credentials.password]); + } else if (credentials.useOffline) { + this.email = credentials.email; + chrome.send( + 'completeOfflineAuthentication', + [credentials.email, credentials.password]); + } else { + chrome.send('completeAuthentication', [ + credentials.gaiaId, credentials.email, credentials.password, + credentials.usingSAML, credentials.services, + credentials.passwordAttributes + ]); + } + + this.loading = true; + // Hide the back button and the border line as they are not useful + // when the loading screen is shown. + this.$['signin-back-button'].hidden = true; + this.$['signin-frame-dialog'].setAttribute('hide-shadow', true); + + // Clear any error messages that were shown before login. + Oobe.clearErrors(); + + this.clearVideoTimer_(); + this.authCompleted_ = true; + this.updateControlsState(); + }, + + /** + * Invoked when onAuthCompleted message received. + * @param {!Object} e Payload of the received HTML5 message. + * @private + */ + onAuthCompletedMessage_: function(e) { + this.onAuthCompleted_(e.detail); + }, + + /** + * Invoked when onLoadAbort message received. + * @param {!Object} e Payload of the received HTML5 message. + * @private + */ + onLoadAbortMessage_: function(e) { + this.onWebviewError(e.detail); + }, + + /** + * Invoked when identifierEntered message received. + * @param {!Object} e Payload of the received HTML5 message. + * @private + */ + onIdentifierEnteredMessage_: function(e) { + this.onIdentifierEntered(e.detail); + }, + + /** + * Clears input fields and switches to input mode. + * @param {boolean} takeFocus True to take focus. + * @param {boolean} forceOnline Whether online sign-in should be forced. + * If |forceOnline| is false previously used sign-in type will be used. + */ + reset: function(takeFocus, forceOnline) { + // Reload and show the sign-in UI if needed. + this.authenticator_.resetStates(); + if (takeFocus) { + if (!forceOnline && this.isOffline()) { + Oobe.getInstance().setSigninUIState(SIGNIN_UI_STATE.GAIA_SIGNIN); + // Do nothing, since offline version is reloaded after an error comes. + } else { + Oobe.showSigninUI(); + } + } + }, + + /** + * Reloads extension frame. + */ + doReload: function() { + if (this.screenMode_ != ScreenMode.DEFAULT) + return; + this.authenticator_.reload(); + this.loading = true; + this.startLoadingTimer_(); + this.lastBackMessageValue_ = false; + this.authCompleted_ = false; + this.updateControlsState(); + }, + + /** + * Shows sign-in error bubble. + * @param {number} loginAttempts Number of login attempts tried. + * @param {HTMLElement} content Content to show in bubble. + */ + showErrorBubble: function(loginAttempts, error) { + if (this.isOffline()) { + // Reload offline version of the sign-in extension, which will show + // error itself. + chrome.send('offlineLogin', [this.email]); + } else if (!this.loading) { + $('bubble').showContentForElement( + this, cr.ui.Bubble.Attachment.BOTTOM, error, + BUBBLE_HORIZONTAL_PADDING, BUBBLE_VERTICAL_PADDING); + } else { + // Defer the bubble until the frame has been loaded. + this.errorBubble_ = [loginAttempts, error]; + } + }, + + /** + * Called when user canceled signin. + */ + cancel: function() { + this.clearVideoTimer_(); + + const isWhitelistError = this.classList.contains('whitelist-error'); + // TODO(crbug.com/470893): Figure out whether/which of these exit conditions + // are useful. + if (this.screenMode_ == ScreenMode.SAML_INTERSTITIAL || isWhitelistError || + this.authCompleted_) { + return; + } + + if (this.screenMode_ == ScreenMode.AD_AUTH) + chrome.send('cancelAdAuthentication'); + + if (this.closable) + Oobe.showUserPods(); + else + Oobe.resetSigninUI(true); + }, + + /** + * Handler for webview error handling. + * @param {!Object} data Additional information about error event like: + * {string} error Error code such as "ERR_INTERNET_DISCONNECTED". + * {string} url The URL that failed to load. + */ + onWebviewError: function(data) { + chrome.send('webviewLoadAborted', [data.error]); + }, + + /** + * Handler for identifierEntered event. + * @param {!Object} data The identifier entered by user: + * {string} accountIdentifier User identifier. + */ + onIdentifierEntered: function(data) { + chrome.send('identifierEntered', [data.accountIdentifier]); + }, + + /** + * Sets enterprise info strings for offline gaia. + * Also sets callback and sends message whether we already have email and + * should switch to the password screen with error. + */ + loadOffline: function(params) { + this.loading = true; + this.startLoadingTimer_(); + var offlineLogin = this.$['offline-gaia']; + if ('enterpriseDisplayDomain' in params) + offlineLogin.domain = params['enterpriseDisplayDomain']; + if ('emailDomain' in params) + offlineLogin.emailDomain = '@' + params['emailDomain']; + offlineLogin.setEmail(params.email); + this.onAuthReady_(); + }, + + loadAdAuth: function(params) { + this.loading = true; + this.startLoadingTimer_(); + var adAuthUI = this.getActiveFrame_(); + adAuthUI.realm = params['realm']; + + if ('emailDomain' in params) + adAuthUI.userRealm = '@' + params['emailDomain']; + + adAuthUI.userName = params['email']; + adAuthUI.focus(); + this.onAuthReady_(); + }, + + /** + * Show/Hide error when user is not in whitelist. When UI is hidden + * GAIA is reloaded. + * @param {boolean} show Show/hide error UI. + * @param {!Object} opt_data Optional additional information. + */ + showWhitelistCheckFailedError: function(show, opt_data) { + if (show) { + var isManaged = opt_data && opt_data.enterpriseManaged; + this.$['gaia-whitelist-error'].textContent = loadTimeData.getValue( + isManaged ? 'whitelistErrorEnterprise' : 'whitelistErrorConsumer'); + // To make animations correct, we need to make sure Gaia is completely + // reloaded. Otherwise ChromeOS overlays hide and Gaia page is shown + // somewhere in the middle of animations. + if (this.screenMode_ == ScreenMode.DEFAULT) + this.authenticator_.resetWebview(); + } + + this.classList.toggle('whitelist-error', show); + this.loading = !show; + + if (show) + this.$['gaia-whitelist-error'].submitButton.focus(); + else + Oobe.showSigninUI(); + + this.updateControlsState(); + }, + + invalidateAd: function(username, errorState) { + if (this.screenMode_ != ScreenMode.AD_AUTH) + return; + var adAuthUI = this.getActiveFrame_(); + adAuthUI.userName = username; + adAuthUI.errorState = errorState; + this.authCompleted_ = false; + this.loading = false; + }, + }); +})();
diff --git a/chrome/browser/resources/gaia_auth_host/authenticator.js b/chrome/browser/resources/gaia_auth_host/authenticator.js index b4dbbb3..06f0dec 100644 --- a/chrome/browser/resources/gaia_auth_host/authenticator.js +++ b/chrome/browser/resources/gaia_auth_host/authenticator.js
@@ -113,7 +113,7 @@ */ class Authenticator extends cr.EventTarget { /** - * @param {webview|string} webview The webview element or its ID to host + * @param {!WebView|string} webview The webview element or its ID to host * IdP web pages. */ constructor(webview) { @@ -127,12 +127,19 @@ this.skipForNow_ = false; this.authFlow = AuthFlow.DEFAULT; this.authDomain = ''; + /** + * @type {!cr.login.SamlHandler|undefined} + * @private + */ + this.samlHandler_ = undefined; this.videoEnabled = false; this.idpOrigin_ = null; this.initialFrameUrl_ = null; this.reloadUrl_ = null; this.trusted_ = true; this.readyFired_ = false; + this.webview_ = typeof webview == 'string' ? $(webview) : webview; + assert(this.webview_); this.webviewEventManager_ = WebviewEventManager.create(); this.clientId_ = null; @@ -160,12 +167,22 @@ */ this.isSamlUserPasswordless_ = null; - this.bindToWebview_(webview); - window.addEventListener( 'message', this.onMessageFromWebview_.bind(this), false); window.addEventListener('focus', this.onFocus_.bind(this), false); window.addEventListener('popstate', this.onPopState_.bind(this), false); + + /** + * @type {boolean} + * @private + */ + this.isDomLoaded_ = document.readyState != 'loading'; + if (this.isDomLoaded_) { + this.initializeAfterDomLoaded_(); + } else { + document.addEventListener( + 'DOMContentLoaded', this.initializeAfterDomLoaded_.bind(this)); + } } /** @@ -199,16 +216,23 @@ } /** - * Binds this authenticator to the passed webview. - * @param {!Object} webview the new webview to be used by this - * Authenticator. + * Completes the part of the initialization that should happen after the + * page's DOM has loaded. * @private */ - bindToWebview_(webview) { - assert(!this.webview_); - assert(!this.samlHandler_); + initializeAfterDomLoaded_() { + this.isDomLoaded_ = true; + this.bindToWebview_(); + } - this.webview_ = typeof webview == 'string' ? $(webview) : webview; + /** + * Binds this authenticator to the current |webview_|. + * @private + */ + bindToWebview_() { + assert(this.webview_); + assert(this.webview_.request); + assert(!this.samlHandler_); this.samlHandler_ = new cr.login.SamlHandler(this.webview_, false /* startsOnSamlPage */); @@ -266,8 +290,16 @@ * @param {Object} webview the new webview to be used by this Authenticator. */ rebindWebview(webview) { + if (!this.isDomLoaded_) { + // We haven't bound to the previously set webview yet, so simply update + // |webview_| to use the new element during the delayed initialization. + this.webview_ = webview; + return; + } this.unbindFromWebview_(); - this.bindToWebview_(webview); + assert(!this.webview_); + this.webview_ = webview; + this.bindToWebview_(); } /**
diff --git a/chrome/browser/resources/settings/app_management_page/app_management_page.js b/chrome/browser/resources/settings/app_management_page/app_management_page.js index bbe68be..57a46ec 100644 --- a/chrome/browser/resources/settings/app_management_page/app_management_page.js +++ b/chrome/browser/resources/settings/app_management_page/app_management_page.js
@@ -12,11 +12,6 @@ /** @private */ onManageAppsClick_: function() { - const host = window.location.hostname; - if (host.includes('settings')) { - window.location.href = `chrome://app-management?ref=${host}`; - } else { - window.location.href = 'chrome://app-management'; - } + window.location.href = 'chrome://app-management'; }, });
diff --git a/chrome/browser/resources/settings/autofill_page/autofill_section.js b/chrome/browser/resources/settings/autofill_page/autofill_section.js index 652a4aa..905f6e6 100644 --- a/chrome/browser/resources/settings/autofill_page/autofill_section.js +++ b/chrome/browser/resources/settings/autofill_page/autofill_section.js
@@ -50,12 +50,12 @@ class AutofillManagerImpl { /** @override */ addAddressListChangedListener(listener) { - chrome.autofillPrivate.onAddressListChanged.addListener(listener); + chrome.autofillPrivate.onPersonalDataChanged.addListener(listener); } /** @override */ removeAddressListChangedListener(listener) { - chrome.autofillPrivate.onAddressListChanged.removeListener(listener); + chrome.autofillPrivate.onPersonalDataChanged.removeListener(listener); } /** @override */
diff --git a/chrome/browser/resources/settings/autofill_page/payments_section.js b/chrome/browser/resources/settings/autofill_page/payments_section.js index 03d51d2..59a5d585 100644 --- a/chrome/browser/resources/settings/autofill_page/payments_section.js +++ b/chrome/browser/resources/settings/autofill_page/payments_section.js
@@ -63,12 +63,12 @@ class PaymentsManagerImpl { /** @override */ addCreditCardListChangedListener(listener) { - chrome.autofillPrivate.onCreditCardListChanged.addListener(listener); + chrome.autofillPrivate.onPersonalDataChanged.addListener(listener); } /** @override */ removeCreditCardListChangedListener(listener) { - chrome.autofillPrivate.onCreditCardListChanged.removeListener(listener); + chrome.autofillPrivate.onPersonalDataChanged.removeListener(listener); } /** @override */
diff --git a/chrome/browser/safe_browsing/download_protection/check_client_download_request.cc b/chrome/browser/safe_browsing/download_protection/check_client_download_request.cc index 15558737..3126ad2 100644 --- a/chrome/browser/safe_browsing/download_protection/check_client_download_request.cc +++ b/chrome/browser/safe_browsing/download_protection/check_client_download_request.cc
@@ -528,20 +528,20 @@ history->QueryRedirectsTo( tab_url_, - base::Bind(&CheckClientDownloadRequest::OnGotTabRedirects, - weakptr_factory_.GetWeakPtr(), tab_url_), + base::BindOnce(&CheckClientDownloadRequest::OnGotTabRedirects, + weakptr_factory_.GetWeakPtr(), tab_url_), &request_tracker_); } void CheckClientDownloadRequest::OnGotTabRedirects( const GURL& url, - const history::RedirectList* redirect_list) { + history::RedirectList redirect_list) { DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_EQ(url, tab_url_); - if (!redirect_list->empty()) { - tab_redirects_.insert(tab_redirects_.end(), redirect_list->rbegin(), - redirect_list->rend()); + if (!redirect_list.empty()) { + tab_redirects_.insert(tab_redirects_.end(), redirect_list.rbegin(), + redirect_list.rend()); } SendRequest();
diff --git a/chrome/browser/safe_browsing/download_protection/check_client_download_request.h b/chrome/browser/safe_browsing/download_protection/check_client_download_request.h index ae219730..ca9ae31 100644 --- a/chrome/browser/safe_browsing/download_protection/check_client_download_request.h +++ b/chrome/browser/safe_browsing/download_protection/check_client_download_request.h
@@ -80,8 +80,7 @@ void OnUrlWhitelistCheckDone(bool is_whitelisted); void OnCertificateWhitelistCheckDone(bool is_whitelisted); void GetTabRedirects(); - void OnGotTabRedirects(const GURL& url, - const history::RedirectList* redirect_list); + void OnGotTabRedirects(const GURL& url, history::RedirectList redirect_list); bool IsDownloadManuallyBlacklisted(const ClientDownloadRequest& request); std::string SanitizeUrl(const GURL& url) const; void SendRequest();
diff --git a/chrome/browser/safe_json_parser_browsertest.cc b/chrome/browser/safe_json_parser_browsertest.cc index 8cb9229..8c04612 100644 --- a/chrome/browser/safe_json_parser_browsertest.cc +++ b/chrome/browser/safe_json_parser_browsertest.cc
@@ -64,27 +64,28 @@ SafeJsonParser::SuccessCallback success_callback; SafeJsonParser::ErrorCallback error_callback; if (value_with_error.value) { - success_callback = - base::Bind(&SafeJsonParserTest::ExpectValue, base::Unretained(this), - base::Passed(std::move(*value_with_error.value))); - error_callback = base::Bind(&SafeJsonParserTest::FailWithError, - base::Unretained(this)); + success_callback = base::BindOnce(&SafeJsonParserTest::ExpectValue, + base::Unretained(this), + std::move(*value_with_error.value)); + error_callback = base::BindOnce(&SafeJsonParserTest::FailWithError, + base::Unretained(this)); } else { - success_callback = base::Bind(&SafeJsonParserTest::FailWithValue, - base::Unretained(this)); - error_callback = - base::Bind(&SafeJsonParserTest::ExpectError, base::Unretained(this), - value_with_error.error_message); + success_callback = base::BindOnce(&SafeJsonParserTest::FailWithValue, + base::Unretained(this)); + error_callback = base::BindOnce(&SafeJsonParserTest::ExpectError, + base::Unretained(this), + value_with_error.error_message); } if (batch_id) { SafeJsonParser::ParseBatch( content::ServiceManagerConnection::GetForProcess()->GetConnector(), - json, success_callback, error_callback, *batch_id); + json, std::move(success_callback), std::move(error_callback), + *batch_id); } else { SafeJsonParser::Parse( content::ServiceManagerConnection::GetForProcess()->GetConnector(), - json, success_callback, error_callback); + json, std::move(success_callback), std::move(error_callback)); } message_loop_runner_->Run();
diff --git a/chrome/browser/search/local_ntp_first_run_field_trial_handler.cc b/chrome/browser/search/local_ntp_first_run_field_trial_handler.cc index 884aeb7..bfc2e49a4 100644 --- a/chrome/browser/search/local_ntp_first_run_field_trial_handler.cc +++ b/chrome/browser/search/local_ntp_first_run_field_trial_handler.cc
@@ -93,8 +93,7 @@ scoped_refptr<base::FieldTrial> trial( base::FieldTrialList::FactoryGetFieldTrial( config.trial_name(), kTotalProbability, kDefaultGroup, - config.expire_year(), config.expire_month(), - config.expire_day_of_month(), base::FieldTrial::ONE_TIME_RANDOMIZED, + base::FieldTrial::ONE_TIME_RANDOMIZED, /*default_group_number=*/nullptr)); for (const auto& group : config.groups()) { variations::AssociateGoogleVariationID(variations::GOOGLE_WEB_PROPERTIES,
diff --git a/chrome/browser/search/local_ntp_first_run_field_trials.cc b/chrome/browser/search/local_ntp_first_run_field_trials.cc index e00812fd..b3f5b491 100644 --- a/chrome/browser/search/local_ntp_first_run_field_trials.cc +++ b/chrome/browser/search/local_ntp_first_run_field_trials.cc
@@ -14,10 +14,7 @@ LocalNtpFirstRunFieldTrialConfig::LocalNtpFirstRunFieldTrialConfig( const std::string& trial_name) - : trial_name_(trial_name), - expire_year_(base::FieldTrialList::kNoExpirationYear), - expire_month_(1), - expire_day_of_month_(1) {} + : trial_name_(trial_name) {} LocalNtpFirstRunFieldTrialConfig::~LocalNtpFirstRunFieldTrialConfig() = default;
diff --git a/chrome/browser/search/local_ntp_first_run_field_trials.h b/chrome/browser/search/local_ntp_first_run_field_trials.h index 6e943ac..9e5f316 100644 --- a/chrome/browser/search/local_ntp_first_run_field_trials.h +++ b/chrome/browser/search/local_ntp_first_run_field_trials.h
@@ -51,16 +51,10 @@ } // Accessors for this FieldTrial. const std::string& trial_name() { return trial_name_; } - int expire_year() { return expire_year_; } - int expire_month() { return expire_month_; } - int expire_day_of_month() { return expire_day_of_month_; } private: std::string trial_name_; std::vector<LocalNtpFirstRunFieldTrialGroup> groups_; - int expire_year_; - int expire_month_; - int expire_day_of_month_; DISALLOW_COPY_AND_ASSIGN(LocalNtpFirstRunFieldTrialConfig); };
diff --git a/chrome/browser/search/one_google_bar/one_google_bar_loader_impl.cc b/chrome/browser/search/one_google_bar/one_google_bar_loader_impl.cc index b3cdee8..216ca39 100644 --- a/chrome/browser/search/one_google_bar/one_google_bar_loader_impl.cc +++ b/chrome/browser/search/one_google_bar/one_google_bar_loader_impl.cc
@@ -336,10 +336,10 @@ data_decoder::SafeJsonParser::Parse( content::ServiceManagerConnection::GetForProcess()->GetConnector(), response, - base::BindRepeating(&OneGoogleBarLoaderImpl::JsonParsed, - weak_ptr_factory_.GetWeakPtr()), - base::BindRepeating(&OneGoogleBarLoaderImpl::JsonParseFailed, - weak_ptr_factory_.GetWeakPtr())); + base::BindOnce(&OneGoogleBarLoaderImpl::JsonParsed, + weak_ptr_factory_.GetWeakPtr()), + base::BindOnce(&OneGoogleBarLoaderImpl::JsonParseFailed, + weak_ptr_factory_.GetWeakPtr())); } void OneGoogleBarLoaderImpl::JsonParsed(base::Value value) {
diff --git a/chrome/browser/search/promos/promo_service.cc b/chrome/browser/search/promos/promo_service.cc index 4988005f..1ec7488a 100644 --- a/chrome/browser/search/promos/promo_service.cc +++ b/chrome/browser/search/promos/promo_service.cc
@@ -161,10 +161,10 @@ data_decoder::SafeJsonParser::Parse( content::ServiceManagerConnection::GetForProcess()->GetConnector(), response, - base::BindRepeating(&PromoService::OnJsonParsed, - weak_ptr_factory_.GetWeakPtr()), - base::BindRepeating(&PromoService::OnJsonParseFailed, - weak_ptr_factory_.GetWeakPtr())); + base::BindOnce(&PromoService::OnJsonParsed, + weak_ptr_factory_.GetWeakPtr()), + base::BindOnce(&PromoService::OnJsonParseFailed, + weak_ptr_factory_.GetWeakPtr())); } void PromoService::OnJsonParsed(base::Value value) {
diff --git a/chrome/browser/search/search_suggest/search_suggest_loader_impl.cc b/chrome/browser/search/search_suggest/search_suggest_loader_impl.cc index 6d3dd18..e7ca4dc 100644 --- a/chrome/browser/search/search_suggest/search_suggest_loader_impl.cc +++ b/chrome/browser/search/search_suggest/search_suggest_loader_impl.cc
@@ -271,10 +271,10 @@ data_decoder::SafeJsonParser::Parse( content::ServiceManagerConnection::GetForProcess()->GetConnector(), response, - base::BindRepeating(&SearchSuggestLoaderImpl::JsonParsed, - weak_ptr_factory_.GetWeakPtr()), - base::BindRepeating(&SearchSuggestLoaderImpl::JsonParseFailed, - weak_ptr_factory_.GetWeakPtr())); + base::BindOnce(&SearchSuggestLoaderImpl::JsonParsed, + weak_ptr_factory_.GetWeakPtr()), + base::BindOnce(&SearchSuggestLoaderImpl::JsonParseFailed, + weak_ptr_factory_.GetWeakPtr())); } void SearchSuggestLoaderImpl::JsonParsed(base::Value value) {
diff --git a/chrome/browser/sharing/OWNERS b/chrome/browser/sharing/OWNERS new file mode 100644 index 0000000..58b32014 --- /dev/null +++ b/chrome/browser/sharing/OWNERS
@@ -0,0 +1,3 @@ +peter@chromium.org + +# COMPONENT: UI>Browser>Sharing
diff --git a/chrome/browser/sharing/proto/BUILD.gn b/chrome/browser/sharing/proto/BUILD.gn new file mode 100644 index 0000000..5971cdb --- /dev/null +++ b/chrome/browser/sharing/proto/BUILD.gn
@@ -0,0 +1,18 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//third_party/protobuf/proto_library.gni") + +group("proto_lite") { + public_deps = [ + ":proto", + "//third_party/protobuf:protobuf_lite", + ] +} + +proto_library("proto") { + sources = [ + "sharing_message.proto", + ] +}
diff --git a/chrome/browser/sharing/proto/sharing_message.proto b/chrome/browser/sharing/proto/sharing_message.proto new file mode 100644 index 0000000..1d27ac14 --- /dev/null +++ b/chrome/browser/sharing/proto/sharing_message.proto
@@ -0,0 +1,39 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +syntax = "proto3"; + +package chrome_browser_sharing; + +// Required in Chrome. +option optimize_for = LITE_RUNTIME; + +// Message for sending between devices in Sharing. +message SharingMessage { + // Unique message identifier. required. + string message_id = 1; + + // Identifier of sender. required. + string sender_guid = 2; + + // Timestamp at which message was sent. required. + int64 send_timestamp = 3; + + // Payload of the message, contains one of the messages below. required. + oneof payload { + PingMessage ping_message = 4; + AckMessage ack_message = 5; + } +} + +// Message for pinging the receiver expecting an acknowledgement. +message PingMessage { + // Intentionally empty. +} + +// Message for acknowledging the sender after a non-AckMessage is received. +message AckMessage { + // required. + string original_message_id = 1; +}
diff --git a/chrome/browser/sharing/sharing_device_info.cc b/chrome/browser/sharing/sharing_device_info.cc new file mode 100644 index 0000000..47d02d7 --- /dev/null +++ b/chrome/browser/sharing/sharing_device_info.cc
@@ -0,0 +1,32 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/sharing/sharing_device_info.h" + +SharingDeviceInfo::SharingDeviceInfo(const std::string& guid, + const std::string& human_readable_name, + base::Time last_online_timestamp, + int capabilities) + : guid_(guid), + human_readable_name_(human_readable_name), + last_online_timestamp_(last_online_timestamp), + capabilities_(capabilities) {} + +SharingDeviceInfo::~SharingDeviceInfo() = default; + +const std::string& SharingDeviceInfo::guid() const { + return guid_; +} + +const std::string& SharingDeviceInfo::human_readable_name() const { + return human_readable_name_; +} + +base::Time SharingDeviceInfo::last_online_timestamp() const { + return last_online_timestamp_; +} + +int SharingDeviceInfo::capabilities() const { + return capabilities_; +}
diff --git a/chrome/browser/sharing/sharing_device_info.h b/chrome/browser/sharing/sharing_device_info.h new file mode 100644 index 0000000..3eb512d --- /dev/null +++ b/chrome/browser/sharing/sharing_device_info.h
@@ -0,0 +1,50 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SHARING_SHARING_DEVICE_INFO_H_ +#define CHROME_BROWSER_SHARING_SHARING_DEVICE_INFO_H_ + +#include <string> + +#include "base/macros.h" +#include "base/time/time.h" + +// Capabilities of which a device can perform. +enum class SharingDeviceCapability { kNone = 0 }; + +// A class that holds information regarding the properties of a device. +class SharingDeviceInfo { + public: + SharingDeviceInfo(const std::string& guid, + const std::string& human_readable_name, + base::Time last_online_timestamp, + int capabilities); + ~SharingDeviceInfo(); + + // Unique identifier for the device. + const std::string& guid() const; + + // A human readable name of the device. + const std::string& human_readable_name() const; + + // Returns the time at which this device was last online. + base::Time last_online_timestamp() const; + + // Gets a bitmask of available capaiblities of the device, defined in + // SharingDeviceCapability enum. + int capabilities() const; + + private: + const std::string guid_; + + const std::string human_readable_name_; + + const base::Time last_online_timestamp_; + + int capabilities_; + + DISALLOW_COPY_AND_ASSIGN(SharingDeviceInfo); +}; + +#endif // CHROME_BROWSER_SHARING_SHARING_DEVICE_INFO_H_
diff --git a/chrome/browser/sharing/sharing_message_handler.h b/chrome/browser/sharing/sharing_message_handler.h new file mode 100644 index 0000000..c089f5f --- /dev/null +++ b/chrome/browser/sharing/sharing_message_handler.h
@@ -0,0 +1,23 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SHARING_SHARING_MESSAGE_HANDLER_H_ +#define CHROME_BROWSER_SHARING_SHARING_MESSAGE_HANDLER_H_ + +#include <string> + +#include "chrome/browser/sharing/proto/sharing_message.pb.h" + +// Interface for handling incoming SharingMessage. +class SharingMessageHandler { + public: + SharingMessageHandler(); + virtual ~SharingMessageHandler(); + + // Called when a SharingMessage has been received. + virtual void OnMessage( + const chrome_browser_sharing::SharingMessage& message) = 0; +}; + +#endif // CHROME_BROWSER_SHARING_SHARING_MESSAGE_HANDLER_H_
diff --git a/chrome/browser/sharing/sharing_service.cc b/chrome/browser/sharing/sharing_service.cc new file mode 100644 index 0000000..59d48f17 --- /dev/null +++ b/chrome/browser/sharing/sharing_service.cc
@@ -0,0 +1,24 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/sharing/sharing_service.h" + +SharingService::SharingService() = default; + +SharingService::~SharingService() = default; + +std::vector<SharingDeviceInfo> SharingService::GetDeviceCandidates( + int required_capabilities) const { + return std::vector<SharingDeviceInfo>(); +} + +bool SharingService::SendMessage( + const std::string& device_guid, + const chrome_browser_sharing::SharingMessage& message) { + return true; +} + +void SharingService::RegisterHandler( + chrome_browser_sharing::SharingMessage::PayloadCase payload_type, + SharingMessageHandler* handler) {}
diff --git a/chrome/browser/sharing/sharing_service.h b/chrome/browser/sharing/sharing_service.h new file mode 100644 index 0000000..c59f803 --- /dev/null +++ b/chrome/browser/sharing/sharing_service.h
@@ -0,0 +1,42 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SHARING_SHARING_SERVICE_H_ +#define CHROME_BROWSER_SHARING_SHARING_SERVICE_H_ + +#include <string> +#include <vector> + +#include "chrome/browser/sharing/proto/sharing_message.pb.h" +#include "chrome/browser/sharing/sharing_device_info.h" +#include "chrome/browser/sharing/sharing_message_handler.h" +#include "components/keyed_service/core/keyed_service.h" + +// Class to manage lifecycle of sharing feature, and provide APIs to send +// sharing messages to other devices. +class SharingService : public KeyedService { + public: + SharingService(); + ~SharingService() override; + + // Returns a list of DeviceInfo that is available to receive messages. + // All returned devices has the specified |required_capabilities| defined in + // SharingDeviceCapability enum. + std::vector<SharingDeviceInfo> GetDeviceCandidates( + int required_capabilities) const; + + // Sends a message to the device specified by GUID. + bool SendMessage(const std::string& device_guid, + const chrome_browser_sharing::SharingMessage& message); + + // Registers a handler of a given SharingMessage payload type. + void RegisterHandler( + chrome_browser_sharing::SharingMessage::PayloadCase payload_type, + SharingMessageHandler* handler); + + private: + DISALLOW_COPY_AND_ASSIGN(SharingService); +}; + +#endif // CHROME_BROWSER_SHARING_SHARING_SERVICE_H_
diff --git a/chrome/browser/sharing/sharing_service_factory.cc b/chrome/browser/sharing/sharing_service_factory.cc new file mode 100644 index 0000000..bae69e3 --- /dev/null +++ b/chrome/browser/sharing/sharing_service_factory.cc
@@ -0,0 +1,48 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/sharing/sharing_service_factory.h" + +#include "base/memory/singleton.h" +#include "chrome/browser/profiles/incognito_helpers.h" +#include "chrome/browser/sharing/sharing_service.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "content/public/browser/browser_context.h" + +namespace { +constexpr char kServiceName[] = "SharingService"; +} // namespace + +// static +SharingServiceFactory* SharingServiceFactory::GetInstance() { + return base::Singleton<SharingServiceFactory>::get(); +} + +// static +SharingService* SharingServiceFactory::GetForBrowserContext( + content::BrowserContext* context) { + return static_cast<SharingService*>( + GetInstance()->GetServiceForBrowserContext(context, true)); +} + +SharingServiceFactory::SharingServiceFactory() + : BrowserContextKeyedServiceFactory( + kServiceName, + BrowserContextDependencyManager::GetInstance()) {} + +SharingServiceFactory::~SharingServiceFactory() = default; + +KeyedService* SharingServiceFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + return new SharingService(); +} + +content::BrowserContext* SharingServiceFactory::GetBrowserContextToUse( + content::BrowserContext* context) const { + return chrome::GetBrowserContextRedirectedInIncognito(context); +} + +bool SharingServiceFactory::ServiceIsCreatedWithBrowserContext() const { + return true; +}
diff --git a/chrome/browser/sharing/sharing_service_factory.h b/chrome/browser/sharing/sharing_service_factory.h new file mode 100644 index 0000000..8e9bc8a --- /dev/null +++ b/chrome/browser/sharing/sharing_service_factory.h
@@ -0,0 +1,46 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SHARING_SHARING_SERVICE_FACTORY_H_ +#define CHROME_BROWSER_SHARING_SHARING_SERVICE_FACTORY_H_ + +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +namespace base { +template <typename T> +struct DefaultSingletonTraits; +} // namespace base + +namespace content { +class BrowserContext; +} + +class SharingService; + +// Factory for SharingService. +class SharingServiceFactory : public BrowserContextKeyedServiceFactory { + public: + // Returns singleton instance of SharingServiceFactory. + static SharingServiceFactory* GetInstance(); + + // Returns the SharingService associated with |context|. + static SharingService* GetForBrowserContext(content::BrowserContext* context); + + private: + friend struct base::DefaultSingletonTraits<SharingServiceFactory>; + + SharingServiceFactory(); + ~SharingServiceFactory() override; + + // BrowserContextKeyedServiceFactory overrides: + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override; + content::BrowserContext* GetBrowserContextToUse( + content::BrowserContext* context) const override; + bool ServiceIsCreatedWithBrowserContext() const override; + + DISALLOW_COPY_AND_ASSIGN(SharingServiceFactory); +}; + +#endif // CHROME_BROWSER_SHARING_SHARING_SERVICE_FACTORY_H_
diff --git a/chrome/browser/supervised_user/supervised_user_browsertest.cc b/chrome/browser/supervised_user/supervised_user_browsertest.cc index 2e6fce6f..c181dd8 100644 --- a/chrome/browser/supervised_user/supervised_user_browsertest.cc +++ b/chrome/browser/supervised_user/supervised_user_browsertest.cc
@@ -10,6 +10,7 @@ #include "base/feature_list.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/bind_test_util.h" #include "base/test/scoped_feature_list.h" #include "base/values.h" #include "chrome/browser/chrome_notification_types.h" @@ -212,15 +213,13 @@ history::QueryResults* results) { base::RunLoop run_loop; base::CancelableTaskTracker history_task_tracker; - auto callback = [](history::QueryResults* new_results, - base::RunLoop* run_loop, - history::QueryResults* results) { - results->Swap(new_results); - run_loop->Quit(); - }; - history_service->QueryHistory(base::UTF8ToUTF16(text_query), options, - base::Bind(callback, results, &run_loop), - &history_task_tracker); + history_service->QueryHistory( + base::UTF8ToUTF16(text_query), options, + base::BindLambdaForTesting([&](history::QueryResults r) { + *results = std::move(r); + run_loop.Quit(); + }), + &history_task_tracker); run_loop.Run(); // Will go until ...Complete calls Quit. }
diff --git a/chrome/browser/sync/test/integration/single_client_nigori_sync_test.cc b/chrome/browser/sync/test/integration/single_client_nigori_sync_test.cc index 03a2d27..a816ac39 100644 --- a/chrome/browser/sync/test/integration/single_client_nigori_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_nigori_sync_test.cc
@@ -24,11 +24,11 @@ MATCHER_P(IsDataEncryptedWith, key_params, "") { const sync_pb::EncryptedData& encrypted_data = arg; - syncer::Nigori nigori; - nigori.InitByDerivation(key_params.derivation_params, key_params.password); + std::unique_ptr<syncer::Nigori> nigori = syncer::Nigori::CreateByDerivation( + key_params.derivation_params, key_params.password); std::string nigori_name; - EXPECT_TRUE(nigori.Permute(syncer::Nigori::Type::Password, - syncer::kNigoriKeyName, &nigori_name)); + EXPECT_TRUE(nigori->Permute(syncer::Nigori::Type::Password, + syncer::kNigoriKeyName, &nigori_name)); return encrypted_data.key_name() == nigori_name; }
diff --git a/chrome/browser/ui/cocoa/history_menu_bridge.h b/chrome/browser/ui/cocoa/history_menu_bridge.h index 458e254..ae14d8e0 100644 --- a/chrome/browser/ui/cocoa/history_menu_bridge.h +++ b/chrome/browser/ui/cocoa/history_menu_bridge.h
@@ -180,7 +180,7 @@ // Callback method for when HistoryService query results are ready with the // most recently-visited sites. - void OnVisitedHistoryResults(history::QueryResults* results); + void OnVisitedHistoryResults(history::QueryResults results); // Creates a HistoryItem* for the given tab entry. Caller takes ownership of // the result and must delete it when finished.
diff --git a/chrome/browser/ui/cocoa/history_menu_bridge.mm b/chrome/browser/ui/cocoa/history_menu_bridge.mm index 5bd546b..9236e69 100644 --- a/chrome/browser/ui/cocoa/history_menu_bridge.mm +++ b/chrome/browser/ui/cocoa/history_menu_bridge.mm
@@ -338,10 +338,9 @@ options.SetRecentDayRange(kVisitedScope); history_service_->QueryHistory( - base::string16(), - options, - base::Bind(&HistoryMenuBridge::OnVisitedHistoryResults, - base::Unretained(this)), + base::string16(), options, + base::BindOnce(&HistoryMenuBridge::OnVisitedHistoryResults, + base::Unretained(this)), &cancelable_task_tracker_); } @@ -351,15 +350,14 @@ CreateMenu(); } -void HistoryMenuBridge::OnVisitedHistoryResults( - history::QueryResults* results) { +void HistoryMenuBridge::OnVisitedHistoryResults(history::QueryResults results) { NSMenu* menu = HistoryMenu(); ClearMenuSection(menu, kVisited); NSInteger top_item = [menu indexOfItemWithTag:kVisitedTitle] + 1; - size_t count = results->size(); + size_t count = results.size(); for (size_t i = 0; i < count; ++i) { - const history::URLResult& result = (*results)[i]; + const history::URLResult& result = results[i]; HistoryItem* item = new HistoryItem; item->title = result.title();
diff --git a/chrome/browser/ui/webui/chromeos/insession_password_change_handler_chromeos.cc b/chrome/browser/ui/webui/chromeos/insession_password_change_handler_chromeos.cc index 01fcd680..6ff7c112 100644 --- a/chrome/browser/ui/webui/chromeos/insession_password_change_handler_chromeos.cc +++ b/chrome/browser/ui/webui/chromeos/insession_password_change_handler_chromeos.cc
@@ -6,49 +6,23 @@ #include <string> -#include "base/command_line.h" #include "base/logging.h" #include "base/macros.h" #include "base/values.h" #include "chrome/browser/chromeos/login/auth/chrome_cryptohome_authenticator.h" #include "chrome/browser/chromeos/login/saml/saml_password_expiry_notification.h" -#include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/pref_names.h" -#include "chromeos/constants/chromeos_switches.h" #include "chromeos/login/auth/saml_password_attributes.h" #include "components/prefs/pref_service.h" #include "components/user_manager/user_manager.h" namespace chromeos { -namespace { - -std::string GetPasswordChangeUrl(Profile* profile) { - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kSamlPasswordChangeUrl)) { - return base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( - switches::kSamlPasswordChangeUrl); - } - - const policy::UserCloudPolicyManagerChromeOS* user_cloud_policy_manager = - profile->GetUserCloudPolicyManagerChromeOS(); - if (user_cloud_policy_manager) { - const enterprise_management::PolicyData* policy = - user_cloud_policy_manager->core()->store()->policy(); - if (policy->has_change_password_uri()) { - return policy->change_password_uri(); - } - } - - return SamlPasswordAttributes::LoadFromPrefs(profile->GetPrefs()) - .password_change_url(); -} - -} // namespace - -InSessionPasswordChangeHandler::InSessionPasswordChangeHandler() = default; +InSessionPasswordChangeHandler::InSessionPasswordChangeHandler( + const std::string& password_change_url) + : password_change_url_(password_change_url) {} InSessionPasswordChangeHandler::~InSessionPasswordChangeHandler() = default; void InSessionPasswordChangeHandler::HandleInitialize( @@ -59,12 +33,11 @@ AllowJavascript(); base::Value params(base::Value::Type::DICTIONARY); - const std::string password_change_url = GetPasswordChangeUrl(profile); - if (password_change_url.empty()) { + if (password_change_url_.empty()) { LOG(ERROR) << "Password change url is empty"; return; } - params.SetKey("passwordChangeUrl", base::Value(password_change_url)); + params.SetKey("passwordChangeUrl", base::Value(password_change_url_)); const user_manager::User* user = ProfileHelper::Get()->GetUserByProfile(profile); if (user)
diff --git a/chrome/browser/ui/webui/chromeos/insession_password_change_handler_chromeos.h b/chrome/browser/ui/webui/chromeos/insession_password_change_handler_chromeos.h index aed2376..97eb55e 100644 --- a/chrome/browser/ui/webui/chromeos/insession_password_change_handler_chromeos.h +++ b/chrome/browser/ui/webui/chromeos/insession_password_change_handler_chromeos.h
@@ -16,7 +16,8 @@ class InSessionPasswordChangeHandler : public content::WebUIMessageHandler, AuthStatusConsumer { public: - InSessionPasswordChangeHandler(); + explicit InSessionPasswordChangeHandler( + const std::string& password_change_url); ~InSessionPasswordChangeHandler() override; // content::WebUIMessageHandler: @@ -30,6 +31,7 @@ void OnAuthSuccess(const UserContext& user_context) override; private: + const std::string password_change_url_; scoped_refptr<CryptohomeAuthenticator> authenticator_; base::WeakPtrFactory<InSessionPasswordChangeHandler> weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(InSessionPasswordChangeHandler);
diff --git a/chrome/browser/ui/webui/chromeos/insession_password_change_ui.cc b/chrome/browser/ui/webui/chromeos/insession_password_change_ui.cc index 648280c..76cc7570 100644 --- a/chrome/browser/ui/webui/chromeos/insession_password_change_ui.cc +++ b/chrome/browser/ui/webui/chromeos/insession_password_change_ui.cc
@@ -7,15 +7,22 @@ #include <memory> #include "base/bind.h" +#include "base/command_line.h" +#include "base/strings/utf_string_conversions.h" +#include "chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/chromeos/insession_password_change_handler_chromeos.h" #include "chrome/common/pref_names.h" #include "chrome/common/webui_url_constants.h" #include "chrome/grit/browser_resources.h" #include "chrome/grit/generated_resources.h" +#include "chromeos/constants/chromeos_switches.h" +#include "chromeos/login/auth/saml_password_attributes.h" #include "components/prefs/pref_service.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_ui_data_source.h" +#include "net/base/url_util.h" +#include "ui/base/l10n/l10n_util.h" #include "ui/display/display.h" #include "ui/display/screen.h" #include "ui/strings/grit/ui_strings.h" @@ -26,6 +33,35 @@ PasswordChangeDialog* g_dialog = nullptr; +std::string GetPasswordChangeUrl(Profile* profile) { + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kSamlPasswordChangeUrl)) { + return base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + switches::kSamlPasswordChangeUrl); + } + + const policy::UserCloudPolicyManagerChromeOS* user_cloud_policy_manager = + profile->GetUserCloudPolicyManagerChromeOS(); + if (user_cloud_policy_manager) { + const enterprise_management::PolicyData* policy = + user_cloud_policy_manager->core()->store()->policy(); + if (policy->has_change_password_uri()) { + return policy->change_password_uri(); + } + } + + return SamlPasswordAttributes::LoadFromPrefs(profile->GetPrefs()) + .password_change_url(); +} + +base::string16 GetManagementNotice(Profile* profile) { + base::string16 host = base::UTF8ToUTF16( + net::GetHostAndOptionalPort(GURL(GetPasswordChangeUrl(profile)))); + DCHECK(!host.empty()); + return l10n_util::GetStringFUTF16(IDS_LOGIN_SAML_PASSWORD_CHANGE_NOTICE, + host); +} + constexpr int kMaxDialogWidth = 768; constexpr int kMaxDialogHeight = 640; @@ -48,9 +84,9 @@ } // namespace -PasswordChangeDialog::PasswordChangeDialog() - : SystemWebDialogDelegate(GURL(chrome::kChromeUIPasswordChangeUrl), - base::string16()) {} +PasswordChangeDialog::PasswordChangeDialog(const base::string16& title) + : SystemWebDialogDelegate(GURL(chrome::kChromeUIPasswordChangeUrl), title) { +} PasswordChangeDialog::~PasswordChangeDialog() { DCHECK_EQ(this, g_dialog); @@ -61,13 +97,13 @@ *size = GetPasswordChangeDialogSize(); } -void PasswordChangeDialog::Show() { +void PasswordChangeDialog::Show(Profile* profile) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); if (g_dialog) { g_dialog->Focus(); return; } - g_dialog = new PasswordChangeDialog(); + g_dialog = new PasswordChangeDialog(GetManagementNotice(profile)); g_dialog->ShowSystemDialog(); } @@ -79,7 +115,8 @@ content::WebUIDataSource* source = content::WebUIDataSource::Create(chrome::kChromeUIPasswordChangeHost); - web_ui->AddMessageHandler(std::make_unique<InSessionPasswordChangeHandler>()); + web_ui->AddMessageHandler(std::make_unique<InSessionPasswordChangeHandler>( + GetPasswordChangeUrl(profile))); source->SetJsonPath("strings.js");
diff --git a/chrome/browser/ui/webui/chromeos/insession_password_change_ui.h b/chrome/browser/ui/webui/chromeos/insession_password_change_ui.h index 704b3de..32007ce 100644 --- a/chrome/browser/ui/webui/chromeos/insession_password_change_ui.h +++ b/chrome/browser/ui/webui/chromeos/insession_password_change_ui.h
@@ -6,17 +6,20 @@ #define CHROME_BROWSER_UI_WEBUI_CHROMEOS_INSESSION_PASSWORD_CHANGE_UI_H_ #include "base/macros.h" +#include "base/strings/string16.h" #include "chrome/browser/ui/webui/chromeos/system_web_dialog_delegate.h" #include "ui/web_dialogs/web_dialog_ui.h" +class Profile; + namespace chromeos { class PasswordChangeDialog : public SystemWebDialogDelegate { public: - static void Show(); + static void Show(Profile* profile); protected: - PasswordChangeDialog(); + explicit PasswordChangeDialog(const base::string16& title); ~PasswordChangeDialog() override; // ui::WebDialogDelegate:
diff --git a/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc b/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc index c70df91..7d19304d 100644 --- a/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc +++ b/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc
@@ -316,7 +316,7 @@ } std::string RefCountedMemoryToString( - const scoped_refptr<base::RefCountedMemory>& memory) { + scoped_refptr<base::RefCountedMemory> memory) { return std::string(memory->front_as<char>(), memory->size()); }
diff --git a/chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc b/chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc index 628f99e..e0d6a90 100644 --- a/chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc +++ b/chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc
@@ -113,7 +113,7 @@ } // Callback that stores a PDF file on disk. -void PrintToPdfCallback(const scoped_refptr<base::RefCountedMemory>& data, +void PrintToPdfCallback(scoped_refptr<base::RefCountedMemory> data, const base::FilePath& path, const base::Closure& pdf_file_saved_closure) { base::File file(path,
diff --git a/chrome/browser/upgrade_detector/upgrade_detector_chromeos.cc b/chrome/browser/upgrade_detector/upgrade_detector_chromeos.cc index 759fc4b..53148f2 100644 --- a/chrome/browser/upgrade_detector/upgrade_detector_chromeos.cc +++ b/chrome/browser/upgrade_detector/upgrade_detector_chromeos.cc
@@ -9,6 +9,7 @@ #include <utility> #include "base/bind.h" +#include "base/location.h" #include "base/logging.h" #include "base/macros.h" #include "base/metrics/histogram_macros.h" @@ -16,10 +17,13 @@ #include "base/time/clock.h" #include "base/time/default_clock.h" #include "base/time/default_tick_clock.h" +#include "base/time/time.h" +#include "chrome/browser/browser_process.h" #include "chrome/common/pref_names.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/update_engine_client.h" #include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" using chromeos::DBusThreadManager; using chromeos::UpdateEngineClient; @@ -35,15 +39,13 @@ // upgrade is detected. constexpr base::TimeDelta kDefaultHighThreshold = base::TimeDelta::FromDays(4); -// The scale factor to determine the elevated annoyance level from the high -// annoyance level's threshold. The elevated level always hits half-way to the -// high level. -constexpr double kElevatedScaleFactor = 0.5; - // The default amount of time between the detector's annoyance level change // from UPGRADE_ANNOYANCE_ELEVATED to UPGRADE_ANNOYANCE_HIGH in ms. constexpr int kDefaultHeadsUpPeriodMs = 24 * 60 * 60 * 1000; // 1 day. +constexpr base::TimeDelta kDefaultHeadsUpPeriod = + base::TimeDelta::FromMilliseconds(kDefaultHeadsUpPeriodMs); + // The reason of the rollback used in the UpgradeDetector.RollbackReason // histogram. enum class RollbackReason { @@ -113,10 +115,22 @@ const base::Clock* clock, const base::TickClock* tick_clock) : UpgradeDetector(clock, tick_clock), - high_threshold_(DetermineHighThreshold()), upgrade_notification_timer_(tick_clock), initialized_(false), - weak_factory_(this) {} + weak_factory_(this) { + CalculateThresholds(); + // Not all tests provide a PrefService for local_state(). + PrefService* local_state = g_browser_process->local_state(); + if (local_state) { + pref_change_registrar_.Init(local_state); + // base::Unretained is safe here because |this| outlives the registrar. + pref_change_registrar_.Add( + prefs::kRelaunchHeadsUpPeriod, + base::BindRepeating( + &UpgradeDetectorChromeos::OnRelaunchHeadsUpPeriodPrefChanged, + base::Unretained(this))); + } +} UpgradeDetectorChromeos::~UpgradeDetectorChromeos() {} @@ -143,7 +157,7 @@ } base::TimeDelta UpgradeDetectorChromeos::GetHighAnnoyanceLevelDelta() { - return high_threshold_ - (high_threshold_ * kElevatedScaleFactor); + return high_threshold_ - elevated_threshold_; } base::Time UpgradeDetectorChromeos::GetHighAnnoyanceDeadline() { @@ -154,15 +168,48 @@ } // static -base::TimeDelta UpgradeDetectorChromeos::DetermineHighThreshold() { - base::TimeDelta custom = GetRelaunchNotificationPeriod(); - return custom.is_zero() ? kDefaultHighThreshold : custom; +base::TimeDelta UpgradeDetectorChromeos::GetRelaunchHeadsUpPeriod() { + // Not all tests provide a PrefService for local_state(). + auto* local_state = g_browser_process->local_state(); + if (!local_state) + return base::TimeDelta(); + const auto* preference = + local_state->FindPreference(prefs::kRelaunchHeadsUpPeriod); + const int value = preference->GetValue()->GetInt(); + // Enforce the preference's documented minimum value. + static constexpr base::TimeDelta kMinValue = base::TimeDelta::FromHours(1); + if (preference->IsDefaultValue() || value < kMinValue.InMilliseconds()) + return base::TimeDelta(); + return base::TimeDelta::FromMilliseconds(value); +} + +void UpgradeDetectorChromeos::CalculateThresholds() { + base::TimeDelta notification_period = GetRelaunchNotificationPeriod(); + high_threshold_ = notification_period.is_zero() ? kDefaultHighThreshold + : notification_period; + base::TimeDelta heads_up_period = GetRelaunchHeadsUpPeriod(); + if (heads_up_period.is_zero()) + heads_up_period = kDefaultHeadsUpPeriod; + elevated_threshold_ = + high_threshold_ - std::min(heads_up_period, high_threshold_); +} + +void UpgradeDetectorChromeos::OnRelaunchHeadsUpPeriodPrefChanged() { + // Run OnThresholdPrefChanged using SequencedTaskRunner to avoid double + // NotifyUpgrade calls in case two polices are changed at one moment. + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(&UpgradeDetectorChromeos::OnThresholdPrefChanged, + weak_factory_.GetWeakPtr())); } void UpgradeDetectorChromeos::OnRelaunchNotificationPeriodPrefChanged() { - high_threshold_ = DetermineHighThreshold(); - if (!upgrade_detected_time().is_null()) - NotifyOnUpgrade(); + // Run OnThresholdPrefChanged using SequencedTaskRunner to avoid double + // NotifyUpgrade calls in case two polices are changed at one moment. + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(&UpgradeDetectorChromeos::OnThresholdPrefChanged, + weak_factory_.GetWeakPtr())); } void UpgradeDetectorChromeos::UpdateStatusChanged( @@ -196,24 +243,37 @@ NotifyUpdateOverCellularOneTimePermissionGranted(); } +void UpgradeDetectorChromeos::OnThresholdPrefChanged() { + // Check the current stage and potentially notify observers now if a change to + // the observed policies results in changes to the thresholds. + const base::TimeDelta old_elevated_threshold = elevated_threshold_; + const base::TimeDelta old_high_threshold = high_threshold_; + CalculateThresholds(); + if (!upgrade_detected_time().is_null() && + (elevated_threshold_ != old_elevated_threshold || + high_threshold_ != old_high_threshold)) { + NotifyOnUpgrade(); + } +} + void UpgradeDetectorChromeos::NotifyOnUpgrade() { - const base::TimeDelta elevated_threshold = - high_threshold_ * kElevatedScaleFactor; - base::TimeDelta delta = clock()->Now() - upgrade_detected_time(); + const base::TimeDelta delta = clock()->Now() - upgrade_detected_time(); // The delay from now until the next highest notification stage is reached, or // zero if the highest notification stage has been reached. base::TimeDelta next_delay; + const auto last_stage = upgrade_notification_stage(); // These if statements must be sorted (highest interval first). if (delta >= high_threshold_) { set_upgrade_notification_stage(UPGRADE_ANNOYANCE_HIGH); - } else if (delta >= elevated_threshold) { + } else if (delta >= elevated_threshold_) { set_upgrade_notification_stage(UPGRADE_ANNOYANCE_ELEVATED); next_delay = high_threshold_ - delta; } else { - set_upgrade_notification_stage(UPGRADE_ANNOYANCE_LOW); - next_delay = elevated_threshold - delta; + set_upgrade_notification_stage(UPGRADE_ANNOYANCE_NONE); + next_delay = elevated_threshold_ - delta; } + const auto new_stage = upgrade_notification_stage(); if (!next_delay.is_zero()) { // Schedule the next wakeup in 20 minutes or when the next change to the @@ -228,7 +288,12 @@ upgrade_notification_timer_.Stop(); } - NotifyUpgrade(); + // Issue a notification if the stage is above "none" or if it's dropped down + // to "none" from something higher. + if (new_stage != UPGRADE_ANNOYANCE_NONE || + last_stage != UPGRADE_ANNOYANCE_NONE) { + NotifyUpgrade(); + } } void UpgradeDetectorChromeos::OnChannelsReceived(std::string current_channel,
diff --git a/chrome/browser/upgrade_detector/upgrade_detector_chromeos.h b/chrome/browser/upgrade_detector/upgrade_detector_chromeos.h index 7eb3c196..e2e9885a 100644 --- a/chrome/browser/upgrade_detector/upgrade_detector_chromeos.h +++ b/chrome/browser/upgrade_detector/upgrade_detector_chromeos.h
@@ -10,6 +10,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/time/time.h" #include "base/timer/timer.h" #include "chrome/browser/upgrade_detector/upgrade_detector.h" #include "chromeos/dbus/update_engine_client.h" @@ -51,6 +52,18 @@ private: friend class base::NoDestructor<UpgradeDetectorChromeos>; + // Returns the period between first notification and Recommended / Required + // deadline specified via the RelaunchHeadsUpPeriod policy setting, or a + // zero delta if unset or out of range. + static base::TimeDelta GetRelaunchHeadsUpPeriod(); + + // Calculates |elevated_threshold_| and |high_threshold_|. + void CalculateThresholds(); + + // Handles a change to the browser.relaunch_heads_up_period Local State + // preference. Calls NotifyUpgrade if an upgrade is available. + void OnRelaunchHeadsUpPeriodPrefChanged(); + // Returns the threshold to reach high annoyance level. static base::TimeDelta DetermineHighThreshold(); @@ -62,6 +75,9 @@ const chromeos::UpdateEngineClient::Status& status) override; void OnUpdateOverCellularOneTimePermissionGranted() override; + // Triggers NotifyOnUpgrade if thresholds have been changed. + void OnThresholdPrefChanged(); + // The function that sends out a notification (after a certain time has // elapsed) that lets the rest of the UI know we should start notifying the // user that a new version is available. @@ -70,9 +86,16 @@ void OnChannelsReceived(std::string current_channel, std::string target_channel); + // The delta from upgrade detection until elevated annoyance level is reached. + base::TimeDelta elevated_threshold_; + // The delta from upgrade detection until high annoyance level is reached. base::TimeDelta high_threshold_; + // Observes changes to the browser.relaunch_heads_up_period Local State + // preference. + PrefChangeRegistrar pref_change_registrar_; + // A timer used to move through the various upgrade notification stages and // call UpgradeDetector::NotifyUpgrade. base::OneShotTimer upgrade_notification_timer_;
diff --git a/chrome/browser/upgrade_detector/upgrade_detector_chromeos_unittest.cc b/chrome/browser/upgrade_detector/upgrade_detector_chromeos_unittest.cc index c2665401..8c29afe 100644 --- a/chrome/browser/upgrade_detector/upgrade_detector_chromeos_unittest.cc +++ b/chrome/browser/upgrade_detector/upgrade_detector_chromeos_unittest.cc
@@ -11,6 +11,7 @@ #include "base/test/scoped_task_environment.h" #include "base/time/clock.h" #include "base/time/tick_clock.h" +#include "base/time/time.h" #include "base/values.h" #include "build/build_config.h" #include "chrome/browser/upgrade_detector/upgrade_observer.h" @@ -97,6 +98,34 @@ fake_update_engine_client_->NotifyObserversThatStatusChanged(status); } + // Sets the browser.relaunch_notification_period preference in Local State to + // |value|. + void SetNotificationPeriodPref(base::TimeDelta value) { + if (value.is_zero()) { + scoped_local_state_.Get()->RemoveManagedPref( + prefs::kRelaunchNotificationPeriod); + } else { + scoped_local_state_.Get()->SetManagedPref( + prefs::kRelaunchNotificationPeriod, + std::make_unique<base::Value>( + base::saturated_cast<int>(value.InMilliseconds()))); + } + } + + // Sets the browser.relaunch_heads_up_period preference in Local State to + // |value|. + void SetHeadsUpPeriodPref(base::TimeDelta value) { + if (value.is_zero()) { + scoped_local_state_.Get()->RemoveManagedPref( + prefs::kRelaunchHeadsUpPeriod); + } else { + scoped_local_state_.Get()->SetManagedPref( + prefs::kRelaunchHeadsUpPeriod, + std::make_unique<base::Value>( + base::saturated_cast<int>(value.InMilliseconds()))); + } + } + // Fast-forwards virtual time by |delta|. void FastForwardBy(base::TimeDelta delta) { scoped_task_environment_.FastForwardBy(delta); @@ -123,8 +152,9 @@ const auto deadline = upgrade_detector.GetHighAnnoyanceDeadline(); - // Another new version of ChromeOS is ready to install after a day. - FastForwardBy(base::TimeDelta::FromDays(1)); + // Another new version of ChromeOS is ready to install after high + // annoyance reached. + FastForwardBy(upgrade_detector.GetDefaultHighAnnoyanceThreshold()); ::testing::Mock::VerifyAndClear(&mock_observer); // New notification could be sent or not. EXPECT_CALL(mock_observer, OnUpgradeRecommended()) @@ -136,3 +166,196 @@ upgrade_detector.Shutdown(); RunUntilIdle(); } + +TEST_F(UpgradeDetectorChromeosTest, TestHeadsUpPeriod) { + TestUpgradeDetectorChromeos upgrade_detector(GetMockClock(), + GetMockTickClock()); + upgrade_detector.Init(); + ::testing::StrictMock<MockUpgradeObserver> mock_observer(&upgrade_detector); + + const auto notification_period = base::TimeDelta::FromDays(7); + const auto heads_up_period = base::TimeDelta::FromDays(1); + SetNotificationPeriodPref(notification_period); + SetHeadsUpPeriodPref(heads_up_period); + + const auto no_notification_till = + notification_period - heads_up_period - base::TimeDelta::FromMinutes(1); + const auto first_notification_at = notification_period - heads_up_period; + const auto second_notification_at = notification_period; + + // Observer should not get notifications about new version till 6-th day. + NotifyUpdateReadyToInstall(); + FastForwardBy(no_notification_till); + ::testing::Mock::VerifyAndClear(&mock_observer); + EXPECT_EQ(upgrade_detector.upgrade_notification_stage(), + UpgradeDetector::UPGRADE_ANNOYANCE_NONE); + + EXPECT_CALL(mock_observer, OnUpgradeRecommended()); + FastForwardBy(first_notification_at - no_notification_till); + ::testing::Mock::VerifyAndClear(&mock_observer); + EXPECT_EQ(upgrade_detector.upgrade_notification_stage(), + UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED); + + // UPGRADE_ANNOYANCE_HIGH at the end of the period. + EXPECT_CALL(mock_observer, OnUpgradeRecommended()) + .Times(testing::AnyNumber()); + FastForwardBy(second_notification_at - first_notification_at); + ::testing::Mock::VerifyAndClear(&mock_observer); + EXPECT_EQ(upgrade_detector.upgrade_notification_stage(), + UpgradeDetector::UPGRADE_ANNOYANCE_HIGH); + upgrade_detector.Shutdown(); + RunUntilIdle(); +} + +TEST_F(UpgradeDetectorChromeosTest, TestHeadsUpPeriodChange) { + TestUpgradeDetectorChromeos upgrade_detector(GetMockClock(), + GetMockTickClock()); + upgrade_detector.Init(); + ::testing::StrictMock<MockUpgradeObserver> mock_observer(&upgrade_detector); + + SetNotificationPeriodPref(base::TimeDelta::FromDays(7)); + SetHeadsUpPeriodPref(base::TimeDelta::FromDays(1)); + + // Observer should not get notifications about new version first 4 days. + NotifyUpdateReadyToInstall(); + FastForwardBy(base::TimeDelta::FromDays(4)); + RunUntilIdle(); + ::testing::Mock::VerifyAndClear(&mock_observer); + EXPECT_EQ(upgrade_detector.upgrade_notification_stage(), + UpgradeDetector::UPGRADE_ANNOYANCE_NONE); + + // Observer should get notifications because of HeadsUpPeriod change. + EXPECT_CALL(mock_observer, OnUpgradeRecommended()); + SetHeadsUpPeriodPref(base::TimeDelta::FromDays(3)); + RunUntilIdle(); + ::testing::Mock::VerifyAndClear(&mock_observer); + EXPECT_EQ(upgrade_detector.upgrade_notification_stage(), + UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED); + + // UPGRADE_ANNOYANCE_HIGH at the end of the period. + EXPECT_CALL(mock_observer, OnUpgradeRecommended()) + .Times(testing::AnyNumber()); + FastForwardBy(base::TimeDelta::FromDays(3)); + RunUntilIdle(); + ::testing::Mock::VerifyAndClear(&mock_observer); + EXPECT_EQ(upgrade_detector.upgrade_notification_stage(), + UpgradeDetector::UPGRADE_ANNOYANCE_HIGH); + upgrade_detector.Shutdown(); + RunUntilIdle(); +} + +TEST_F(UpgradeDetectorChromeosTest, TestHeadsUpPeriodNotificationPeriodChange) { + TestUpgradeDetectorChromeos upgrade_detector(GetMockClock(), + GetMockTickClock()); + upgrade_detector.Init(); + ::testing::StrictMock<MockUpgradeObserver> mock_observer(&upgrade_detector); + + SetNotificationPeriodPref(base::TimeDelta::FromDays(7)); + SetHeadsUpPeriodPref(base::TimeDelta::FromDays(1)); + + // Observer should not get notifications about new version first 4 days. + NotifyUpdateReadyToInstall(); + FastForwardBy(base::TimeDelta::FromDays(4)); + RunUntilIdle(); + ::testing::Mock::VerifyAndClear(&mock_observer); + EXPECT_EQ(upgrade_detector.upgrade_notification_stage(), + UpgradeDetector::UPGRADE_ANNOYANCE_NONE); + + // Observer should get notifications because of NotificationPeriod change. + EXPECT_CALL(mock_observer, OnUpgradeRecommended()); + SetNotificationPeriodPref(base::TimeDelta::FromDays(5)); + RunUntilIdle(); + ::testing::Mock::VerifyAndClear(&mock_observer); + EXPECT_EQ(upgrade_detector.upgrade_notification_stage(), + UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED); + + // UPGRADE_ANNOYANCE_HIGH at the end of the period. + EXPECT_CALL(mock_observer, OnUpgradeRecommended()) + .Times(testing::AnyNumber()); + FastForwardBy(base::TimeDelta::FromDays(3)); + RunUntilIdle(); + ::testing::Mock::VerifyAndClear(&mock_observer); + EXPECT_EQ(upgrade_detector.upgrade_notification_stage(), + UpgradeDetector::UPGRADE_ANNOYANCE_HIGH); + upgrade_detector.Shutdown(); + RunUntilIdle(); +} + +TEST_F(UpgradeDetectorChromeosTest, + TestHeadsUpPeriodOverflowNotificationPeriod) { + TestUpgradeDetectorChromeos upgrade_detector(GetMockClock(), + GetMockTickClock()); + upgrade_detector.Init(); + ::testing::StrictMock<MockUpgradeObserver> mock_observer(&upgrade_detector); + + SetNotificationPeriodPref(base::TimeDelta::FromDays(7)); + SetHeadsUpPeriodPref(base::TimeDelta::FromDays(8)); + + // Observer should get notification because HeadsUpPeriod bigger than + // NotificationPeriod. + EXPECT_CALL(mock_observer, OnUpgradeRecommended()); + NotifyUpdateReadyToInstall(); + RunUntilIdle(); + ::testing::Mock::VerifyAndClear(&mock_observer); + EXPECT_EQ(upgrade_detector.upgrade_notification_stage(), + UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED); + EXPECT_EQ(upgrade_detector.GetHighAnnoyanceLevelDelta(), + base::TimeDelta::FromDays(7)); + + // HighAnnoyanceLevelDelta becomes 8 days because period is increased. + EXPECT_CALL(mock_observer, OnUpgradeRecommended()); + SetNotificationPeriodPref(base::TimeDelta::FromDays(14)); + RunUntilIdle(); + ::testing::Mock::VerifyAndClear(&mock_observer); + EXPECT_EQ(upgrade_detector.upgrade_notification_stage(), + UpgradeDetector::UPGRADE_ANNOYANCE_NONE); + EXPECT_EQ(upgrade_detector.GetHighAnnoyanceLevelDelta(), + base::TimeDelta::FromDays(8)); + + // Bring NotificationPeriod back, HighAnnoyanceLevelDelta becomes 7 days. + EXPECT_CALL(mock_observer, OnUpgradeRecommended()); + SetNotificationPeriodPref(base::TimeDelta::FromDays(7)); + RunUntilIdle(); + ::testing::Mock::VerifyAndClear(&mock_observer); + EXPECT_EQ(upgrade_detector.upgrade_notification_stage(), + UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED); + EXPECT_EQ(upgrade_detector.GetHighAnnoyanceLevelDelta(), + base::TimeDelta::FromDays(7)); + + // UPGRADE_ANNOYANCE_HIGH at the end of the period. + EXPECT_CALL(mock_observer, OnUpgradeRecommended()) + .Times(testing::AnyNumber()); + FastForwardBy(base::TimeDelta::FromDays(7)); + ::testing::Mock::VerifyAndClear(&mock_observer); + EXPECT_EQ(upgrade_detector.upgrade_notification_stage(), + UpgradeDetector::UPGRADE_ANNOYANCE_HIGH); + upgrade_detector.Shutdown(); + RunUntilIdle(); +} + +TEST_F(UpgradeDetectorChromeosTest, OnUpgradeRecommendedCalledOnce) { + TestUpgradeDetectorChromeos upgrade_detector(GetMockClock(), + GetMockTickClock()); + upgrade_detector.Init(); + ::testing::StrictMock<MockUpgradeObserver> mock_observer(&upgrade_detector); + + SetNotificationPeriodPref(base::TimeDelta::FromDays(7)); + SetHeadsUpPeriodPref(base::TimeDelta::FromDays(7)); + + // Observer should get notification because HeadsUpPeriod is the same as + // NotificationPeriod. + EXPECT_CALL(mock_observer, OnUpgradeRecommended()); + NotifyUpdateReadyToInstall(); + RunUntilIdle(); + ::testing::Mock::VerifyAndClear(&mock_observer); + + // Both periods are changed but OnUpgradeRecommended called only once. + EXPECT_CALL(mock_observer, OnUpgradeRecommended()); + SetNotificationPeriodPref(base::TimeDelta::FromDays(8)); + SetHeadsUpPeriodPref(base::TimeDelta::FromDays(8)); + RunUntilIdle(); + ::testing::Mock::VerifyAndClear(&mock_observer); + + upgrade_detector.Shutdown(); + RunUntilIdle(); +}
diff --git a/chrome/common/extensions/api/autofill_private.idl b/chrome/common/extensions/api/autofill_private.idl index b41477f7..30242f2 100644 --- a/chrome/common/extensions/api/autofill_private.idl +++ b/chrome/common/extensions/api/autofill_private.idl
@@ -242,14 +242,9 @@ }; interface Events { - // Fired when the address list has changed, meaning that an entry has been - // added, removed, or changed. - // |entries| The updated list of entries. - static void onAddressListChanged(AddressEntry[] entries); - - // Fired when the credit card list has changed, meaning that an entry has + // Fired when the personal data has changed, meaning that an entry has // been added, removed, or changed. // |entries| The updated list of entries. - static void onCreditCardListChanged(CreditCardEntry[] entries); + static void onPersonalDataChanged(AddressEntry[] addressEntries, CreditCardEntry[] creditCardEntries); }; };
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 2e6cb58..42b2c78 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1969,6 +1969,8 @@ "../browser/chromeos/login/test/offline_gaia_test_mixin.h", "../browser/chromeos/login/test/oobe_base_test.cc", "../browser/chromeos/login/test/oobe_base_test.h", + "../browser/chromeos/login/test/oobe_screens_utils.cc", + "../browser/chromeos/login/test/oobe_screens_utils.h", "../browser/chromeos/login/test/oobe_window_visibility_waiter.cc", "../browser/chromeos/login/test/oobe_window_visibility_waiter.h", "../browser/chromeos/login/test/scoped_policy_update.cc",
diff --git a/chrome/test/base/ui_test_utils.cc b/chrome/test/base/ui_test_utils.cc index 36f377e73..746c8d1 100644 --- a/chrome/test/base/ui_test_utils.cc +++ b/chrome/test/base/ui_test_utils.cc
@@ -18,6 +18,7 @@ #include "base/memory/ref_counted.h" #include "base/path_service.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/bind_test_util.h" #include "base/test/test_timeouts.h" #include "base/threading/thread_restrictions.h" #include "base/time/time.h" @@ -478,30 +479,24 @@ } HistoryEnumerator::HistoryEnumerator(Profile* profile) { - scoped_refptr<content::MessageLoopRunner> message_loop_runner = - new content::MessageLoopRunner; + base::RunLoop run_loop; + base::CancelableTaskTracker tracker; - history::HistoryService* hs = HistoryServiceFactory::GetForProfile( - profile, ServiceAccessType::EXPLICIT_ACCESS); - hs->QueryHistory(base::string16(), - history::QueryOptions(), - base::Bind(&HistoryEnumerator::HistoryQueryComplete, - base::Unretained(this), - message_loop_runner->QuitClosure()), - &tracker_); - message_loop_runner->Run(); + HistoryServiceFactory::GetForProfile(profile, + ServiceAccessType::EXPLICIT_ACCESS) + ->QueryHistory( + base::string16(), history::QueryOptions(), + base::BindLambdaForTesting([&](history::QueryResults results) { + for (const auto& item : results) + urls_.push_back(item.url()); + run_loop.Quit(); + }), + &tracker); + run_loop.Run(); } HistoryEnumerator::~HistoryEnumerator() {} -void HistoryEnumerator::HistoryQueryComplete( - const base::Closure& quit_task, - history::QueryResults* results) { - for (size_t i = 0; i < results->size(); ++i) - urls_.push_back((*results)[i].url()); - quit_task.Run(); -} - // Wait for HistoryService to load. class WaitHistoryLoadedObserver : public history::HistoryServiceObserver { public:
diff --git a/chrome/test/base/ui_test_utils.h b/chrome/test/base/ui_test_utils.h index e01b1d19..3febc41 100644 --- a/chrome/test/base/ui_test_utils.h +++ b/chrome/test/base/ui_test_utils.h
@@ -309,14 +309,8 @@ std::vector<GURL>& urls() { return urls_; } private: - void HistoryQueryComplete( - const base::Closure& quit_task, - history::QueryResults* results); - std::vector<GURL> urls_; - base::CancelableTaskTracker tracker_; - DISALLOW_COPY_AND_ASSIGN(HistoryEnumerator); };
diff --git a/chrome/test/data/extensions/api_test/autofill_private/test.js b/chrome/test/data/extensions/api_test/autofill_private/test.js index d416d05..50ba8b3 100644 --- a/chrome/test/data/extensions/api_test/autofill_private/test.js +++ b/chrome/test/data/extensions/api_test/autofill_private/test.js
@@ -97,8 +97,8 @@ // Setup the callback that verifies that the address was correctly // added. chrome.test.listenOnce( - chrome.autofillPrivate.onAddressListChanged, - chrome.test.callbackPass(function(addressList) { + chrome.autofillPrivate.onPersonalDataChanged, + chrome.test.callbackPass(function(addressList, cardList) { chrome.test.assertEq( [{ fullNames: [NAME], @@ -154,8 +154,8 @@ // Setup the callback that verifies that the address was correctly // updated. chrome.test.listenOnce( - chrome.autofillPrivate.onAddressListChanged, - chrome.test.callbackPass(function(addressList) { + chrome.autofillPrivate.onPersonalDataChanged, + chrome.test.callbackPass(function(addressList, cardList) { chrome.test.assertEq( [{ guid: addressGuid, @@ -199,8 +199,8 @@ // Setup the callback that verifies that the card was correctly added. chrome.test.listenOnce( - chrome.autofillPrivate.onCreditCardListChanged, - chrome.test.callbackPass(function(cardList) { + chrome.autofillPrivate.onPersonalDataChanged, + chrome.test.callbackPass(function(addressList, cardList) { chrome.test.assertEq( [{ name: CARD_NAME, @@ -244,8 +244,8 @@ // Setup the callback that verifies that the address was correctly // updated. chrome.test.listenOnce( - chrome.autofillPrivate.onCreditCardListChanged, - chrome.test.callbackPass(function(cardList) { + chrome.autofillPrivate.onPersonalDataChanged, + chrome.test.callbackPass(function(addressList, cardList) { chrome.test.assertEq( [{ guid: cardGuid, @@ -289,7 +289,7 @@ } } - chrome.autofillPrivate.onCreditCardListChanged.addListener(handler); + chrome.autofillPrivate.onPersonalDataChanged.addListener(handler); chrome.autofillPrivate.getCreditCardList(handler); chrome.autofillPrivate.saveCreditCard({name: NAME}); },
diff --git a/chromecast/base/cast_features.cc b/chromecast/base/cast_features.cc index 9baa7a2..d71bcc2 100644 --- a/chromecast/base/cast_features.cc +++ b/chromecast/base/cast_features.cc
@@ -224,7 +224,6 @@ const std::string& feature_name = it.key(); auto* field_trial = base::FieldTrialList::FactoryGetFieldTrial( feature_name, k100PercentProbability, kDefaultDCSFeaturesGroup, - base::FieldTrialList::kNoExpirationYear, 1 /* month */, 1 /* day */, base::FieldTrial::SESSION_RANDOMIZED, nullptr); bool enabled;
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index fd4b667..6ecc39c5 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -12233.0.0 \ No newline at end of file +12234.0.0 \ No newline at end of file
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc index 4575b9b..2aaff6b9 100644 --- a/chromeos/constants/chromeos_features.cc +++ b/chromeos/constants/chromeos_features.cc
@@ -131,6 +131,11 @@ const base::Feature kUserActivityPrediction{"UserActivityPrediction", base::FEATURE_ENABLED_BY_DEFAULT}; +// Remap search+click to right click instead of the legacy alt+click on +// Chrome OS. +const base::Feature kUseSearchClickForRightClick{ + "UseSearchClickForRightClick", base::FEATURE_DISABLED_BY_DEFAULT}; + // Enable or disable native controls in video player on Chrome OS. const base::Feature kVideoPlayerNativeControls{ "VideoPlayerNativeControls", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chromeos/constants/chromeos_features.h b/chromeos/constants/chromeos_features.h index 6f582f2a8..c7fc8094 100644 --- a/chromeos/constants/chromeos_features.h +++ b/chromeos/constants/chromeos_features.h
@@ -64,6 +64,8 @@ COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kUserActivityPrediction; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) +extern const base::Feature kUseSearchClickForRightClick; +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kVideoPlayerNativeControls; // Keep alphabetized.
diff --git a/chromeos/dbus/kerberos/fake_kerberos_client.cc b/chromeos/dbus/kerberos/fake_kerberos_client.cc index 6d50e06..10e8bfc 100644 --- a/chromeos/dbus/kerberos/fake_kerberos_client.cc +++ b/chromeos/dbus/kerberos/fake_kerberos_client.cc
@@ -69,6 +69,13 @@ PostResponse(std::move(callback), error); } +void FakeKerberosClient::ClearAccounts( + const kerberos::ClearAccountsRequest& request, + ClearAccountsCallback callback) { + accounts_.clear(); + PostResponse(std::move(callback), kerberos::ERROR_NONE); +} + void FakeKerberosClient::ListAccounts( const kerberos::ListAccountsRequest& request, ListAccountsCallback callback) {
diff --git a/chromeos/dbus/kerberos/fake_kerberos_client.h b/chromeos/dbus/kerberos/fake_kerberos_client.h index 561447c..5d199fb 100644 --- a/chromeos/dbus/kerberos/fake_kerberos_client.h +++ b/chromeos/dbus/kerberos/fake_kerberos_client.h
@@ -26,6 +26,8 @@ AddAccountCallback callback) override; void RemoveAccount(const kerberos::RemoveAccountRequest& request, RemoveAccountCallback callback) override; + void ClearAccounts(const kerberos::ClearAccountsRequest& request, + ClearAccountsCallback callback) override; void ListAccounts(const kerberos::ListAccountsRequest& request, ListAccountsCallback callback) override; void SetConfig(const kerberos::SetConfigRequest& request,
diff --git a/chromeos/dbus/kerberos/kerberos_client.cc b/chromeos/dbus/kerberos/kerberos_client.cc index ed8376d..1a808be 100644 --- a/chromeos/dbus/kerberos/kerberos_client.cc +++ b/chromeos/dbus/kerberos/kerberos_client.cc
@@ -58,6 +58,12 @@ std::move(callback)); } + void ClearAccounts(const kerberos::ClearAccountsRequest& request, + ClearAccountsCallback callback) override { + CallProtoMethod(kerberos::kClearAccountsMethod, request, + std::move(callback)); + } + void ListAccounts(const kerberos::ListAccountsRequest& request, ListAccountsCallback callback) override { CallProtoMethod(kerberos::kListAccountsMethod, request,
diff --git a/chromeos/dbus/kerberos/kerberos_client.h b/chromeos/dbus/kerberos/kerberos_client.h index 9592727..c30e454 100644 --- a/chromeos/dbus/kerberos/kerberos_client.h +++ b/chromeos/dbus/kerberos/kerberos_client.h
@@ -26,6 +26,8 @@ base::OnceCallback<void(const kerberos::AddAccountResponse& response)>; using RemoveAccountCallback = base::OnceCallback<void(const kerberos::RemoveAccountResponse& response)>; + using ClearAccountsCallback = + base::OnceCallback<void(const kerberos::ClearAccountsResponse& response)>; using ListAccountsCallback = base::OnceCallback<void(const kerberos::ListAccountsResponse& response)>; using SetConfigCallback = @@ -68,6 +70,9 @@ virtual void RemoveAccount(const kerberos::RemoveAccountRequest& request, RemoveAccountCallback callback) = 0; + virtual void ClearAccounts(const kerberos::ClearAccountsRequest& request, + ClearAccountsCallback callback) = 0; + virtual void ListAccounts(const kerberos::ListAccountsRequest& request, ListAccountsCallback callback) = 0;
diff --git a/chromeos/services/multidevice_setup/public/cpp/first_run_field_trial.cc b/chromeos/services/multidevice_setup/public/cpp/first_run_field_trial.cc index cede6ab..d215c733 100644 --- a/chromeos/services/multidevice_setup/public/cpp/first_run_field_trial.cc +++ b/chromeos/services/multidevice_setup/public/cpp/first_run_field_trial.cc
@@ -44,9 +44,7 @@ scoped_refptr<base::FieldTrial> trial( base::FieldTrialList::FactoryGetFieldTrial( kInstantTetheringTrialName, 100 /* total_probability */, - kInstantTetheringGroupName, base::FieldTrialList::kNoExpirationYear, - 1 /* month */, 1 /* day_of_month */, - base::FieldTrial::ONE_TIME_RANDOMIZED, + kInstantTetheringGroupName, base::FieldTrial::ONE_TIME_RANDOMIZED, nullptr /* default_group_number */)); feature_list->RegisterFieldTrialOverride( features::kInstantTethering.name,
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc index df9e83ea..d4390cb 100644 --- a/components/autofill/core/browser/personal_data_manager.cc +++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -1168,17 +1168,22 @@ &unique_matched_profiles); std::unique_ptr<LabelFormatter> formatter; + bool use_formatter; #if !defined(OS_ANDROID) && !defined(OS_IOS) - bool use_improved_label_disambiguation = base::FeatureList::IsEnabled( + use_formatter = base::FeatureList::IsEnabled( autofill::features::kAutofillUseImprovedLabelDisambiguation); +#else + use_formatter = base::FeatureList::IsEnabled( + autofill::features::kAutofillUseMobileLabelDisambiguation); +#endif // !defined(OS_ANDROID) && !defined(OS_IOS) + // The formatter stores a constant reference to |unique_matched_profiles|. // This is safe since the formatter is destroyed when this function returns. - formatter = use_improved_label_disambiguation + formatter = use_formatter ? LabelFormatter::Create(unique_matched_profiles, app_locale_, type.GetStorableType(), field_types) : nullptr; -#endif // !defined(OS_ANDROID) && !defined(OS_IOS) // Generate disambiguating labels based on the list of matches. std::vector<base::string16> labels; @@ -1190,12 +1195,10 @@ app_locale_, &labels); } -#if !defined(OS_ANDROID) && !defined(OS_IOS) - if (use_improved_label_disambiguation && !unique_suggestions.empty()) { + if (use_formatter && !unique_suggestions.empty()) { AutofillMetrics::LogProfileSuggestionsMadeWithFormatter(formatter != nullptr); } -#endif // #if !defined(OS_ANDROID) && !defined(OS_IOS) suggestion_selection::PrepareSuggestions(formatter != nullptr, labels, &unique_suggestions, comparator);
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc index 41e19dd..89858208 100644 --- a/components/autofill/core/browser/personal_data_manager_unittest.cc +++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -2836,6 +2836,164 @@ } #endif // #if !defined(OS_ANDROID) && !defined(OS_IOS) +#if defined(OS_ANDROID) || defined(OS_IOS) +TEST_F(PersonalDataManagerTest, GetProfileSuggestions_MobileShowOne) { + std::map<std::string, std::string> parameters; + parameters[features::kAutofillUseMobileLabelDisambiguationParameterName] = + features::kAutofillUseMobileLabelDisambiguationParameterShowOne; + base::test::ScopedFeatureList scoped_features; + scoped_features.InitAndEnableFeatureWithParameters( + features::kAutofillUseMobileLabelDisambiguation, parameters); + + AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin); + test::SetProfileInfo(&profile1, "Hoa", "", "Pham", "hoa.pham@comcast.net", "", + "401 Merrimack St", "", "Lowell", "MA", "01852", "US", + "19786744120"); + AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin); + test::SetProfileInfo(&profile2, "María", "", "Lòpez", "maria@aol.com", "", + "11 Elkins St", "", "Boston", "MA", "02127", "US", + "6172686862"); + + // The profiles' use dates and counts are set make this test deterministic. + // The suggestion created with data from profile1 should be ranked higher + // than profile2's associated suggestion. This ensures that profile1's + // suggestion is the first element in the collection returned by + // GetProfileSuggestions. + profile1.set_use_date(AutofillClock::Now()); + profile1.set_use_count(10); + profile2.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(10)); + profile2.set_use_count(1); + + AddProfileToPersonalDataManager(profile1); + AddProfileToPersonalDataManager(profile2); + + // Tests a form with name, email address, and phone number fields. + EXPECT_THAT( + personal_data_->GetProfileSuggestions( + AutofillType(EMAIL_ADDRESS), base::string16(), false, + std::vector<ServerFieldType>{NAME_FIRST, NAME_LAST, EMAIL_ADDRESS, + PHONE_HOME_WHOLE_NUMBER}), + ElementsAre(AllOf(testing::Field(&Suggestion::label, + base::ASCIIToUTF16("(978) 674-4120")), + testing::Field(&Suggestion::additional_label, + base::ASCIIToUTF16("(978) 674-4120")), + testing::Field(&Suggestion::icon, "")), + AllOf(testing::Field(&Suggestion::label, + base::ASCIIToUTF16("(617) 268-6862")), + testing::Field(&Suggestion::additional_label, + base::ASCIIToUTF16("(617) 268-6862")), + testing::Field(&Suggestion::icon, "")))); + + // Tests a form with name, address, phone number, and email address fields. + EXPECT_THAT( + personal_data_->GetProfileSuggestions( + AutofillType(EMAIL_ADDRESS), base::string16(), false, + std::vector<ServerFieldType>{NAME_FULL, ADDRESS_HOME_STREET_ADDRESS, + ADDRESS_HOME_CITY, EMAIL_ADDRESS, + PHONE_HOME_WHOLE_NUMBER}), + ElementsAre(AllOf(testing::Field(&Suggestion::label, + base::ASCIIToUTF16("401 Merrimack St")), + testing::Field(&Suggestion::additional_label, + base::ASCIIToUTF16("401 Merrimack St")), + testing::Field(&Suggestion::icon, "")), + AllOf(testing::Field(&Suggestion::label, + base::ASCIIToUTF16("11 Elkins St")), + testing::Field(&Suggestion::additional_label, + base::ASCIIToUTF16("11 Elkins St")), + testing::Field(&Suggestion::icon, "")))); +} +#endif // if defined(OS_ANDROID) || defined(OS_IOS) + +#if defined(OS_ANDROID) || defined(OS_IOS) +TEST_F(PersonalDataManagerTest, GetProfileSuggestions_MobileShowAll) { + std::map<std::string, std::string> parameters; + parameters[features::kAutofillUseMobileLabelDisambiguationParameterName] = + features::kAutofillUseMobileLabelDisambiguationParameterShowAll; + base::test::ScopedFeatureList scoped_features; + scoped_features.InitAndEnableFeatureWithParameters( + features::kAutofillUseMobileLabelDisambiguation, parameters); + + AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin); + test::SetProfileInfo(&profile1, "Hoa", "", "Pham", "hoa.pham@comcast.net", "", + "401 Merrimack St", "", "Lowell", "MA", "01852", "US", + "19786744120"); + AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin); + test::SetProfileInfo(&profile2, "María", "", "Lòpez", "maria@aol.com", "", + "11 Elkins St", "", "Boston", "MA", "02127", "US", + "6172686862"); + + // The profiles' use dates and counts are set make this test deterministic. + // The suggestion created with data from profile1 should be ranked higher + // than profile2's associated suggestion. This ensures that profile1's + // suggestion is the first element in the collection returned by + // GetProfileSuggestions. + profile1.set_use_date(AutofillClock::Now()); + profile1.set_use_count(10); + profile2.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(10)); + profile2.set_use_count(1); + + AddProfileToPersonalDataManager(profile1); + AddProfileToPersonalDataManager(profile2); + + // Tests a form with name, email address, and phone number fields. + EXPECT_THAT( + personal_data_->GetProfileSuggestions( + AutofillType(EMAIL_ADDRESS), base::string16(), false, + std::vector<ServerFieldType>{NAME_FIRST, NAME_LAST, EMAIL_ADDRESS, + PHONE_HOME_WHOLE_NUMBER}), + ElementsAre( + AllOf(testing::Field(&Suggestion::label, + ConstructMobileLabelLine( + {base::ASCIIToUTF16("Hoa"), + base::ASCIIToUTF16("(978) 674-4120")})), + testing::Field(&Suggestion::additional_label, + ConstructMobileLabelLine( + {base::ASCIIToUTF16("Hoa"), + base::ASCIIToUTF16("(978) 674-4120")})), + testing::Field(&Suggestion::icon, "")), + AllOf(testing::Field(&Suggestion::label, + ConstructMobileLabelLine( + {base::UTF8ToUTF16("María"), + base::ASCIIToUTF16("(617) 268-6862")})), + testing::Field(&Suggestion::additional_label, + ConstructMobileLabelLine( + {base::UTF8ToUTF16("María"), + base::ASCIIToUTF16("(617) 268-6862")})), + testing::Field(&Suggestion::icon, "")))); + + // Tests a form with name, address, phone number, and email address fields. + EXPECT_THAT( + personal_data_->GetProfileSuggestions( + AutofillType(EMAIL_ADDRESS), base::string16(), false, + std::vector<ServerFieldType>{NAME_FULL, ADDRESS_HOME_STREET_ADDRESS, + ADDRESS_HOME_CITY, EMAIL_ADDRESS, + PHONE_HOME_WHOLE_NUMBER}), + ElementsAre( + AllOf(testing::Field(&Suggestion::label, + ConstructMobileLabelLine( + {base::ASCIIToUTF16("Hoa Pham"), + base::ASCIIToUTF16("401 Merrimack St"), + base::ASCIIToUTF16("(978) 674-4120")})), + testing::Field(&Suggestion::additional_label, + ConstructMobileLabelLine( + {base::ASCIIToUTF16("Hoa Pham"), + base::ASCIIToUTF16("401 Merrimack St"), + base::ASCIIToUTF16("(978) 674-4120")})), + testing::Field(&Suggestion::icon, "")), + AllOf(testing::Field(&Suggestion::label, + ConstructMobileLabelLine( + {base::UTF8ToUTF16("María Lòpez"), + base::ASCIIToUTF16("11 Elkins St"), + base::ASCIIToUTF16("(617) 268-6862")})), + testing::Field(&Suggestion::additional_label, + ConstructMobileLabelLine( + {base::UTF8ToUTF16("María Lòpez"), + base::ASCIIToUTF16("11 Elkins St"), + base::ASCIIToUTF16("(617) 268-6862")})), + testing::Field(&Suggestion::icon, "")))); +} +#endif // if defined(OS_ANDROID) || defined(OS_IOS) + TEST_F(PersonalDataManagerTest, IsKnownCard_MatchesMaskedServerCard) { // Add a masked server card. std::vector<CreditCard> server_cards;
diff --git a/components/autofill_assistant/browser/BUILD.gn b/components/autofill_assistant/browser/BUILD.gn index 00412bf..c770bf6b 100644 --- a/components/autofill_assistant/browser/BUILD.gn +++ b/components/autofill_assistant/browser/BUILD.gn
@@ -86,6 +86,8 @@ "client.h", "client_memory.cc", "client_memory.h", + "client_settings.cc", + "client_settings.h", "client_status.cc", "client_status.h", "controller.cc",
diff --git a/components/autofill_assistant/browser/actions/action_delegate.h b/components/autofill_assistant/browser/actions/action_delegate.h index 600d786..702b3105 100644 --- a/components/autofill_assistant/browser/actions/action_delegate.h +++ b/components/autofill_assistant/browser/actions/action_delegate.h
@@ -34,6 +34,7 @@ namespace autofill_assistant { class ClientMemory; class ClientStatus; +struct ClientSettings; // Action delegate called when processing actions. class ActionDelegate { @@ -248,6 +249,9 @@ // Set the peek mode. virtual void SetPeekMode(ConfigureBottomSheetProto::PeekMode peek_mode) = 0; + // Returns the current client settings. + virtual const ClientSettings& GetSettings() = 0; + // Show a form to the user and call |callback| with its values whenever there // is a change. |callback| will be called directly with the initial values of // the form directly after this call. Returns true if the form was correctly
diff --git a/components/autofill_assistant/browser/actions/mock_action_delegate.h b/components/autofill_assistant/browser/actions/mock_action_delegate.h index a0cdb5d1..79167ab 100644 --- a/components/autofill_assistant/browser/actions/mock_action_delegate.h +++ b/components/autofill_assistant/browser/actions/mock_action_delegate.h
@@ -12,6 +12,7 @@ #include "base/callback.h" #include "components/autofill/core/browser/data_model/credit_card.h" #include "components/autofill_assistant/browser/actions/action_delegate.h" +#include "components/autofill_assistant/browser/client_settings.h" #include "components/autofill_assistant/browser/service.pb.h" #include "testing/gmock/include/gmock/gmock.h" @@ -166,6 +167,10 @@ SetForm, bool(std::unique_ptr<FormProto> form, base::RepeatingCallback<void(const FormProto::Result*)> callback)); + + const ClientSettings& GetSettings() override { return client_settings_; } + + ClientSettings client_settings_; }; } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/actions/prompt_action.cc b/components/autofill_assistant/browser/actions/prompt_action.cc index ac5795e..2853c9f 100644 --- a/components/autofill_assistant/browser/actions/prompt_action.cc +++ b/components/autofill_assistant/browser/actions/prompt_action.cc
@@ -12,17 +12,12 @@ #include "base/bind.h" #include "base/callback.h" #include "components/autofill_assistant/browser/actions/action_delegate.h" +#include "components/autofill_assistant/browser/client_settings.h" #include "components/autofill_assistant/browser/element_precondition.h" #include "url/gurl.h" namespace autofill_assistant { -namespace { -// Time between two chip precondition checks. -static constexpr base::TimeDelta kPreconditionChipCheckInterval = - base::TimeDelta::FromSeconds(1); -} // namespace - PromptAction::PromptAction(const ActionProto& proto) : Action(proto), weak_ptr_factory_(this) { DCHECK(proto_.has_prompt()); @@ -48,7 +43,8 @@ if (HasNonemptyPreconditions() || HasAutoSelect()) { RunPeriodicChecks(); timer_ = std::make_unique<base::RepeatingTimer>(); - timer_->Start(FROM_HERE, kPreconditionChipCheckInterval, + timer_->Start(FROM_HERE, + delegate->GetSettings().periodic_script_check_interval, base::BindRepeating(&PromptAction::RunPeriodicChecks, weak_ptr_factory_.GetWeakPtr())); }
diff --git a/components/autofill_assistant/browser/client_settings.cc b/components/autofill_assistant/browser/client_settings.cc new file mode 100644 index 0000000..81d8f29 --- /dev/null +++ b/components/autofill_assistant/browser/client_settings.cc
@@ -0,0 +1,49 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/autofill_assistant/browser/client_settings.h" + +#include "components/autofill_assistant/browser/service.pb.h" + +namespace autofill_assistant { + +ClientSettings::ClientSettings() = default; + +void ClientSettings::UpdateFromProto(const ClientSettingsProto& proto) { + if (proto.has_periodic_script_check_interval_ms()) { + periodic_script_check_interval = base::TimeDelta::FromMilliseconds( + proto.periodic_script_check_interval_ms()); + } + if (proto.has_periodic_element_check_interval_ms()) { + periodic_element_check_interval = base::TimeDelta::FromMilliseconds( + proto.periodic_element_check_interval_ms()); + } + if (proto.has_periodic_script_check_count()) { + periodic_script_check_count = proto.periodic_script_check_count(); + } + if (proto.has_element_position_update_interval_ms()) { + element_position_update_interval = base::TimeDelta::FromMilliseconds( + proto.element_position_update_interval_ms()); + } + if (proto.has_short_wait_for_element_deadline_ms()) { + short_wait_for_element_deadline = base::TimeDelta::FromMilliseconds( + proto.short_wait_for_element_deadline_ms()); + } + if (proto.has_box_model_check_interval_ms()) { + box_model_check_interval = + base::TimeDelta::FromMilliseconds(proto.box_model_check_interval_ms()); + } + if (proto.has_box_model_check_count()) { + box_model_check_count = proto.box_model_check_count(); + } + if (proto.has_document_ready_check_interval_ms()) { + document_ready_check_interval = base::TimeDelta::FromMilliseconds( + proto.document_ready_check_interval_ms()); + } + if (proto.has_document_ready_check_count()) { + document_ready_check_count = proto.document_ready_check_count(); + } +} + +} // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/client_settings.h b/components/autofill_assistant/browser/client_settings.h new file mode 100644 index 0000000..0aaae220 --- /dev/null +++ b/components/autofill_assistant/browser/client_settings.h
@@ -0,0 +1,72 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_CLIENT_SETTINGS_H_ +#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_CLIENT_SETTINGS_H_ + +#include "base/macros.h" +#include "base/time/time.h" + +namespace autofill_assistant { +class ClientSettingsProto; + +// Global settings for the Autofill Assistant client. +// +// These settings can be updated by the server, from +// SupportsScriptResponseProto. +// +// Note that since settings can change, all classes using settings should keep a +// pointer to the single ClientSettings instance instead of making a copy. +struct ClientSettings { + ClientSettings(); + + // Time between two periodic script precondition checks. + base::TimeDelta periodic_script_check_interval = + base::TimeDelta::FromSeconds(1); + + // Time between two element checks in the script executor. + base::TimeDelta periodic_element_check_interval = + base::TimeDelta::FromSeconds(1); + + // Run that many periodic checks before giving up unless something happens to + // wake it up, such as the user touching the screen. + int periodic_script_check_count = 10; + + // Time between two element position refreshes, when displaying highlighted + // areas in prompt state. + base::TimeDelta element_position_update_interval = + base::TimeDelta::FromMilliseconds(100); + + // Maximum amount of time normal actions should implicitly wait for a selector + // to show up. + base::TimeDelta short_wait_for_element_deadline = + base::TimeDelta::FromSeconds(2); + + // Time to wait between two checks of the box model, when waiting for an + // element to become stable, such as before clicking. + base::TimeDelta box_model_check_interval = + base::TimeDelta::FromMilliseconds(200); + + // Maximum number of checks to run while waiting for the element position to + // become stable. + int box_model_check_count = 50; + + // Time to wait between two checks of the document state, when waiting for the + // document to become ready. + base::TimeDelta document_ready_check_interval = + base::TimeDelta::FromMilliseconds(200); + + // Maximum number of checks to run while waiting for the document to become + // ready. + int document_ready_check_count = 50; + + void UpdateFromProto(const ClientSettingsProto& proto); + + private: + DISALLOW_COPY_AND_ASSIGN(ClientSettings); +}; + +} // namespace autofill_assistant + +#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_CLIENT_SETTINGS_H_
diff --git a/components/autofill_assistant/browser/controller.cc b/components/autofill_assistant/browser/controller.cc index 273dfd8..c506856 100644 --- a/components/autofill_assistant/browser/controller.cc +++ b/components/autofill_assistant/browser/controller.cc
@@ -31,14 +31,6 @@ namespace { -// Time between two periodic script checks. -static constexpr base::TimeDelta kPeriodicScriptCheckInterval = - base::TimeDelta::FromSeconds(1); - -// Number of script checks to run after a call to StartPeriodicScriptChecks. -// This limit does not apply when in autostart mode. -static constexpr int kPeriodicScriptCheckCount = 10; - // The initial progress to set when autostarting and showing the "Loading..." // message. static constexpr int kAutostartInitialProgress = 5; @@ -69,6 +61,10 @@ Controller::~Controller() = default; +const ClientSettings& Controller::GetSettings() { + return settings_; +} + const GURL& Controller::GetCurrentURL() { const GURL& last_committed = web_contents()->GetLastCommittedURL(); if (!last_committed.is_empty()) @@ -101,7 +97,8 @@ WebController* Controller::GetWebController() { if (!web_controller_) { - web_controller_ = WebController::CreateForWebContents(web_contents()); + web_controller_ = + WebController::CreateForWebContents(web_contents(), &settings_); } return web_controller_.get(); } @@ -474,7 +471,7 @@ } void Controller::StartPeriodicScriptChecks() { - periodic_script_check_count_ = kPeriodicScriptCheckCount; + periodic_script_check_count_ = settings_.periodic_script_check_count; // If periodic checks are running, setting periodic_script_check_count_ keeps // them running longer. if (periodic_script_check_scheduled_) @@ -484,7 +481,7 @@ FROM_HERE, {content::BrowserThread::UI}, base::BindOnce(&Controller::OnPeriodicScriptCheck, weak_ptr_factory_.GetWeakPtr()), - kPeriodicScriptCheckInterval); + settings_.periodic_script_check_interval); } void Controller::StopPeriodicScriptChecks() { @@ -517,7 +514,7 @@ FROM_HERE, {content::BrowserThread::UI}, base::BindOnce(&Controller::OnPeriodicScriptCheck, weak_ptr_factory_.GetWeakPtr()), - kPeriodicScriptCheckInterval); + settings_.periodic_script_check_interval); } void Controller::OnGetScripts(const GURL& url, @@ -546,6 +543,8 @@ Metrics::GET_SCRIPTS_UNPARSABLE); return; } + if (response_proto.has_client_settings()) + settings_.UpdateFromProto(response_proto.client_settings()); std::vector<std::unique_ptr<Script>> scripts; for (const auto& script_proto : response_proto.scripts()) {
diff --git a/components/autofill_assistant/browser/controller.h b/components/autofill_assistant/browser/controller.h index 505e0f8c..ac418a1 100644 --- a/components/autofill_assistant/browser/controller.h +++ b/components/autofill_assistant/browser/controller.h
@@ -13,6 +13,7 @@ #include "base/macros.h" #include "components/autofill_assistant/browser/client.h" #include "components/autofill_assistant/browser/client_memory.h" +#include "components/autofill_assistant/browser/client_settings.h" #include "components/autofill_assistant/browser/element_area.h" #include "components/autofill_assistant/browser/metrics.h" #include "components/autofill_assistant/browser/payment_request.h" @@ -66,6 +67,7 @@ void WillShutdown(Metrics::DropOutReason reason); // Overrides ScriptExecutorDelegate: + const ClientSettings& GetSettings() override; const GURL& GetCurrentURL() override; Service* GetService() override; UiController* GetUiController() override; @@ -215,6 +217,7 @@ ElementArea* touchable_element_area(); ScriptTracker* script_tracker(); + ClientSettings settings_; Client* const client_; const base::TickClock* const tick_clock_;
diff --git a/components/autofill_assistant/browser/element_area.cc b/components/autofill_assistant/browser/element_area.cc index af39e3c2..bb55e3a 100644 --- a/components/autofill_assistant/browser/element_area.cc +++ b/components/autofill_assistant/browser/element_area.cc
@@ -16,12 +16,6 @@ namespace autofill_assistant { -namespace { -// Waiting period between two checks. -static constexpr base::TimeDelta kCheckDelay = - base::TimeDelta::FromMilliseconds(100); -} // namespace - ElementArea::ElementArea(ScriptExecutorDelegate* delegate) : delegate_(delegate), scheduled_update_(false), weak_ptr_factory_(this) { DCHECK(delegate_); @@ -142,7 +136,7 @@ FROM_HERE, base::BindOnce(&ElementArea::KeepUpdatingElementPositions, weak_ptr_factory_.GetWeakPtr()), - kCheckDelay); + delegate_->GetSettings().element_position_update_interval); } void ElementArea::OnGetElementPosition(const Selector& selector,
diff --git a/components/autofill_assistant/browser/element_area.h b/components/autofill_assistant/browser/element_area.h index 1074ccd..69c4014 100644 --- a/components/autofill_assistant/browser/element_area.h +++ b/components/autofill_assistant/browser/element_area.h
@@ -11,6 +11,7 @@ #include "base/callback.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "components/autofill_assistant/browser/client_settings.h" #include "components/autofill_assistant/browser/rectf.h" #include "components/autofill_assistant/browser/selector.h" @@ -21,7 +22,8 @@ // changeable set of elements. class ElementArea { public: - // |delegate| must remain valid for the lifetime of this instance. + // |delegate| and |settings| must remain valid for the lifetime of this + // instance. explicit ElementArea(ScriptExecutorDelegate* delegate); ~ElementArea();
diff --git a/components/autofill_assistant/browser/fake_script_executor_delegate.cc b/components/autofill_assistant/browser/fake_script_executor_delegate.cc index 373ce2d9..cf6744c 100644 --- a/components/autofill_assistant/browser/fake_script_executor_delegate.cc +++ b/components/autofill_assistant/browser/fake_script_executor_delegate.cc
@@ -11,6 +11,10 @@ FakeScriptExecutorDelegate::FakeScriptExecutorDelegate() = default; FakeScriptExecutorDelegate::~FakeScriptExecutorDelegate() = default; +const ClientSettings& FakeScriptExecutorDelegate::GetSettings() { + return client_settings_; +} + const GURL& FakeScriptExecutorDelegate::GetCurrentURL() { return current_url_; }
diff --git a/components/autofill_assistant/browser/fake_script_executor_delegate.h b/components/autofill_assistant/browser/fake_script_executor_delegate.h index b365d75..c02e5883c 100644 --- a/components/autofill_assistant/browser/fake_script_executor_delegate.h +++ b/components/autofill_assistant/browser/fake_script_executor_delegate.h
@@ -12,6 +12,7 @@ #include <vector> #include "components/autofill_assistant/browser/client_memory.h" +#include "components/autofill_assistant/browser/client_settings.h" #include "components/autofill_assistant/browser/script_executor_delegate.h" #include "components/autofill_assistant/browser/trigger_context.h" @@ -24,6 +25,7 @@ FakeScriptExecutorDelegate(); ~FakeScriptExecutorDelegate() override; + const ClientSettings& GetSettings() override; const GURL& GetCurrentURL() override; Service* GetService() override; UiController* GetUiController() override; @@ -54,6 +56,8 @@ void AddListener(Listener* listener) override; void RemoveListener(Listener* listener) override; + ClientSettings* GetMutableSettings() { return &client_settings_; } + void SetCurrentURL(const GURL& url) { current_url_ = url; } void SetService(Service* service) { service_ = service; } @@ -92,6 +96,7 @@ bool HasListeners() { return !listeners_.empty(); } private: + ClientSettings client_settings_; GURL current_url_; Service* service_ = nullptr; UiController* ui_controller_ = nullptr;
diff --git a/components/autofill_assistant/browser/mock_web_controller.cc b/components/autofill_assistant/browser/mock_web_controller.cc index 675766c6..21dcf826 100644 --- a/components/autofill_assistant/browser/mock_web_controller.cc +++ b/components/autofill_assistant/browser/mock_web_controller.cc
@@ -6,7 +6,8 @@ namespace autofill_assistant { -MockWebController::MockWebController() : WebController(nullptr, nullptr) {} +MockWebController::MockWebController() + : WebController(nullptr, nullptr, nullptr) {} MockWebController::~MockWebController() {} } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/script_executor.cc b/components/autofill_assistant/browser/script_executor.cc index a117a78..bc248d5 100644 --- a/components/autofill_assistant/browser/script_executor.cc +++ b/components/autofill_assistant/browser/script_executor.cc
@@ -30,15 +30,6 @@ namespace autofill_assistant { namespace { -// Maximum amount of time normal actions should implicitly wait for a selector -// to show up. -constexpr base::TimeDelta kShortWaitForElementDeadline = - base::TimeDelta::FromSeconds(2); - -// Time between two element checks. -static constexpr base::TimeDelta kPeriodicElementCheck = - base::TimeDelta::FromSeconds(1); - std::ostream& operator<<(std::ostream& out, const ScriptExecutor::AtEnd& at_end) { #ifdef NDEBUG @@ -165,7 +156,7 @@ const Selector& selector, base::OnceCallback<void(bool)> callback) { wait_for_dom_ = std::make_unique<WaitForDomOperation>( - this, delegate_, kShortWaitForElementDeadline, + this, delegate_, delegate_->GetSettings().short_wait_for_element_deadline, /* allow_interrupt= */ false, base::BindRepeating(&ScriptExecutor::CheckElementMatches, weak_ptr_factory_.GetWeakPtr(), selector), @@ -470,6 +461,10 @@ delegate_->SetPeekMode(peek_mode); } +const ClientSettings& ScriptExecutor::GetSettings() { + return delegate_->GetSettings(); +} + bool ScriptExecutor::SetForm( std::unique_ptr<FormProto> form, base::RepeatingCallback<void(const FormProto::Result*)> callback) { @@ -684,7 +679,8 @@ allow_interrupt_(allow_interrupt), check_elements_(std::move(check_elements)), callback_(std::move(callback)), - retry_timer_(kPeriodicElementCheck), + retry_timer_(main_script->delegate_->GetSettings() + .periodic_element_check_interval), weak_ptr_factory_(this) {} ScriptExecutor::WaitForDomOperation::~WaitForDomOperation() {
diff --git a/components/autofill_assistant/browser/script_executor.h b/components/autofill_assistant/browser/script_executor.h index 43ce45dd..0325853 100644 --- a/components/autofill_assistant/browser/script_executor.h +++ b/components/autofill_assistant/browser/script_executor.h
@@ -18,6 +18,7 @@ #include "components/autofill_assistant/browser/actions/action.h" #include "components/autofill_assistant/browser/actions/action_delegate.h" #include "components/autofill_assistant/browser/actions/click_action.h" +#include "components/autofill_assistant/browser/client_settings.h" #include "components/autofill_assistant/browser/details.h" #include "components/autofill_assistant/browser/info_box.h" #include "components/autofill_assistant/browser/retry_timer.h" @@ -179,6 +180,7 @@ void SetProgressVisible(bool visible) override; void SetResizeViewport(bool resize_viewport) override; void SetPeekMode(ConfigureBottomSheetProto::PeekMode peek_mode) override; + const ClientSettings& GetSettings() override; bool SetForm(std::unique_ptr<FormProto> form, base::RepeatingCallback<void(const FormProto::Result*)> callback) override; @@ -326,7 +328,7 @@ const std::string initial_script_payload_; std::string last_script_payload_; ScriptExecutor::Listener* const listener_; - ScriptExecutorDelegate* delegate_; + ScriptExecutorDelegate* const delegate_; RunScriptCallback callback_; std::vector<std::unique_ptr<Action>> actions_;
diff --git a/components/autofill_assistant/browser/script_executor_delegate.h b/components/autofill_assistant/browser/script_executor_delegate.h index ebb6a46..3a46eea 100644 --- a/components/autofill_assistant/browser/script_executor_delegate.h +++ b/components/autofill_assistant/browser/script_executor_delegate.h
@@ -31,6 +31,7 @@ class UiController; class WebController; class ClientMemory; +struct ClientSettings; struct TriggerContext; class ScriptExecutorDelegate { @@ -42,6 +43,7 @@ virtual void OnNavigationStateChanged() = 0; }; + virtual const ClientSettings& GetSettings() = 0; virtual const GURL& GetCurrentURL() = 0; virtual Service* GetService() = 0; virtual UiController* GetUiController() = 0;
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto index e027b03..0d703458 100644 --- a/components/autofill_assistant/browser/service.proto +++ b/components/autofill_assistant/browser/service.proto
@@ -62,6 +62,44 @@ // Defines what should happen if no scripts in [scripts] becomes runnable, // because of preconditions. optional ScriptTimeoutError script_timeout_error = 2; + + optional ClientSettingsProto client_settings = 3; +} + +message ClientSettingsProto { + // Time between two periodic script precondition checks. + optional int32 periodic_script_check_interval_ms = 1; + + // Time between two element checks in the script executor. + optional int32 periodic_element_check_interval_ms = 2; + + // Run that many periodic checks before giving up unless something happens to + // wake it up, such as the user touching the screen. + optional int32 periodic_script_check_count = 3; + + // Time between two element position refreshes, when displaying highlighted + // areas in prompt state. + optional int32 element_position_update_interval_ms = 4; + + // Maximum amount of time normal actions should implicitly wait for a selector + // to show up. + optional int32 short_wait_for_element_deadline_ms = 5; + + // Time to wait between two checks of the box model, when waiting for an + // element to become stable, such as before clicking. + optional int32 box_model_check_interval_ms = 6; + + // Maximum number of checks to run while waiting for the element position to + // become stable. + optional int32 box_model_check_count = 7; + + // Time to wait between two checks of the document state, when waiting for the + // document to become ready. + optional int32 document_ready_check_interval_ms = 8; + + // Maximum number of checks to run while waiting for the document to become + // ready. + optional int32 document_ready_check_count = 9; } message ScriptTimeoutError {
diff --git a/components/autofill_assistant/browser/web_controller.cc b/components/autofill_assistant/browser/web_controller.cc index 5dc4f0a9..ac0356b8 100644 --- a/components/autofill_assistant/browser/web_controller.cc +++ b/components/autofill_assistant/browser/web_controller.cc
@@ -22,6 +22,7 @@ #include "components/autofill/core/browser/data_model/credit_card.h" #include "components/autofill/core/common/autofill_constants.h" #include "components/autofill/core/common/form_data.h" +#include "components/autofill_assistant/browser/client_settings.h" #include "components/autofill_assistant/browser/rectf.h" #include "components/autofill_assistant/browser/string_conversions_util.h" #include "content/public/browser/browser_task_traits.h" @@ -35,13 +36,6 @@ using autofill::ContentAutofillDriver; namespace { -// Time between two periodic box model and document ready state checks. -static constexpr base::TimeDelta kPeriodicCheckInterval = - base::TimeDelta::FromMilliseconds(200); - -// Timeout after roughly 10 seconds (50*200ms). -constexpr int kPeriodicCheckRounds = 50; - // Expiration time for the Autofill Assistant cookie. constexpr int kCookieExpiresSeconds = 600; @@ -346,7 +340,7 @@ class WebController::ElementPositionGetter : public WebController::Worker { public: - ElementPositionGetter(); + ElementPositionGetter(const ClientSettings& settings); ~ElementPositionGetter() override; // |devtools_client| must be valid for the lifetime of the instance, which is @@ -365,6 +359,11 @@ void OnResult(int x, int y); void OnError(); + // Time to wait between two box model checks. + const base::TimeDelta check_interval_; + // Maximum number of checks to run. + const int max_rounds_; + DevtoolsClient* devtools_client_ = nullptr; std::string object_id_; int remaining_rounds_ = 0; @@ -382,8 +381,12 @@ base::WeakPtrFactory<ElementPositionGetter> weak_ptr_factory_; }; -WebController::ElementPositionGetter::ElementPositionGetter() - : weak_ptr_factory_(this) {} +WebController::ElementPositionGetter::ElementPositionGetter( + const ClientSettings& settings) + : check_interval_(settings.box_model_check_interval), + max_rounds_(settings.box_model_check_count), + weak_ptr_factory_(this) {} + WebController::ElementPositionGetter::~ElementPositionGetter() = default; void WebController::ElementPositionGetter::Start( @@ -394,7 +397,7 @@ devtools_client_ = devtools_client; object_id_ = element_object_id; callback_ = std::move(callback); - remaining_rounds_ = kPeriodicCheckRounds; + remaining_rounds_ = max_rounds_; // TODO(crbug/806868): Consider using autofill_assistant::RetryTimer // Wait for a roundtrips through the renderer and compositor pipeline, @@ -442,18 +445,18 @@ int new_point_y = round((round((*content_box)[3]) + round((*content_box)[5])) * 0.5); - // Wait for at least three rounds (~600ms = - // 3*kPeriodicCheckInterval) for visual state update callback since - // it might take longer time to return or never return if no updates. - DCHECK(kPeriodicCheckRounds > 2 && kPeriodicCheckRounds >= remaining_rounds_); + // Wait for at least three rounds (~600ms = 3*check_interval_) for visual + // state update callback since it might take longer time to return or never + // return if no updates. + DCHECK(max_rounds_ > 2 && max_rounds_ >= remaining_rounds_); if (has_point_ && new_point_x == point_x_ && new_point_y == point_y_ && - (visual_state_updated_ || remaining_rounds_ + 2 < kPeriodicCheckRounds)) { + (visual_state_updated_ || remaining_rounds_ + 2 < max_rounds_)) { // Note that there is still a chance that the element's position has been - // changed after the last call of GetBoxModel, however, it might be safe - // to assume the element's position will not be changed before issuing - // click or tap event after stable for kPeriodicCheckInterval. In - // addition, checking again after issuing click or tap event doesn't help - // since the change may be expected. + // changed after the last call of GetBoxModel, however, it might be safe to + // assume the element's position will not be changed before issuing click or + // tap event after stable for check_interval_. In addition, checking again + // after issuing click or tap event doesn't help since the change may be + // expected. OnResult(new_point_x, new_point_y); return; } @@ -492,7 +495,7 @@ base::BindOnce( &WebController::ElementPositionGetter::GetAndWaitBoxModelStable, weak_ptr_factory_.GetWeakPtr()), - kPeriodicCheckInterval); + check_interval_); } void WebController::ElementPositionGetter::OnScrollIntoView( @@ -510,7 +513,7 @@ base::BindOnce( &WebController::ElementPositionGetter::GetAndWaitBoxModelStable, weak_ptr_factory_.GetWeakPtr()), - kPeriodicCheckInterval); + check_interval_); } void WebController::ElementPositionGetter::OnResult(int x, int y) { @@ -870,17 +873,21 @@ // static std::unique_ptr<WebController> WebController::CreateForWebContents( - content::WebContents* web_contents) { + content::WebContents* web_contents, + const ClientSettings* settings) { return std::make_unique<WebController>( web_contents, std::make_unique<DevtoolsClient>( - content::DevToolsAgentHost::GetOrCreateFor(web_contents))); + content::DevToolsAgentHost::GetOrCreateFor(web_contents)), + settings); } WebController::WebController(content::WebContents* web_contents, - std::unique_ptr<DevtoolsClient> devtools_client) + std::unique_ptr<DevtoolsClient> devtools_client, + const ClientSettings* settings) : web_contents_(web_contents), devtools_client_(std::move(devtools_client)), + settings_(settings), weak_ptr_factory_(this) {} WebController::~WebController() {} @@ -922,7 +929,7 @@ std::string element_object_id = result->object_id; WaitForDocumentToBecomeInteractive( - kPeriodicCheckRounds, element_object_id, + settings_->document_ready_check_count, element_object_id, base::BindOnce( &WebController::OnWaitDocumentToBecomeInteractiveForClickOrTap, weak_ptr_factory_.GetWeakPtr(), std::move(callback), click_type, @@ -992,7 +999,7 @@ } std::unique_ptr<ElementPositionGetter> getter = - std::make_unique<ElementPositionGetter>(); + std::make_unique<ElementPositionGetter>(*settings_); ElementPositionGetter* getter_ptr = getter.get(); pending_workers_[getter_ptr] = std::move(getter); getter_ptr->Start(target_element->container_frame_host, @@ -1166,7 +1173,7 @@ std::string element_object_id = element_result->object_id; WaitForDocumentToBecomeInteractive( - kPeriodicCheckRounds, element_object_id, + settings_->document_ready_check_count, element_object_id, base::BindOnce( &WebController::OnWaitDocumentToBecomeInteractiveForFocusElement, weak_ptr_factory_.GetWeakPtr(), std::move(callback), @@ -1930,7 +1937,7 @@ base::BindOnce(&WebController::WaitForDocumentToBecomeInteractive, weak_ptr_factory_.GetWeakPtr(), --remaining_rounds, object_id, std::move(callback)), - kPeriodicCheckInterval); + settings_->document_ready_check_interval); } } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/web_controller.h b/components/autofill_assistant/browser/web_controller.h index 73cdebeb..760fb4d3 100644 --- a/components/autofill_assistant/browser/web_controller.h +++ b/components/autofill_assistant/browser/web_controller.h
@@ -42,6 +42,7 @@ } namespace autofill_assistant { +struct ClientSettings; // Controller to interact with the web pages. // @@ -54,13 +55,16 @@ // multiple operations, whether in sequence or in parallel. class WebController { public: - // Create web controller for a given |web_contents|. + // Create web controller for a given |web_contents|. |settings| must be valid + // for the lifetime of the controller. static std::unique_ptr<WebController> CreateForWebContents( - content::WebContents* web_contents); + content::WebContents* web_contents, + const ClientSettings* settings); - // |web_contents| must outlive this web controller. + // |web_contents| and |settings| must outlive this web controller. WebController(content::WebContents* web_contents, - std::unique_ptr<DevtoolsClient> devtools_client); + std::unique_ptr<DevtoolsClient> devtools_client, + const ClientSettings* settings); virtual ~WebController(); // Load |url| in the current tab. Returns immediately, before the new page has @@ -428,6 +432,7 @@ // is guaranteed by the owner of this object. content::WebContents* web_contents_; std::unique_ptr<DevtoolsClient> devtools_client_; + const ClientSettings* const settings_; // Workers currently running and using |devtools_client_|. std::map<Worker*, std::unique_ptr<Worker>> pending_workers_;
diff --git a/components/autofill_assistant/browser/web_controller_browsertest.cc b/components/autofill_assistant/browser/web_controller_browsertest.cc index 4072c537..3c36d69 100644 --- a/components/autofill_assistant/browser/web_controller_browsertest.cc +++ b/components/autofill_assistant/browser/web_controller_browsertest.cc
@@ -5,6 +5,7 @@ #include "base/bind.h" #include "base/memory/ref_counted.h" #include "components/autofill_assistant/browser/actions/click_action.h" +#include "components/autofill_assistant/browser/client_settings.h" #include "components/autofill_assistant/browser/service.pb.h" #include "components/autofill_assistant/browser/string_conversions_util.h" #include "components/autofill_assistant/browser/web_controller.h" @@ -37,8 +38,8 @@ ASSERT_TRUE(http_server_->Start()); ASSERT_TRUE( NavigateToURL(shell(), http_server_->GetURL(kTargetWebsitePath))); - web_controller_ = - WebController::CreateForWebContents(shell()->web_contents()); + web_controller_ = WebController::CreateForWebContents( + shell()->web_contents(), &settings_); Observe(shell()->web_contents()); } @@ -417,6 +418,7 @@ private: std::unique_ptr<net::EmbeddedTestServer> http_server_; bool paint_occurred_during_last_loop_ = false; + ClientSettings settings_; DISALLOW_COPY_AND_ASSIGN(WebControllerBrowserTest); };
diff --git a/components/browser_sync/signin_confirmation_helper.cc b/components/browser_sync/signin_confirmation_helper.cc index f7f9f30..eb5bdb8ac 100644 --- a/components/browser_sync/signin_confirmation_helper.cc +++ b/components/browser_sync/signin_confirmation_helper.cc
@@ -63,13 +63,11 @@ void SigninConfirmationHelper::OnHistoryQueryResults( size_t max_entries, - history::QueryResults* results) { - history::QueryResults owned_results; - results->Swap(&owned_results); - bool too_much_history = owned_results.size() >= max_entries; + history::QueryResults results) { + bool too_much_history = results.size() >= max_entries; if (too_much_history) { - DVLOG(1) << "SigninConfirmationHelper: profile contains " - << owned_results.size() << " history entries"; + DVLOG(1) << "SigninConfirmationHelper: profile contains " << results.size() + << " history entries"; } ReturnResult(too_much_history); } @@ -84,8 +82,8 @@ opts.max_count = max_entries; history_service_->QueryHistory( base::string16(), opts, - base::Bind(&SigninConfirmationHelper::OnHistoryQueryResults, - base::Unretained(this), max_entries), + base::BindOnce(&SigninConfirmationHelper::OnHistoryQueryResults, + base::Unretained(this), max_entries), &task_tracker_); }
diff --git a/components/browser_sync/signin_confirmation_helper.h b/components/browser_sync/signin_confirmation_helper.h index 4260aa9e..cf742531 100644 --- a/components/browser_sync/signin_confirmation_helper.h +++ b/components/browser_sync/signin_confirmation_helper.h
@@ -41,8 +41,7 @@ ~SigninConfirmationHelper(); // Callback helper function for CheckHasHistory. - void OnHistoryQueryResults(size_t max_entries, - history::QueryResults* results); + void OnHistoryQueryResults(size_t max_entries, history::QueryResults results); // Posts the given result to the origin sequence. void PostResult(bool result);
diff --git a/components/cast_channel/cast_message_handler.cc b/components/cast_channel/cast_message_handler.cc index 3eb5f28..185f02b9 100644 --- a/components/cast_channel/cast_message_handler.cc +++ b/components/cast_channel/cast_message_handler.cc
@@ -301,10 +301,10 @@ cast_channel::CastMessage_PayloadType_STRING) { data_decoder::SafeJsonParser::ParseBatch( connector_.get(), message.payload_utf8(), - base::BindRepeating(&CastMessageHandler::HandleCastInternalMessage, - weak_ptr_factory_.GetWeakPtr(), socket.id(), - message.source_id(), message.destination_id()), - base::BindRepeating(&ReportParseError), data_decoder_batch_id_); + base::BindOnce(&CastMessageHandler::HandleCastInternalMessage, + weak_ptr_factory_.GetWeakPtr(), socket.id(), + message.source_id(), message.destination_id()), + base::BindOnce(&ReportParseError), data_decoder_batch_id_); } else { DLOG(ERROR) << "Dropping internal message with binary payload: " << message.namespace_();
diff --git a/components/cronet/ios/BUILD.gn b/components/cronet/ios/BUILD.gn index 4a5711e..b8659e29 100644 --- a/components/cronet/ios/BUILD.gn +++ b/components/cronet/ios/BUILD.gn
@@ -50,7 +50,8 @@ "//ios/net", "//ios/net:network_protocol", "//ios/web/public:user_agent", - "//ios/web/public/global_state", + "//ios/web/public/init:global_state", + "//ios/web/init:global_state", "//net", "//url", ] @@ -86,7 +87,8 @@ source_set("cronet_sources_with_global_state") { deps = [ "//base", - "//ios/web/public/global_state", + "//ios/web/init:global_state", + "//ios/web/public/init:global_state", ] public_deps = [
diff --git a/components/cronet/ios/cronet_environment.mm b/components/cronet/ios/cronet_environment.mm index b659dbdf..1703b14 100644 --- a/components/cronet/ios/cronet_environment.mm +++ b/components/cronet/ios/cronet_environment.mm
@@ -27,8 +27,8 @@ #include "components/prefs/pref_filter.h" #include "ios/net/cookies/cookie_store_ios.h" #include "ios/net/cookies/cookie_store_ios_client.h" -#include "ios/web/public/global_state/ios_global_state.h" -#include "ios/web/public/global_state/ios_global_state_configuration.h" +#include "ios/web/public/init/ios_global_state.h" +#include "ios/web/public/init/ios_global_state_configuration.h" #include "ios/web/public/user_agent.h" #include "net/base/http_user_agent_settings.h" #include "net/base/network_change_notifier.h"
diff --git a/components/cronet/ios/cronet_global_state_ios.mm b/components/cronet/ios/cronet_global_state_ios.mm index dfafdeb..50c5f60 100644 --- a/components/cronet/ios/cronet_global_state_ios.mm +++ b/components/cronet/ios/cronet_global_state_ios.mm
@@ -9,8 +9,8 @@ #include <utility> #include "base/callback.h" -#include "ios/web/public/global_state/ios_global_state.h" -#include "ios/web/public/global_state/ios_global_state_configuration.h" +#include "ios/web/public/init/ios_global_state.h" +#include "ios/web/public/init/ios_global_state_configuration.h" #include "ios/web/public/user_agent.h" #include "net/proxy_resolution/proxy_config_service.h" #include "net/proxy_resolution/proxy_resolution_service.h"
diff --git a/components/cronet/ios/ios_global_state_configuration.cc b/components/cronet/ios/ios_global_state_configuration.cc index 816486d..244f306 100644 --- a/components/cronet/ios/ios_global_state_configuration.cc +++ b/components/cronet/ios/ios_global_state_configuration.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ios/web/public/global_state/ios_global_state_configuration.h" +#include "ios/web/public/init/ios_global_state_configuration.h" namespace ios_global_state {
diff --git a/components/history/core/browser/browsing_history_service.cc b/components/history/core/browser/browsing_history_service.cc index fb64adb11..035db5b2 100644 --- a/components/history/core/browser/browsing_history_service.cc +++ b/components/history/core/browser/browsing_history_service.cc
@@ -254,8 +254,8 @@ state->search_text, OptionsWithEndTime(state->original_options, state->local_end_time_for_continuation), - base::Bind(&BrowsingHistoryService::QueryComplete, - weak_factory_.GetWeakPtr(), state), + base::BindOnce(&BrowsingHistoryService::QueryComplete, + weak_factory_.GetWeakPtr(), state), &query_task_tracker_); } } else { @@ -537,11 +537,11 @@ void BrowsingHistoryService::QueryComplete( scoped_refptr<QueryHistoryState> state, - QueryResults* results) { + QueryResults results) { std::vector<HistoryEntry>& output = state->local_results; - output.reserve(output.size() + results->size()); + output.reserve(output.size() + results.size()); - for (const auto& page : *results) { + for (const auto& page : results) { // TODO(dubroy): Use sane time (crbug.com/146090) here when it's ready. output.emplace_back(HistoryEntry( HistoryEntry::LOCAL_ENTRY, page.url(), page.title(), page.visit_time(), @@ -550,7 +550,7 @@ } state->local_status = - results->reached_beginning() ? REACHED_BEGINNING : MORE_RESULTS; + results.reached_beginning() ? REACHED_BEGINNING : MORE_RESULTS; if (!web_history_timer_->IsRunning()) ReturnResultsToDriver(std::move(state));
diff --git a/components/history/core/browser/browsing_history_service.h b/components/history/core/browser/browsing_history_service.h index b35de25..93b4ab85 100644 --- a/components/history/core/browser/browsing_history_service.h +++ b/components/history/core/browser/browsing_history_service.h
@@ -172,7 +172,7 @@ // Callback from the history system when a history query has completed. void QueryComplete(scoped_refptr<QueryHistoryState> state, - QueryResults* results); + QueryResults results); // Combines the query results from the local history database and the history // server, and sends the combined results to the
diff --git a/components/history/core/browser/history_backend.cc b/components/history/core/browser/history_backend.cc index 974fa36..e9b42e7 100644 --- a/components/history/core/browser/history_backend.cc +++ b/components/history/core/browser/history_backend.cc
@@ -1243,22 +1243,22 @@ DCHECK_GE(ids.size(), num_downloads_deleted); } -void HistoryBackend::QueryHistory(const base::string16& text_query, - const QueryOptions& options, - QueryResults* query_results) { - DCHECK(query_results); +QueryResults HistoryBackend::QueryHistory(const base::string16& text_query, + const QueryOptions& options) { + QueryResults query_results; base::TimeTicks beginning_time = base::TimeTicks::Now(); if (db_) { if (text_query.empty()) { // Basic history query for the main database. - QueryHistoryBasic(options, query_results); + QueryHistoryBasic(options, &query_results); } else { // Text history query. - QueryHistoryText(text_query, options, query_results); + QueryHistoryText(text_query, options, &query_results); } } UMA_HISTOGRAM_TIMES("History.QueryHistory", TimeTicks::Now() - beginning_time); + return query_results; } // Basic time-based querying of history. @@ -1342,32 +1342,32 @@ result->set_reached_beginning(true); } -void HistoryBackend::QueryRedirectsFrom(const GURL& from_url, - RedirectList* redirects) { - redirects->clear(); +RedirectList HistoryBackend::QueryRedirectsFrom(const GURL& from_url) { if (!db_) - return; + return {}; URLID from_url_id = db_->GetRowForURL(from_url, nullptr); VisitID cur_visit = db_->GetMostRecentVisitForURL(from_url_id, nullptr); if (!cur_visit) - return; // No visits for URL. + return {}; // No visits for URL. - GetRedirectsFromSpecificVisit(cur_visit, redirects); + RedirectList redirects; + GetRedirectsFromSpecificVisit(cur_visit, &redirects); + return redirects; } -void HistoryBackend::QueryRedirectsTo(const GURL& to_url, - RedirectList* redirects) { - redirects->clear(); +RedirectList HistoryBackend::QueryRedirectsTo(const GURL& to_url) { if (!db_) - return; + return {}; URLID to_url_id = db_->GetRowForURL(to_url, nullptr); VisitID cur_visit = db_->GetMostRecentVisitForURL(to_url_id, nullptr); if (!cur_visit) - return; // No visits for URL. + return {}; // No visits for URL. - GetRedirectsToSpecificVisit(cur_visit, redirects); + RedirectList redirects; + GetRedirectsToSpecificVisit(cur_visit, &redirects); + return redirects; } void HistoryBackend::GetVisibleVisitCountToHost( @@ -1396,8 +1396,7 @@ url_filter); for (const std::unique_ptr<PageUsageData>& current_data : data) { - RedirectList redirects; - QueryRedirectsFrom(current_data->GetURL(), &redirects); + RedirectList redirects = QueryRedirectsFrom(current_data->GetURL()); result->emplace_back(current_data->GetURL(), current_data->GetTitle(), redirects); } @@ -1446,8 +1445,8 @@ } void HistoryBackend::ScheduleAutocomplete( - const base::Callback<void(HistoryBackend*, URLDatabase*)>& callback) { - callback.Run(this, db_.get()); + base::OnceCallback<void(HistoryBackend*, URLDatabase*)> callback) { + std::move(callback).Run(this, db_.get()); } void HistoryBackend::DeleteFTSIndexDatabases() {
diff --git a/components/history/core/browser/history_backend.h b/components/history/core/browser/history_backend.h index 729e9c1..ac42a18 100644 --- a/components/history/core/browser/history_backend.h +++ b/components/history/core/browser/history_backend.h
@@ -233,25 +233,24 @@ // Run the |callback| on the History thread. // |callback| should handle the null database case. void ScheduleAutocomplete( - const base::Callback<void(HistoryBackend*, URLDatabase*)>& callback); + base::OnceCallback<void(HistoryBackend*, URLDatabase*)> callback); QueryURLResult QueryURL(const GURL& url, bool want_visits); - void QueryHistory(const base::string16& text_query, - const QueryOptions& options, - QueryResults* query_results); + QueryResults QueryHistory(const base::string16& text_query, + const QueryOptions& options); // Computes the most recent URL(s) that the given canonical URL has // redirected to. There may be more than one redirect in a row, so this // function will fill the given array with the entire chain. If there are // no redirects for the most recent visit of the URL, or the URL is not // in history, the array will be empty. - void QueryRedirectsFrom(const GURL& url, RedirectList* redirects); + RedirectList QueryRedirectsFrom(const GURL& url); // Similar to above function except computes a chain of redirects to the // given URL. Stores the most recent list of redirects ending at |url| in the // given RedirectList. For example, if we have the redirect list A -> B -> C, // then calling this function with url=C would fill redirects with {B, A}. - void QueryRedirectsTo(const GURL& url, RedirectList* redirects); + RedirectList QueryRedirectsTo(const GURL& url); void GetVisibleVisitCountToHost(const GURL& url, VisibleVisitCountToHostResult* result);
diff --git a/components/history/core/browser/history_querying_unittest.cc b/components/history/core/browser/history_querying_unittest.cc index 6f1f950..b51d9e9 100644 --- a/components/history/core/browser/history_querying_unittest.cc +++ b/components/history/core/browser/history_querying_unittest.cc
@@ -13,6 +13,7 @@ #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" #include "base/task/cancelable_task_tracker.h" +#include "base/test/bind_test_util.h" #include "base/test/scoped_task_environment.h" #include "components/history/core/browser/history_database_params.h" #include "components/history/core/browser/history_service.h" @@ -80,14 +81,15 @@ void QueryHistory(const std::string& text_query, const QueryOptions& options, QueryResults* results) { - history_->QueryHistory(base::UTF8ToUTF16(text_query), - options, - base::Bind(&HistoryQueryTest::QueryHistoryComplete, - base::Unretained(this)), + base::RunLoop loop; + history_->QueryHistory(base::UTF8ToUTF16(text_query), options, + base::BindLambdaForTesting([&](QueryResults r) { + *results = std::move(r); + loop.Quit(); + }), &tracker_); // Will go until ...Complete calls Quit. - base::RunLoop().Run(); - results->Swap(&last_query_results_); + loop.Run(); } // Test paging through results, with a fixed number of results per page. @@ -190,12 +192,6 @@ } } - void QueryHistoryComplete(QueryResults* results) { - results->Swap(&last_query_results_); - // Will return out to QueryHistory. - base::RunLoop::QuitCurrentWhenIdleDeprecated(); - } - base::ScopedTempDir temp_dir_; base::test::ScopedTaskEnvironment task_environment_; @@ -204,10 +200,6 @@ base::CancelableTaskTracker tracker_; - // The QueryHistoryComplete callback will put the results here so QueryHistory - // can return them. - QueryResults last_query_results_; - DISALLOW_COPY_AND_ASSIGN(HistoryQueryTest); };
diff --git a/components/history/core/browser/history_service.cc b/components/history/core/browser/history_service.cc index 2f2bcaba..05c92127 100644 --- a/components/history/core/browser/history_service.cc +++ b/components/history/core/browser/history_service.cc
@@ -806,44 +806,41 @@ base::CancelableTaskTracker::TaskId HistoryService::QueryHistory( const base::string16& text_query, const QueryOptions& options, - const QueryHistoryCallback& callback, + QueryHistoryCallback callback, base::CancelableTaskTracker* tracker) { DCHECK(backend_task_runner_) << "History service being called after cleanup"; DCHECK(thread_checker_.CalledOnValidThread()); - QueryResults* query_results = new QueryResults(); - return tracker->PostTaskAndReply( + return tracker->PostTaskAndReplyWithResult( backend_task_runner_.get(), FROM_HERE, base::BindOnce(&HistoryBackend::QueryHistory, history_backend_, - text_query, options, base::Unretained(query_results)), - base::BindOnce(callback, base::Owned(query_results))); + text_query, options), + std::move(callback)); } base::CancelableTaskTracker::TaskId HistoryService::QueryRedirectsFrom( const GURL& from_url, - const QueryRedirectsCallback& callback, + QueryRedirectsCallback callback, base::CancelableTaskTracker* tracker) { DCHECK(backend_task_runner_) << "History service being called after cleanup"; DCHECK(thread_checker_.CalledOnValidThread()); - RedirectList* result = new RedirectList(); - return tracker->PostTaskAndReply( + return tracker->PostTaskAndReplyWithResult( backend_task_runner_.get(), FROM_HERE, base::BindOnce(&HistoryBackend::QueryRedirectsFrom, history_backend_, - from_url, base::Unretained(result)), - base::BindOnce(callback, base::Owned(result))); + from_url), + std::move(callback)); } base::CancelableTaskTracker::TaskId HistoryService::QueryRedirectsTo( const GURL& to_url, - const QueryRedirectsCallback& callback, + QueryRedirectsCallback callback, base::CancelableTaskTracker* tracker) { DCHECK(backend_task_runner_) << "History service being called after cleanup"; DCHECK(thread_checker_.CalledOnValidThread()); - RedirectList* result = new RedirectList(); - return tracker->PostTaskAndReply( + return tracker->PostTaskAndReplyWithResult( backend_task_runner_.get(), FROM_HERE, base::BindOnce(&HistoryBackend::QueryRedirectsTo, history_backend_, - to_url, base::Unretained(result)), - base::BindOnce(callback, base::Owned(result))); + to_url), + std::move(callback)); } base::CancelableTaskTracker::TaskId HistoryService::GetVisibleVisitCountToHost( @@ -959,11 +956,11 @@ } void HistoryService::ScheduleAutocomplete( - const base::Callback<void(HistoryBackend*, URLDatabase*)>& callback) { + base::OnceCallback<void(HistoryBackend*, URLDatabase*)> callback) { DCHECK(thread_checker_.CalledOnValidThread()); ScheduleTask(PRIORITY_UI, base::BindOnce(&HistoryBackend::ScheduleAutocomplete, - history_backend_, callback)); + history_backend_, std::move(callback))); } void HistoryService::ScheduleTask(SchedulePriority priority,
diff --git a/components/history/core/browser/history_service.h b/components/history/core/browser/history_service.h index d680e30f..0108799 100644 --- a/components/history/core/browser/history_service.h +++ b/components/history/core/browser/history_service.h
@@ -232,7 +232,7 @@ // Provides the result of a query. See QueryResults in history_types.h. // The common use will be to use QueryResults.Swap to suck the contents of // the results out of the passed in parameter and take ownership of them. - typedef base::Callback<void(QueryResults*)> QueryHistoryCallback; + using QueryHistoryCallback = base::OnceCallback<void(QueryResults)>; // Queries all history with the given options (see QueryOptions in // history_types.h). If empty, all results matching the given options @@ -240,7 +240,7 @@ base::CancelableTaskTracker::TaskId QueryHistory( const base::string16& text_query, const QueryOptions& options, - const QueryHistoryCallback& callback, + QueryHistoryCallback callback, base::CancelableTaskTracker* tracker); // Called when the results of QueryRedirectsFrom are available. @@ -254,21 +254,21 @@ // If there is no such URL in the database or the most recent visit has no // redirect, the vector will be empty. If the given page has redirected to // multiple destinations, this will pick a random one. - typedef base::Callback<void(const RedirectList*)> QueryRedirectsCallback; + using QueryRedirectsCallback = base::OnceCallback<void(RedirectList)>; // Schedules a query for the most recent redirect coming out of the given // URL. See the RedirectQuerySource above, which is guaranteed to be called // if the request is not canceled. base::CancelableTaskTracker::TaskId QueryRedirectsFrom( const GURL& from_url, - const QueryRedirectsCallback& callback, + QueryRedirectsCallback callback, base::CancelableTaskTracker* tracker); // Schedules a query to get the most recent redirects ending at the given // URL. base::CancelableTaskTracker::TaskId QueryRedirectsTo( const GURL& to_url, - const QueryRedirectsCallback& callback, + QueryRedirectsCallback callback, base::CancelableTaskTracker* tracker); // Requests the number of user-visible visits (i.e. no redirects or subframes) @@ -575,7 +575,7 @@ // will be called back on the internal history thread with the history // database so it can query. See history_url_provider.h for a diagram. void ScheduleAutocomplete( - const base::Callback<void(HistoryBackend*, URLDatabase*)>& callback); + base::OnceCallback<void(HistoryBackend*, URLDatabase*)> callback); // Notification from the backend that it has finished loading. Sends // notification (NOTIFY_HISTORY_LOADED) and sets backend_loaded_ to true.
diff --git a/components/history/core/browser/history_service_unittest.cc b/components/history/core/browser/history_service_unittest.cc index 4208b0c..9e603cf 100644 --- a/components/history/core/browser/history_service_unittest.cc +++ b/components/history/core/browser/history_service_unittest.cc
@@ -125,20 +125,16 @@ base::RunLoop run_loop; history_service_->QueryRedirectsFrom( url, - base::BindRepeating(&HistoryServiceTest::OnRedirectQueryComplete, - base::Unretained(this), run_loop.QuitClosure()), + base::BindOnce(&HistoryServiceTest::OnRedirectQueryComplete, + base::Unretained(this), run_loop.QuitClosure()), &tracker_); run_loop.Run(); // Will be exited in *QueryComplete. } // Callback for QueryRedirects. void OnRedirectQueryComplete(base::OnceClosure done, - const history::RedirectList* redirects) { - saved_redirects_.clear(); - if (!redirects->empty()) { - saved_redirects_.insert( - saved_redirects_.end(), redirects->begin(), redirects->end()); - } + history::RedirectList redirects) { + saved_redirects_ = std::move(redirects); std::move(done).Run(); }
diff --git a/components/history/core/browser/history_types.cc b/components/history/core/browser/history_types.cc index ec60cf7..530831a 100644 --- a/components/history/core/browser/history_types.cc +++ b/components/history/core/browser/history_types.cc
@@ -34,11 +34,19 @@ // QueryResults ---------------------------------------------------------------- -QueryResults::QueryResults() : reached_beginning_(false) { -} +QueryResults::QueryResults() {} QueryResults::~QueryResults() {} +QueryResults::QueryResults(QueryResults&& other) noexcept { + Swap(&other); +} + +QueryResults& QueryResults::operator=(QueryResults&& other) noexcept { + Swap(&other); + return *this; +} + const size_t* QueryResults::MatchesForURL(const GURL& url, size_t* num_matches) const { auto found = url_to_results_.find(url);
diff --git a/components/history/core/browser/history_types.h b/components/history/core/browser/history_types.h index 8112f879..cb84ba4 100644 --- a/components/history/core/browser/history_types.h +++ b/components/history/core/browser/history_types.h
@@ -142,6 +142,9 @@ QueryResults(); ~QueryResults(); + QueryResults(QueryResults&& other) noexcept; + QueryResults& operator=(QueryResults&& other) noexcept; + void set_reached_beginning(bool reached) { reached_beginning_ = reached; } bool reached_beginning() { return reached_beginning_; } @@ -202,7 +205,7 @@ void AdjustResultMap(size_t begin, size_t end, ptrdiff_t delta); // Whether the query reaches the beginning of the database. - bool reached_beginning_; + bool reached_beginning_ = false; // The ordered list of results. The pointers inside this are owned by this // QueryResults object.
diff --git a/components/invalidation/public/invalidation_util.h b/components/invalidation/public/invalidation_util.h index d8d8e0d..b50abfb3 100644 --- a/components/invalidation/public/invalidation_util.h +++ b/components/invalidation/public/invalidation_util.h
@@ -47,11 +47,10 @@ class Invalidation; class InvalidationHandler; -// TODO(https://crbug.com/842655): Convert Repeating to Once. using ParseJSONCallback = base::RepeatingCallback<void( const std::string& unsafe_json, - const base::RepeatingCallback<void(base::Value)>& success_callback, - const base::RepeatingCallback<void(const std::string&)>& error_callback)>; + base::OnceCallback<void(base::Value)> success_callback, + base::OnceCallback<void(const std::string&)> error_callback)>; struct INVALIDATION_EXPORT ObjectIdLessThan { bool operator()(const invalidation::ObjectId& lhs,
diff --git a/components/journey/journey_info_json_request.h b/components/journey/journey_info_json_request.h index 2b144afc..b1a643a 100644 --- a/components/journey/journey_info_json_request.h +++ b/components/journey/journey_info_json_request.h
@@ -33,12 +33,12 @@ // serializing the request body protos. class JourneyInfoJsonRequest { // Callbacks for JSON parsing to allow injecting platform-dependent code. - using SuccessCallback = base::RepeatingCallback<void(base::Value result)>; - using ErrorCallback = base::RepeatingCallback<void(const std::string& error)>; + using SuccessCallback = base::OnceCallback<void(base::Value result)>; + using ErrorCallback = base::OnceCallback<void(const std::string& error)>; using ParseJSONCallback = base::RepeatingCallback<void(const std::string& raw_json_string, - const SuccessCallback& success_callback, - const ErrorCallback& error_callback)>; + SuccessCallback success_callback, + ErrorCallback error_callback)>; using CompletedCallback = base::OnceCallback<void(base::Optional<base::Value> result, const std::string& error_detail)>;
diff --git a/components/management_strings.grdp b/components/management_strings.grdp index d3e355f..3c2d4c69 100644 --- a/components/management_strings.grdp +++ b/components/management_strings.grdp
@@ -77,7 +77,7 @@ Can remotely change your device setup. </message> <message name="IDS_MANAGEMENT_DEVICE_MANAGED_DATA" desc="Continuation of the managed device clarification sentence explaining device user data management."> - Controls how your device data is handled. Google processes your device data exclusively under the direction of your device manager and solely for the purposes specified by your device manager. + Controls how your device data is handled. How Google processes and uses your device data is determined by your device manager. </message> <!-- Device and account managed clarification --> <message name="IDS_MANAGEMENT_DEVICE_AND_ACCOUNT_MANAGED_CLARIFICATION" desc="First part of the sentence of the managed device and account clarification, when enrollment domain equals account domain."> @@ -87,7 +87,7 @@ Can remotely change your device and account setup. </message> <message name="IDS_MANAGEMENT_DEVICE_AND_ACCOUNT_MANAGED_DATA" desc="Continuation of the managed device and account clarification sentence explaining device and account user data management."> - Controls how your device and account data is handled. Google processes your device and account data exclusively under the direction of your device and account manager and solely for the purposes specified by your device and account manager. + Controls how your device and account data is handled. How Google processes and uses your device and account data is determined by your device and account manager. </message> </if> <!-- Account managed clarification --> @@ -101,7 +101,7 @@ Can remotely change your account setup. </message> <message name="IDS_MANAGEMENT_ACCOUNT_MANAGED_DATA" desc="Continuation of the managed account clarification sentence explaining account user data management."> - Controls how your account data is handled. Google processes your account data exclusively under the direction of your account manager and solely for the purposes specified by your account manager. + Controls how your account data is handled. How Google processes and uses your account data is determined by your account manager. </message> <if expr="chromeos">
diff --git a/components/network_time/network_time_test_utils.cc b/components/network_time/network_time_test_utils.cc index 984da34..7261189 100644 --- a/components/network_time/network_time_test_utils.cc +++ b/components/network_time/network_time_test_utils.cc
@@ -111,8 +111,13 @@ // refcounted, and reference held by the singleton FieldTrialList. base::FieldTrial* trial = base::FieldTrialList::FactoryGetFieldTrial( - kTrialName, 100, kGroupName, 1971, 1, 1, - base::FieldTrial::SESSION_RANDOMIZED, nullptr /* default_group_number */); + kTrialName, 100, kGroupName, base::FieldTrial::SESSION_RANDOMIZED, + nullptr /* default_group_number */); + // Disabling the field trial selects the default group, with which we + // associate the provided params. Disabling the field trial does not disable + // the feature itself, but just provides a default group to use to set the + // feature enabled/disabled state below. + trial->Disable(); ASSERT_TRUE( variations::AssociateVariationParams(kTrialName, kGroupName, params));
diff --git a/components/ntp_snippets/remote/remote_suggestions_fetcher_impl_unittest.cc b/components/ntp_snippets/remote/remote_suggestions_fetcher_impl_unittest.cc index 04f78c98..8de361d4 100644 --- a/components/ntp_snippets/remote/remote_suggestions_fetcher_impl_unittest.cc +++ b/components/ntp_snippets/remote/remote_suggestions_fetcher_impl_unittest.cc
@@ -148,20 +148,20 @@ }; void ParseJson(const std::string& json, - const SuccessCallback& success_callback, - const ErrorCallback& error_callback) { + SuccessCallback success_callback, + ErrorCallback error_callback) { base::JSONReader json_reader; base::Optional<base::Value> value = json_reader.ReadToValue(json); if (value) { - success_callback.Run(std::move(*value)); + std::move(success_callback).Run(std::move(*value)); } else { - error_callback.Run(json_reader.GetErrorMessage()); + std::move(error_callback).Run(json_reader.GetErrorMessage()); } } void ParseJsonDelayed(const std::string& json, - const SuccessCallback& success_callback, - const ErrorCallback& error_callback) { + SuccessCallback success_callback, + ErrorCallback error_callback) { base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, base::BindOnce(&ParseJson, json, std::move(success_callback),
diff --git a/components/ntp_snippets/remote/request_params.h b/components/ntp_snippets/remote/request_params.h index 1066644f..510626e 100644 --- a/components/ntp_snippets/remote/request_params.h +++ b/components/ntp_snippets/remote/request_params.h
@@ -41,12 +41,12 @@ }; // Callbacks for JSON parsing to allow injecting platform-dependent code. -using SuccessCallback = base::Callback<void(base::Value result)>; -using ErrorCallback = base::Callback<void(const std::string& error)>; +using SuccessCallback = base::OnceCallback<void(base::Value result)>; +using ErrorCallback = base::OnceCallback<void(const std::string& error)>; using ParseJSONCallback = base::Callback<void(const std::string& raw_json_string, - const SuccessCallback& success_callback, - const ErrorCallback& error_callback)>; + SuccessCallback success_callback, + ErrorCallback error_callback)>; } // namespace ntp_snippets
diff --git a/components/ntp_tiles/popular_sites_impl.cc b/components/ntp_tiles/popular_sites_impl.cc index f1c72c88..34eef87 100644 --- a/components/ntp_tiles/popular_sites_impl.cc +++ b/components/ntp_tiles/popular_sites_impl.cc
@@ -262,12 +262,12 @@ const TemplateURLService* template_url_service, VariationsService* variations_service, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - ParseJSONCallback parse_json) + const ParseJSONCallback& parse_json) : prefs_(prefs), template_url_service_(template_url_service), variations_(variations_service), url_loader_factory_(std::move(url_loader_factory)), - parse_json_(std::move(parse_json)), + parse_json_(parse_json), is_fallback_(false), sections_( ParseSites(*prefs->GetList(prefs::kPopularSitesJsonPref), @@ -465,10 +465,10 @@ } parse_json_.Run(*response_body, - base::Bind(&PopularSitesImpl::OnJsonParsed, - weak_ptr_factory_.GetWeakPtr()), - base::Bind(&PopularSitesImpl::OnJsonParseFailed, - weak_ptr_factory_.GetWeakPtr())); + base::BindOnce(&PopularSitesImpl::OnJsonParsed, + weak_ptr_factory_.GetWeakPtr()), + base::BindOnce(&PopularSitesImpl::OnJsonParseFailed, + weak_ptr_factory_.GetWeakPtr())); } void PopularSitesImpl::OnJsonParsed(base::Value json) {
diff --git a/components/ntp_tiles/popular_sites_impl.h b/components/ntp_tiles/popular_sites_impl.h index ab84011..5b51e289 100644 --- a/components/ntp_tiles/popular_sites_impl.h +++ b/components/ntp_tiles/popular_sites_impl.h
@@ -39,10 +39,10 @@ namespace ntp_tiles { -using ParseJSONCallback = base::Callback<void( +using ParseJSONCallback = base::RepeatingCallback<void( const std::string& unsafe_json, - const base::Callback<void(base::Value)>& success_callback, - const base::Callback<void(const std::string&)>& error_callback)>; + base::OnceCallback<void(base::Value)> success_callback, + base::OnceCallback<void(const std::string&)> error_callback)>; // Actual (non-test) implementation of the PopularSites interface. Caches the // downloaded file on disk to avoid re-downloading on every startup. @@ -53,7 +53,7 @@ const TemplateURLService* template_url_service, variations::VariationsService* variations_service, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - ParseJSONCallback parse_json); + const ParseJSONCallback& parse_json); ~PopularSitesImpl() override;
diff --git a/components/omnibox/browser/history_url_provider.cc b/components/omnibox/browser/history_url_provider.cc index 12ad551..519db73 100644 --- a/components/omnibox/browser/history_url_provider.cc +++ b/components/omnibox/browser/history_url_provider.cc
@@ -597,7 +597,7 @@ params_ = params.release(); // This object will be destroyed in // QueryComplete() once we're done with it. history_service->ScheduleAutocomplete( - base::BindRepeating(&HistoryURLProvider::ExecuteWithDB, this, params_)); + base::BindOnce(&HistoryURLProvider::ExecuteWithDB, this, params_)); } } @@ -1157,8 +1157,7 @@ (source < matches->size()) && (source < max_results); ) { const GURL& url = (*matches)[source].url_info.url(); // TODO(brettw) this should go away when everything uses GURL. - history::RedirectList redirects; - backend->QueryRedirectsFrom(url, &redirects); + history::RedirectList redirects = backend->QueryRedirectsFrom(url); if (!redirects.empty()) { // Remove all but the first occurrence of any of these redirects in the // search results. We also must add the URL we queried for, since it may
diff --git a/components/password_manager/core/browser/http_auth_manager_impl.cc b/components/password_manager/core/browser/http_auth_manager_impl.cc index 3785547..698ef031 100644 --- a/components/password_manager/core/browser/http_auth_manager_impl.cc +++ b/components/password_manager/core/browser/http_auth_manager_impl.cc
@@ -60,7 +60,8 @@ observer_ = observer; // Initialize the form manager. form_manager_ = std::make_unique<NewPasswordFormManager>( - client_, observed_form, nullptr, /* form_fetcher */ + client_, PasswordStore::FormDigest(observed_form), + nullptr, /* form_fetcher */ std::make_unique<FormSaverImpl>(client_->GetPasswordStore())); }
diff --git a/components/password_manager/core/browser/http_auth_manager_impl.h b/components/password_manager/core/browser/http_auth_manager_impl.h index c74b344..2ec9a6c 100644 --- a/components/password_manager/core/browser/http_auth_manager_impl.h +++ b/components/password_manager/core/browser/http_auth_manager_impl.h
@@ -28,7 +28,7 @@ HttpAuthManagerImpl(PasswordManagerClient* client, HttpAuthObserver* observer, - const autofill::PasswordForm& observerd_form); + const autofill::PasswordForm& observed_form); ~HttpAuthManagerImpl() override;
diff --git a/components/password_manager/core/browser/new_password_form_manager.cc b/components/password_manager/core/browser/new_password_form_manager.cc index 1e121a3..93d39c3 100644 --- a/components/password_manager/core/browser/new_password_form_manager.cc +++ b/components/password_manager/core/browser/new_password_form_manager.cc
@@ -146,17 +146,15 @@ NewPasswordFormManager::NewPasswordFormManager( PasswordManagerClient* client, - const PasswordForm& http_auth_observed_form, + PasswordStore::FormDigest observed_http_auth_digest, FormFetcher* form_fetcher, std::unique_ptr<FormSaver> form_saver) - : NewPasswordFormManager( - client, - form_fetcher, - std::move(form_saver), - nullptr /* metrics_recorder */, - PasswordStore::FormDigest(http_auth_observed_form)) { - observed_http_auth_digest_ = - PasswordStore::FormDigest(http_auth_observed_form); + : NewPasswordFormManager(client, + form_fetcher, + std::move(form_saver), + nullptr /* metrics_recorder */, + observed_http_auth_digest) { + observed_http_auth_digest_ = std::move(observed_http_auth_digest); form_fetcher_->AddConsumer(this); } @@ -728,13 +726,13 @@ FormFetcher* form_fetcher, std::unique_ptr<FormSaver> form_saver, scoped_refptr<PasswordFormMetricsRecorder> metrics_recorder, - const PasswordStore::FormDigest& form_digest) + PasswordStore::FormDigest form_digest) : client_(client), metrics_recorder_(metrics_recorder), owned_form_fetcher_(form_fetcher ? nullptr : std::make_unique<FormFetcherImpl>( - form_digest, + std::move(form_digest), client_, true /* should_migrate_http_passwords */)), form_fetcher_(form_fetcher ? form_fetcher : owned_form_fetcher_.get()),
diff --git a/components/password_manager/core/browser/new_password_form_manager.h b/components/password_manager/core/browser/new_password_form_manager.h index 4ac6ad0..c8dfff9 100644 --- a/components/password_manager/core/browser/new_password_form_manager.h +++ b/components/password_manager/core/browser/new_password_form_manager.h
@@ -57,7 +57,7 @@ // Constructor for http authentication (aka basic authentication). NewPasswordFormManager(PasswordManagerClient* client, - const autofill::PasswordForm& http_auth_observed_form, + PasswordStore::FormDigest observed_http_auth_digest, FormFetcher* form_fetcher, std::unique_ptr<FormSaver> form_saver); @@ -211,7 +211,7 @@ FormFetcher* form_fetcher, std::unique_ptr<FormSaver> form_saver, scoped_refptr<PasswordFormMetricsRecorder> metrics_recorder, - const PasswordStore::FormDigest& form_digest); + PasswordStore::FormDigest form_digest); // Compares |parsed_form| with |old_parsing_result_| and records UKM metric. // TODO(https://crbug.com/831123): Remove it when the old form parsing is
diff --git a/components/password_manager/core/browser/new_password_form_manager_unittest.cc b/components/password_manager/core/browser/new_password_form_manager_unittest.cc index 196465d..c1460af 100644 --- a/components/password_manager/core/browser/new_password_form_manager_unittest.cc +++ b/components/password_manager/core/browser/new_password_form_manager_unittest.cc
@@ -23,6 +23,7 @@ #include "components/password_manager/core/browser/fake_form_fetcher.h" #include "components/password_manager/core/browser/password_form_manager_for_ui.h" #include "components/password_manager/core/browser/password_manager_util.h" +#include "components/password_manager/core/browser/password_store.h" #include "components/password_manager/core/browser/stub_form_saver.h" #include "components/password_manager/core/browser/stub_password_manager_client.h" #include "components/password_manager/core/browser/stub_password_manager_driver.h" @@ -379,8 +380,8 @@ fetcher_.reset(new FakeFormFetcher()); fetcher_->Fetch(); form_manager_.reset(new NewPasswordFormManager( - &client_, base_auth_observed_form, fetcher_.get(), - std::make_unique<NiceMock<MockFormSaver>>())); + &client_, PasswordStore::FormDigest(base_auth_observed_form), + fetcher_.get(), std::make_unique<NiceMock<MockFormSaver>>())); } void SetNonFederatedAndNotifyFetchCompleted(
diff --git a/components/payments/content/utility/payment_manifest_parser.cc b/components/payments/content/utility/payment_manifest_parser.cc index a33e9ac..27c1d1f 100644 --- a/components/payments/content/utility/payment_manifest_parser.cc +++ b/components/payments/content/utility/payment_manifest_parser.cc
@@ -380,10 +380,10 @@ data_decoder::SafeJsonParser::Parse( content::ServiceManagerConnection::GetForProcess()->GetConnector(), content, - base::Bind(&JsonParserCallback<PaymentMethodCallback>::OnSuccess, - json_callback), - base::Bind(&JsonParserCallback<PaymentMethodCallback>::OnError, - json_callback)); + base::BindOnce(&JsonParserCallback<PaymentMethodCallback>::OnSuccess, + json_callback), + base::BindOnce(&JsonParserCallback<PaymentMethodCallback>::OnError, + json_callback)); } void PaymentManifestParser::ParseWebAppManifest(const std::string& content, @@ -400,10 +400,10 @@ data_decoder::SafeJsonParser::Parse( content::ServiceManagerConnection::GetForProcess()->GetConnector(), content, - base::Bind(&JsonParserCallback<WebAppCallback>::OnSuccess, - parser_callback), - base::Bind(&JsonParserCallback<WebAppCallback>::OnError, - parser_callback)); + base::BindOnce(&JsonParserCallback<WebAppCallback>::OnSuccess, + parser_callback), + base::BindOnce(&JsonParserCallback<WebAppCallback>::OnError, + parser_callback)); } void PaymentManifestParser::ParseWebAppInstallationInfo( @@ -419,10 +419,12 @@ data_decoder::SafeJsonParser::Parse( content::ServiceManagerConnection::GetForProcess()->GetConnector(), content, - base::Bind(&JsonParserCallback<WebAppInstallationInfoCallback>::OnSuccess, - sw_parser_callback), - base::Bind(&JsonParserCallback<WebAppInstallationInfoCallback>::OnError, - sw_parser_callback)); + base::BindOnce( + &JsonParserCallback<WebAppInstallationInfoCallback>::OnSuccess, + sw_parser_callback), + base::BindOnce( + &JsonParserCallback<WebAppInstallationInfoCallback>::OnError, + sw_parser_callback)); } // static
diff --git a/components/policy/core/common/schema.cc b/components/policy/core/common/schema.cc index a99813e..2d8ea2dc 100644 --- a/components/policy/core/common/schema.cc +++ b/components/policy/core/common/schema.cc
@@ -522,30 +522,37 @@ } const SchemaNode* schema(int index) const { + DCHECK_GE(index, 0); return schema_data_.schema_nodes + index; } const PropertiesNode* properties(int index) const { + DCHECK_GE(index, 0); return schema_data_.properties_nodes + index; } const PropertyNode* property(int index) const { + DCHECK_GE(index, 0); return schema_data_.property_nodes + index; } const RestrictionNode* restriction(int index) const { + DCHECK_GE(index, 0); return schema_data_.restriction_nodes + index; } const char* const* required_property(int index) const { + DCHECK_GE(index, 0); return schema_data_.required_properties + index; } const int* int_enums(int index) const { + DCHECK_GE(index, 0); return schema_data_.int_enums + index; } const char* const* string_enums(int index) const { + DCHECK_GE(index, 0); return schema_data_.string_enums + index; } @@ -1159,10 +1166,16 @@ } Schema::Iterator::Iterator(const scoped_refptr<const InternalStorage>& storage, - const PropertiesNode* node) - : storage_(storage), - it_(storage->property(node->begin)), - end_(storage->property(node->end)) {} + const PropertiesNode* node) { + if (node->begin == kInvalid || node->end == kInvalid) { + it_ = nullptr; + end_ = nullptr; + } else { + storage_ = storage; + it_ = storage->property(node->begin); + end_ = storage->property(node->end); + } +} Schema::Iterator::Iterator(const Iterator& iterator) : storage_(iterator.storage_), @@ -1183,6 +1196,7 @@ } void Schema::Iterator::Advance() { + DCHECK(it_); ++it_; } @@ -1503,6 +1517,8 @@ CHECK(valid()); CHECK_EQ(base::Value::Type::DICTIONARY, type()); const PropertiesNode* node = storage_->properties(node_->extra); + if (node->begin == kInvalid || node->end == kInvalid) + return Schema(); const PropertyNode* begin = storage_->property(node->begin); const PropertyNode* end = storage_->property(node->end); const PropertyNode* it = std::lower_bound(begin, end, key, CompareKeys); @@ -1524,6 +1540,8 @@ CHECK(valid()); CHECK_EQ(base::Value::Type::DICTIONARY, type()); const PropertiesNode* node = storage_->properties(node_->extra); + if (node->end == kInvalid || node->pattern_end == kInvalid) + return {}; const PropertyNode* begin = storage_->property(node->end); const PropertyNode* end = storage_->property(node->pattern_end); SchemaList matching_properties; @@ -1540,6 +1558,8 @@ CHECK(valid()); CHECK_EQ(base::Value::Type::DICTIONARY, type()); const PropertiesNode* node = storage_->properties(node_->extra); + if (node->required_begin == kInvalid || node->required_end == kInvalid) + return {}; const size_t begin = node->required_begin; const size_t end = node->required_end;
diff --git a/components/policy/core/common/schema_unittest.cc b/components/policy/core/common/schema_unittest.cc index 493b993..bb79daa 100644 --- a/components/policy/core/common/schema_unittest.cc +++ b/components/policy/core/common/schema_unittest.cc
@@ -444,6 +444,9 @@ // This empty schema should never find named properties. EXPECT_FALSE(schema.GetKnownProperty("").valid()); EXPECT_FALSE(schema.GetKnownProperty("xyz").valid()); + EXPECT_TRUE(schema.GetRequiredProperties().empty()); + EXPECT_TRUE(schema.GetPatternProperties("").empty()); + EXPECT_FALSE(schema.GetAdditionalProperties().valid()); EXPECT_TRUE(schema.GetPropertiesIterator().IsAtEnd()); schema = Schema::Parse(R"({
diff --git a/components/policy/proto/device_management_backend.proto b/components/policy/proto/device_management_backend.proto index eafdef0..d03e2fe 100644 --- a/components/policy/proto/device_management_backend.proto +++ b/components/policy/proto/device_management_backend.proto
@@ -1837,6 +1837,11 @@ // |DEVICE_SET_VOLUME|: {"volume": volume_value}, where volume_value must be // an integer between 0 and 100. optional string payload = 4; + + // An identifier for the target this command is for. This is the same as + // the device_id in PolicyData. We rely on this identifier not being stable + // across powerwashes. + optional string target_device_id = 5; } // This protobuf defines the execution result of a single remote command @@ -1845,8 +1850,10 @@ // If you change this, update policy.mojom/CommandResultType. enum ResultType { RESULT_IGNORED = 0; // The command was ignored as obsolete. - RESULT_FAILURE = 1; // The command could not be executed. - RESULT_SUCCESS = 2; // The command was successfully executed. + RESULT_FAILURE = 1; // The command could not be executed or parsed. + RESULT_SUCCESS = 2; // The command was successfully executed. Commands + // such as powerwash will return success before they + // are executed since state will be forgotten. } // The result of the command. @@ -1874,11 +1881,26 @@ // The execution results of previously fetched commands. // The client should send back a command result whenever possible. repeated RemoteCommandResult command_results = 2; + + // Whether the server should send secure commands or not. + optional bool send_secure_commands = 3; } message DeviceRemoteCommandResponse { - // The queue of pending commands. + // The queue of pending, non secure commands. If this is present + // then there shall be no secure commands in this response (and + // vice versa). repeated RemoteCommand commands = 1; + + // The queue of pending, secure commands. If this is present + // then there shall be no non secure commands in this response + // (and vice versa). + // + // The secure_commands.data field contains a serialized + // RemoteCommand. The ecure_commands.signature field is a + // signature of the data field with the policy key for the + // domain the device belongs to. + repeated SignedData secure_commands = 2; } // Sent by the client to the server to check if the current user is allowed
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 878949d..0459a48 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -13175,7 +13175,7 @@ 'example_value': 604800000, 'desc': '''Allows you to set the time period, in milliseconds, over which users are notified that <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> must be relaunched or that a <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> device must be restarted to apply a pending update. - Over this time period, the user will be repeatedly informed of the need for an update. For <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> devices, a restart notification appears in the system tray when an upgrade is detected. For <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> browsers, the app menu changes to indicate that a relaunch is needed once one third of the notification period passes. This notification changes color once two thirds of the notification period passes, and again once the full notification period has passed. The additional notifications enabled by the <ph name="RELAUNCH_NOTIFICATION_POLICY_NAME">RelaunchNotification</ph> policy follow this same schedule. + Over this time period, the user will be repeatedly informed of the need for an update. For <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> devices, a restart notification appears in the system tray according to the <ph name="RELAUNCH_HEADS_UP_PERIOD_POLICY_NAME">RelaunchHeadsUpPeriod</ph> policy. For <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> browsers, the app menu changes to indicate that a relaunch is needed once one third of the notification period passes. This notification changes color once two thirds of the notification period passes, and again once the full notification period has passed. The additional notifications enabled by the <ph name="RELAUNCH_NOTIFICATION_POLICY_NAME">RelaunchNotification</ph> policy follow this same schedule. If not set, the default period of 345600000 milliseconds (four days) is used for <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> devices and 604800000 milliseconds (one week) for <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>.''', },
diff --git a/components/safe_browsing/browser/threat_details_history.cc b/components/safe_browsing/browser/threat_details_history.cc index 632f32e..1381c2a 100644 --- a/components/safe_browsing/browser/threat_details_history.cc +++ b/components/safe_browsing/browser/threat_details_history.cc
@@ -84,18 +84,18 @@ history_service_->QueryRedirectsTo( url, - base::Bind(&ThreatDetailsRedirectsCollector::OnGotQueryRedirectsTo, - base::Unretained(this), url), + base::BindOnce(&ThreatDetailsRedirectsCollector::OnGotQueryRedirectsTo, + base::Unretained(this), url), &request_tracker_); } void ThreatDetailsRedirectsCollector::OnGotQueryRedirectsTo( const GURL& url, - const history::RedirectList* redirect_list) { - if (!redirect_list->empty()) { + history::RedirectList redirect_list) { + if (!redirect_list.empty()) { std::vector<GURL> urllist; urllist.push_back(url); - urllist.insert(urllist.end(), redirect_list->begin(), redirect_list->end()); + urllist.insert(urllist.end(), redirect_list.begin(), redirect_list.end()); redirects_urls_.push_back(urllist); }
diff --git a/components/safe_browsing/browser/threat_details_history.h b/components/safe_browsing/browser/threat_details_history.h index 16bd25ff..fcf5c997 100644 --- a/components/safe_browsing/browser/threat_details_history.h +++ b/components/safe_browsing/browser/threat_details_history.h
@@ -53,7 +53,7 @@ void StartGetRedirects(const std::vector<GURL>& urls); void GetRedirects(const GURL& url); void OnGotQueryRedirectsTo(const GURL& url, - const history::RedirectList* redirect_list); + history::RedirectList redirect_list); // Runs the callback when redirects collecting is all done. void AllDone();
diff --git a/components/sync/driver/sync_service_crypto.cc b/components/sync/driver/sync_service_crypto.cc index 4c0e7b8..630b8a0 100644 --- a/components/sync/driver/sync_service_crypto.cc +++ b/components/sync/driver/sync_service_crypto.cc
@@ -109,12 +109,11 @@ return false; } - Nigori nigori; - bool derivation_result = - nigori.InitByDerivation(key_derivation_params, passphrase); - DCHECK(derivation_result); + std::unique_ptr<Nigori> nigori = + Nigori::CreateByDerivation(key_derivation_params, passphrase); + DCHECK(nigori); std::string plaintext; - bool decrypt_result = nigori.Decrypt(pending_keys.blob(), &plaintext); + bool decrypt_result = nigori->Decrypt(pending_keys.blob(), &plaintext); DVLOG_IF(1, !decrypt_result) << "Passphrase failed to decrypt pending keys."; return decrypt_result; }
diff --git a/components/sync/engine_impl/model_type_worker_unittest.cc b/components/sync/engine_impl/model_type_worker_unittest.cc index dc22a22..607b5e0 100644 --- a/components/sync/engine_impl/model_type_worker_unittest.cc +++ b/components/sync/engine_impl/model_type_worker_unittest.cc
@@ -85,32 +85,32 @@ // Modifies the input/output parameter |specifics| by encrypting it with // a Nigori intialized with the specified KeyParams. void EncryptUpdate(const KeyParams& params, EntitySpecifics* specifics) { - Nigori nigori; - nigori.InitByDerivation(params.derivation_params, params.password); + std::unique_ptr<Nigori> nigori = + Nigori::CreateByDerivation(params.derivation_params, params.password); EntitySpecifics original_specifics = *specifics; std::string plaintext; original_specifics.SerializeToString(&plaintext); std::string encrypted; - nigori.Encrypt(plaintext, &encrypted); + nigori->Encrypt(plaintext, &encrypted); specifics->Clear(); AddDefaultFieldValue(PREFERENCES, specifics); - specifics->mutable_encrypted()->set_key_name(GetNigoriName(nigori)); + specifics->mutable_encrypted()->set_key_name(GetNigoriName(*nigori)); specifics->mutable_encrypted()->set_blob(encrypted); } sync_pb::EntitySpecifics EncryptPasswordSpecifics( const KeyParams& key_params, const sync_pb::PasswordSpecificsData& unencrypted_password) { - Nigori nigori; - nigori.InitByDerivation(key_params.derivation_params, key_params.password); + std::unique_ptr<Nigori> nigori = Nigori::CreateByDerivation( + key_params.derivation_params, key_params.password); std::string encrypted_blob; - nigori.Encrypt(unencrypted_password.SerializeAsString(), &encrypted_blob); + nigori->Encrypt(unencrypted_password.SerializeAsString(), &encrypted_blob); sync_pb::EntitySpecifics encrypted_specifics; encrypted_specifics.mutable_password()->mutable_encrypted()->set_key_name( - GetNigoriName(nigori)); + GetNigoriName(*nigori)); encrypted_specifics.mutable_password()->mutable_encrypted()->set_blob( encrypted_blob); return encrypted_specifics; @@ -260,29 +260,29 @@ sync_pb::NigoriKeyBag bag; for (int i = 0; i <= foreign_encryption_key_index_; ++i) { - Nigori nigori; KeyParams params = GetNthKeyParams(i); - nigori.InitByDerivation(params.derivation_params, params.password); + std::unique_ptr<Nigori> nigori = + Nigori::CreateByDerivation(params.derivation_params, params.password); sync_pb::NigoriKey* key = bag.add_key(); - key->set_name(GetNigoriName(nigori)); - nigori.ExportKeys(key->mutable_user_key(), key->mutable_encryption_key(), - key->mutable_mac_key()); + key->set_name(GetNigoriName(*nigori)); + nigori->ExportKeys(key->mutable_user_key(), key->mutable_encryption_key(), + key->mutable_mac_key()); } // Re-create the last nigori from that loop. - Nigori last_nigori; KeyParams params = GetNthKeyParams(foreign_encryption_key_index_); - last_nigori.InitByDerivation(params.derivation_params, params.password); + std::unique_ptr<Nigori> last_nigori = + Nigori::CreateByDerivation(params.derivation_params, params.password); // Serialize and encrypt the bag with the last nigori. std::string serialized_bag; bag.SerializeToString(&serialized_bag); sync_pb::EncryptedData encrypted; - encrypted.set_key_name(GetNigoriName(last_nigori)); - last_nigori.Encrypt(serialized_bag, encrypted.mutable_blob()); + encrypted.set_key_name(GetNigoriName(*last_nigori)); + last_nigori->Encrypt(serialized_bag, encrypted.mutable_blob()); // Update the cryptographer with new pending keys. cryptographer_->SetPendingKeys(encrypted);
diff --git a/components/sync/engine_impl/sync_encryption_handler_impl.cc b/components/sync/engine_impl/sync_encryption_handler_impl.cc index 003fdd6..197739f5 100644 --- a/components/sync/engine_impl/sync_encryption_handler_impl.cc +++ b/components/sync/engine_impl/sync_encryption_handler_impl.cc
@@ -1100,12 +1100,13 @@ KeyDerivationParams::CreateForPbkdf2(); if (*passphrase_type == PassphraseType::CUSTOM_PASSPHRASE) { key_derivation_params = GetKeyDerivationParamsFromNigori(nigori); - custom_passphrase_key_derivation_params_ = key_derivation_params; if (key_derivation_params.method() == KeyDerivationMethod::UNSUPPORTED) { DLOG(WARNING) << "Updating from a Nigori node with an unsupported key " - "derivation method. Decryption will fail."; + "derivation method."; } + + custom_passphrase_key_derivation_params_ = key_derivation_params; } // If we've completed a sync cycle and the cryptographer isn't ready @@ -1371,6 +1372,8 @@ KeyDerivationParams::CreateForPbkdf2(); if (passphrase_type == PassphraseType::CUSTOM_PASSPHRASE) { DCHECK(custom_passphrase_key_derivation_params_.has_value()); + DCHECK_NE(custom_passphrase_key_derivation_params_->method(), + KeyDerivationMethod::UNSUPPORTED); key_derivation_params = custom_passphrase_key_derivation_params_.value(); } KeyParams key_params = {key_derivation_params, passphrase};
diff --git a/components/sync/engine_impl/sync_encryption_handler_impl_unittest.cc b/components/sync/engine_impl/sync_encryption_handler_impl_unittest.cc index c4b2e29..fde1fd3 100644 --- a/components/sync/engine_impl/sync_encryption_handler_impl_unittest.cc +++ b/components/sync/engine_impl/sync_encryption_handler_impl_unittest.cc
@@ -478,10 +478,10 @@ const KeyDerivationParams& key_derivation_params, const std::string& passphrase) { sync_pb::NigoriKey key; - Nigori nigori; - nigori.InitByDerivation(key_derivation_params, passphrase); - nigori.ExportKeys(key.mutable_user_key(), key.mutable_encryption_key(), - key.mutable_mac_key()); + std::unique_ptr<Nigori> nigori = + Nigori::CreateByDerivation(key_derivation_params, passphrase); + nigori->ExportKeys(key.mutable_user_key(), key.mutable_encryption_key(), + key.mutable_mac_key()); return key.SerializeAsString(); }
diff --git a/components/sync/nigori/cryptographer.cc b/components/sync/nigori/cryptographer.cc index a14978f3b..7b2ed19 100644 --- a/components/sync/nigori/cryptographer.cc +++ b/components/sync/nigori/cryptographer.cc
@@ -127,24 +127,16 @@ } bool Cryptographer::AddKey(const KeyParams& params) { - // Create the new Nigori and make it the default encryptor. - std::unique_ptr<Nigori> nigori(new Nigori); - if (!nigori->InitByDerivation(params.derivation_params, params.password)) { - NOTREACHED(); // Invalid username or password. - return false; - } - return AddKeyImpl(std::move(nigori), true); + return AddKeyImpl( + Nigori::CreateByDerivation(params.derivation_params, params.password), + /*set_as_default=*/true); } bool Cryptographer::AddNonDefaultKey(const KeyParams& params) { DCHECK(is_initialized()); - // Create the new Nigori and add it to the keybag. - std::unique_ptr<Nigori> nigori(new Nigori); - if (!nigori->InitByDerivation(params.derivation_params, params.password)) { - NOTREACHED(); // Invalid username or password. - return false; - } - return AddKeyImpl(std::move(nigori), false); + return AddKeyImpl( + Nigori::CreateByDerivation(params.derivation_params, params.password), + /*set_as_default=*/false); } bool Cryptographer::AddKeyFromBootstrapToken( @@ -155,9 +147,10 @@ return ImportNigoriKey(serialized_nigori_key); } -bool Cryptographer::AddKeyImpl(std::unique_ptr<Nigori> initialized_nigori, +bool Cryptographer::AddKeyImpl(std::unique_ptr<Nigori> nigori, bool set_as_default) { - std::string key_name = key_bag_.AddKey(std::move(initialized_nigori)); + DCHECK(nigori); + std::string key_name = key_bag_.AddKey(std::move(nigori)); if (key_name.empty()) { NOTREACHED(); return false; @@ -209,14 +202,14 @@ } bool Cryptographer::DecryptPendingKeys(const KeyParams& params) { - Nigori nigori; - if (!nigori.InitByDerivation(params.derivation_params, params.password)) { - NOTREACHED(); - return false; - } + DCHECK_NE(KeyDerivationMethod::UNSUPPORTED, + params.derivation_params.method()); + + std::unique_ptr<Nigori> nigori = + Nigori::CreateByDerivation(params.derivation_params, params.password); std::string plaintext; - if (!nigori.Decrypt(pending_keys_->blob(), &plaintext)) + if (!nigori->Decrypt(pending_keys_->blob(), &plaintext)) return false; sync_pb::NigoriKeyBag bag; @@ -311,10 +304,11 @@ if (!key.ParseFromString(serialized_nigori_key)) return false; - std::unique_ptr<Nigori> nigori(new Nigori); - if (!nigori->InitByImport(key.user_key(), key.encryption_key(), - key.mac_key())) { - NOTREACHED(); + std::unique_ptr<Nigori> nigori = Nigori::CreateByImport( + key.user_key(), key.encryption_key(), key.mac_key()); + + if (!nigori) { + DLOG(ERROR) << "Ignoring invalid Nigori when importing"; return false; }
diff --git a/components/sync/nigori/nigori.cc b/components/sync/nigori/nigori.cc index 337588f..f43d7fb 100644 --- a/components/sync/nigori/nigori.cc +++ b/components/sync/nigori/nigori.cc
@@ -12,6 +12,7 @@ #include "base/base64.h" #include "base/feature_list.h" #include "base/logging.h" +#include "base/memory/ptr_util.h" #include "base/metrics/histogram_functions.h" #include "base/stl_util.h" #include "base/strings/string_util.h" @@ -126,7 +127,7 @@ Nigori::Keys::Keys() = default; Nigori::Keys::~Keys() = default; -bool Nigori::Keys::InitByDerivationUsingPbkdf2(const std::string& password) { +void Nigori::Keys::InitByDerivationUsingPbkdf2(const std::string& password) { // Previously (<=M70) this value has been recalculated every time based on a // constant hostname (hardcoded to "localhost") and username (hardcoded to // "dummy") as PBKDF2_HMAC_SHA1(Ns("dummy") + Ns("localhost"), "saltsalt", @@ -158,11 +159,9 @@ SymmetricKey::HMAC_SHA1, password, salt, kSigningIterations, kDerivedKeySizeInBits); DCHECK(mac_key); - - return user_key && encryption_key && mac_key; } -bool Nigori::Keys::InitByDerivationUsingScrypt(const std::string& salt, +void Nigori::Keys::InitByDerivationUsingScrypt(const std::string& salt, const std::string& password) { const size_t kCostParameter = 8192; // 2^13. const size_t kBlockSize = 8; @@ -174,6 +173,7 @@ // failure on those clients. user_key = SymmetricKey::Import(SymmetricKey::AES, std::string(kDerivedKeySizeInBytes, '\0')); + DCHECK(user_key); // Derive a master key twice as long as the required key size, and split it // into two to get the encryption and MAC keys. @@ -188,63 +188,52 @@ master_key_str.substr(0, kDerivedKeySizeInBytes); DCHECK_EQ(encryption_key_str.length(), kDerivedKeySizeInBytes); encryption_key = SymmetricKey::Import(SymmetricKey::AES, encryption_key_str); + DCHECK(encryption_key); std::string mac_key_str = master_key_str.substr(kDerivedKeySizeInBytes); DCHECK_EQ(mac_key_str.length(), kDerivedKeySizeInBytes); mac_key = SymmetricKey::Import(SymmetricKey::HMAC_SHA1, mac_key_str); - - return user_key && encryption_key && mac_key; + DCHECK(mac_key); } bool Nigori::Keys::InitByImport(const std::string& user_key_str, const std::string& encryption_key_str, const std::string& mac_key_str) { + // |user_key| is not used anymore so we tolerate a failed import. user_key = SymmetricKey::Import(SymmetricKey::AES, user_key_str); encryption_key = SymmetricKey::Import(SymmetricKey::AES, encryption_key_str); - DCHECK(encryption_key); + if (!encryption_key) + return false; mac_key = SymmetricKey::Import(SymmetricKey::HMAC_SHA1, mac_key_str); - DCHECK(mac_key); + if (!mac_key) + return false; - return encryption_key && mac_key; + return true; } -Nigori::Nigori() : tick_clock_(base::DefaultTickClock::GetInstance()) {} - Nigori::~Nigori() {} -bool Nigori::InitByDerivation(const KeyDerivationParams& key_derivation_params, - const std::string& password) { - base::TimeTicks begin_time = tick_clock_->NowTicks(); - bool result = false; - switch (key_derivation_params.method()) { - case KeyDerivationMethod::PBKDF2_HMAC_SHA1_1003: - result = keys_.InitByDerivationUsingPbkdf2(password); - break; - case KeyDerivationMethod::SCRYPT_8192_8_11: - DCHECK(!base::FeatureList::IsEnabled( - switches::kSyncForceDisableScryptForCustomPassphrase)); - result = keys_.InitByDerivationUsingScrypt( - key_derivation_params.scrypt_salt(), password); - break; - case KeyDerivationMethod::UNSUPPORTED: - return false; - } - - UmaHistogramTimes( - base::StringPrintf("Sync.Crypto.NigoriKeyDerivationDuration.%s", - GetHistogramSuffixForKeyDerivationMethod( - key_derivation_params.method())), - tick_clock_->NowTicks() - begin_time); - - return result; +// static +std::unique_ptr<Nigori> Nigori::CreateByDerivation( + const KeyDerivationParams& key_derivation_params, + const std::string& password) { + return CreateByDerivationImpl(key_derivation_params, password, + base::DefaultTickClock::GetInstance()); } -bool Nigori::InitByImport(const std::string& user_key, - const std::string& encryption_key, - const std::string& mac_key) { - return keys_.InitByImport(user_key, encryption_key, mac_key); +// static +std::unique_ptr<Nigori> Nigori::CreateByImport( + const std::string& user_key, + const std::string& encryption_key, + const std::string& mac_key) { + // base::WrapUnique() is used because the constructor is private. + auto nigori = base::WrapUnique(new Nigori()); + if (!nigori->keys_.InitByImport(user_key, encryption_key, mac_key)) { + return nullptr; + } + return nigori; } // Permute[Kenc,Kmac](type || name) @@ -373,4 +362,43 @@ return salt; } +std::unique_ptr<Nigori> Nigori::CreateByDerivationForTesting( + const KeyDerivationParams& key_derivation_params, + const std::string& password, + const base::TickClock* tick_clock) { + return CreateByDerivationImpl(key_derivation_params, password, tick_clock); +} + +Nigori::Nigori() = default; + +// static +std::unique_ptr<Nigori> Nigori::CreateByDerivationImpl( + const KeyDerivationParams& key_derivation_params, + const std::string& password, + const base::TickClock* tick_clock) { + auto nigori = base::WrapUnique(new Nigori()); + base::TimeTicks begin_time = tick_clock->NowTicks(); + switch (key_derivation_params.method()) { + case KeyDerivationMethod::PBKDF2_HMAC_SHA1_1003: + nigori->keys_.InitByDerivationUsingPbkdf2(password); + break; + case KeyDerivationMethod::SCRYPT_8192_8_11: + DCHECK(!base::FeatureList::IsEnabled( + switches::kSyncForceDisableScryptForCustomPassphrase)); + nigori->keys_.InitByDerivationUsingScrypt( + key_derivation_params.scrypt_salt(), password); + break; + case KeyDerivationMethod::UNSUPPORTED: + NOTREACHED(); + } + + UmaHistogramTimes( + base::StringPrintf("Sync.Crypto.NigoriKeyDerivationDuration.%s", + GetHistogramSuffixForKeyDerivationMethod( + key_derivation_params.method())), + tick_clock->NowTicks() - begin_time); + + return nigori; +} + } // namespace syncer
diff --git a/components/sync/nigori/nigori.h b/components/sync/nigori/nigori.h index 94e9868..b8ff669 100644 --- a/components/sync/nigori/nigori.h +++ b/components/sync/nigori/nigori.h
@@ -63,18 +63,21 @@ Password = 1, }; - Nigori(); virtual ~Nigori(); // Initialize by deriving keys based on the given |key_derivation_params| and - // |password|. - bool InitByDerivation(const KeyDerivationParams& key_derivation_params, - const std::string& password); + // |password|. The key derivation method must not be UNSUPPORTED. The return + // value is guaranteed to be non-null. + static std::unique_ptr<Nigori> CreateByDerivation( + const KeyDerivationParams& key_derivation_params, + const std::string& password); // Initialize by importing the given keys instead of deriving new ones. - bool InitByImport(const std::string& user_key, - const std::string& encryption_key, - const std::string& mac_key); + // Returns null in case of failure. + static std::unique_ptr<Nigori> CreateByImport( + const std::string& user_key, + const std::string& encryption_key, + const std::string& mac_key); // Derives a secure lookup name from |type| and |name|. If |hostname|, // |username| and |password| are kept constant, a given |type| and |name| pair @@ -95,11 +98,13 @@ std::string* encryption_key, std::string* mac_key) const; - static std::string GenerateScryptSalt(); + // Same as CreateByDerivation() but allows overriding the clock. + static std::unique_ptr<Nigori> CreateByDerivationForTesting( + const KeyDerivationParams& key_derivation_params, + const std::string& password, + const base::TickClock* tick_clock); - void SetTickClockForTesting(const base::TickClock* tick_clock) { - tick_clock_ = tick_clock; - } + static std::string GenerateScryptSalt(); // Exposed for tests. static const size_t kIvSize = 16; @@ -117,16 +122,22 @@ std::unique_ptr<crypto::SymmetricKey> encryption_key; std::unique_ptr<crypto::SymmetricKey> mac_key; - bool InitByDerivationUsingPbkdf2(const std::string& password); - bool InitByDerivationUsingScrypt(const std::string& salt, + void InitByDerivationUsingPbkdf2(const std::string& password); + void InitByDerivationUsingScrypt(const std::string& salt, const std::string& password); bool InitByImport(const std::string& user_key_str, const std::string& encryption_key_str, const std::string& mac_key_str); }; + Nigori(); + + static std::unique_ptr<Nigori> CreateByDerivationImpl( + const KeyDerivationParams& key_derivation_params, + const std::string& password, + const base::TickClock* tick_clock); + Keys keys_; - const base::TickClock* tick_clock_; }; } // namespace syncer
diff --git a/components/sync/nigori/nigori_key_bag.cc b/components/sync/nigori/nigori_key_bag.cc index acb11d69e..3e45791 100644 --- a/components/sync/nigori/nigori_key_bag.cc +++ b/components/sync/nigori/nigori_key_bag.cc
@@ -32,24 +32,15 @@ return proto; } -std::unique_ptr<Nigori> NigoriFromProto(const sync_pb::NigoriKey& proto) { - auto nigori = std::make_unique<Nigori>(); - if (!nigori->InitByImport(proto.user_key(), proto.encryption_key(), - proto.mac_key())) { - return nullptr; - } - return nigori; -} - std::unique_ptr<Nigori> CloneNigori(const Nigori& nigori) { std::string user_key; std::string encryption_key; std::string mac_key; nigori.ExportKeys(&user_key, &encryption_key, &mac_key); - auto nigori_copy = std::make_unique<Nigori>(); - bool success = nigori_copy->InitByImport(user_key, encryption_key, mac_key); - DCHECK(success); + std::unique_ptr<Nigori> nigori_copy = + Nigori::CreateByImport(user_key, encryption_key, mac_key); + DCHECK(nigori_copy); return nigori_copy; } @@ -64,11 +55,16 @@ NigoriKeyBag NigoriKeyBag::CreateFromProto(const sync_pb::NigoriKeyBag& proto) { NigoriKeyBag output; for (const sync_pb::NigoriKey& key : proto.key()) { - auto nigori = NigoriFromProto(key); + std::unique_ptr<Nigori> nigori = Nigori::CreateByImport( + key.user_key(), key.encryption_key(), key.mac_key()); if (!nigori) { - NOTREACHED(); + // TODO(crbug.com/922900): Consider propagating this error to callers such + // that they can do smarter handling. + DLOG(ERROR) << "Invalid NigoriKey protocol buffer message."; continue; } + // TODO(crbug.com/967417): We shouldn't trust the name in the proto and + // instead should compute ComputeNigoriName(*nigori). output.nigori_map_[key.name()] = std::move(nigori); } return output;
diff --git a/components/sync/nigori/nigori_key_bag_unittest.cc b/components/sync/nigori/nigori_key_bag_unittest.cc index afd06c5..fb8231ed 100644 --- a/components/sync/nigori/nigori_key_bag_unittest.cc +++ b/components/sync/nigori/nigori_key_bag_unittest.cc
@@ -17,9 +17,8 @@ using testing::SizeIs; std::unique_ptr<Nigori> CreateTestNigori(const std::string& password) { - auto nigori = std::make_unique<Nigori>(); - nigori->InitByDerivation(KeyDerivationParams::CreateForPbkdf2(), password); - return nigori; + return Nigori::CreateByDerivation(KeyDerivationParams::CreateForPbkdf2(), + password); } TEST(NigoriKeyBagTest, ShouldCreateEmpty) { @@ -82,6 +81,25 @@ EXPECT_TRUE(restored_key_bag.HasKey(key_name2)); } +TEST(NigoriKeyBagTest, ShouldCreateNonEmptyFromPartiallyInvalidProto) { + NigoriKeyBag original_key_bag = NigoriKeyBag::CreateEmpty(); + const std::string key_name1 = + original_key_bag.AddKey(CreateTestNigori("password1")); + const std::string key_name2 = + original_key_bag.AddKey(CreateTestNigori("password2")); + + sync_pb::NigoriKeyBag malformed_proto = original_key_bag.ToProto(); + ASSERT_THAT(malformed_proto.key(), SizeIs(2)); + malformed_proto.mutable_key(1)->set_encryption_key("malformed-key"); + + NigoriKeyBag restored_key_bag = + NigoriKeyBag::CreateFromProto(malformed_proto); + + EXPECT_THAT(restored_key_bag, SizeIs(1)); + EXPECT_TRUE(restored_key_bag.HasKey(key_name1)); + EXPECT_FALSE(restored_key_bag.HasKey(key_name2)); +} + TEST(NigoriKeyBagTest, ShouldClone) { NigoriKeyBag original_key_bag = NigoriKeyBag::CreateEmpty(); const std::string key_name1 =
diff --git a/components/sync/nigori/nigori_sync_bridge_impl_unittest.cc b/components/sync/nigori/nigori_sync_bridge_impl_unittest.cc index eb2e41aa..de5fed50 100644 --- a/components/sync/nigori/nigori_sync_bridge_impl_unittest.cc +++ b/components/sync/nigori/nigori_sync_bridge_impl_unittest.cc
@@ -30,11 +30,10 @@ MATCHER_P(HasDefaultKeyDerivedFrom, key_params, "") { const Cryptographer& cryptographer = arg; - Nigori expected_default_nigori; - expected_default_nigori.InitByDerivation(key_params.derivation_params, - key_params.password); + std::unique_ptr<Nigori> expected_default_nigori = Nigori::CreateByDerivation( + key_params.derivation_params, key_params.password); std::string expected_default_key_name; - EXPECT_TRUE(expected_default_nigori.Permute( + EXPECT_TRUE(expected_default_nigori->Permute( Nigori::Type::Password, kNigoriKeyName, &expected_default_key_name)); return cryptographer.GetDefaultNigoriKeyName() == expected_default_key_name; } @@ -57,15 +56,15 @@ MATCHER_P(CanDecryptWith, key_params, "") { const Cryptographer& cryptographer = arg; - Nigori nigori; - nigori.InitByDerivation(key_params.derivation_params, key_params.password); + std::unique_ptr<Nigori> nigori = Nigori::CreateByDerivation( + key_params.derivation_params, key_params.password); std::string nigori_name; EXPECT_TRUE( - nigori.Permute(Nigori::Type::Password, kNigoriKeyName, &nigori_name)); + nigori->Permute(Nigori::Type::Password, kNigoriKeyName, &nigori_name)); const std::string unencrypted = "test"; sync_pb::EncryptedData encrypted; encrypted.set_key_name(nigori_name); - EXPECT_TRUE(nigori.Encrypt(unencrypted, encrypted.mutable_blob())); + EXPECT_TRUE(nigori->Encrypt(unencrypted, encrypted.mutable_blob())); if (!cryptographer.CanDecrypt(encrypted)) { return false;
diff --git a/components/sync/nigori/nigori_unittest.cc b/components/sync/nigori/nigori_unittest.cc index a191ce6..4828002 100644 --- a/components/sync/nigori/nigori_unittest.cc +++ b/components/sync/nigori/nigori_unittest.cc
@@ -4,17 +4,23 @@ #include "components/sync/nigori/nigori.h" +#include <memory> + #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/time/tick_clock.h" #include "components/sync/base/sync_base_switches.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" namespace syncer { namespace { +using testing::IsNull; +using testing::NotNull; + class FakeTickClock : public base::TickClock { public: FakeTickClock() : call_count_(0) {} @@ -40,12 +46,12 @@ constexpr base::TimeDelta FakeTickClock::kTicksAdvanceAfterEachCall; TEST(SyncNigoriTest, Permute) { - Nigori nigori; - EXPECT_TRUE(nigori.InitByDerivation(KeyDerivationParams::CreateForPbkdf2(), - "password")); + std::unique_ptr<Nigori> nigori = Nigori::CreateByDerivation( + KeyDerivationParams::CreateForPbkdf2(), "password"); + ASSERT_THAT(nigori, NotNull()); std::string permuted; - EXPECT_TRUE(nigori.Permute(Nigori::Password, "test name", &permuted)); + EXPECT_TRUE(nigori->Permute(Nigori::Password, "test name", &permuted)); std::string expected = "evpwwPT726JS/mhxv1UwPVLDz5ha/GrMA8HfA3sQGJr5" @@ -54,189 +60,191 @@ } TEST(SyncNigoriTest, PermuteIsConstant) { - Nigori nigori1; - EXPECT_TRUE(nigori1.InitByDerivation(KeyDerivationParams::CreateForPbkdf2(), - "password")); + std::unique_ptr<Nigori> nigori1 = Nigori::CreateByDerivation( + KeyDerivationParams::CreateForPbkdf2(), "password"); + ASSERT_THAT(nigori1, NotNull()); std::string permuted1; - EXPECT_TRUE(nigori1.Permute(Nigori::Password, "name", &permuted1)); + EXPECT_TRUE(nigori1->Permute(Nigori::Password, "name", &permuted1)); - Nigori nigori2; - EXPECT_TRUE(nigori2.InitByDerivation(KeyDerivationParams::CreateForPbkdf2(), - "password")); + std::unique_ptr<Nigori> nigori2 = Nigori::CreateByDerivation( + KeyDerivationParams::CreateForPbkdf2(), "password"); + ASSERT_THAT(nigori2, NotNull()); std::string permuted2; - EXPECT_TRUE(nigori2.Permute(Nigori::Password, "name", &permuted2)); + EXPECT_TRUE(nigori2->Permute(Nigori::Password, "name", &permuted2)); EXPECT_LT(0U, permuted1.size()); EXPECT_EQ(permuted1, permuted2); } TEST(SyncNigoriTest, EncryptDifferentIv) { - Nigori nigori; - EXPECT_TRUE(nigori.InitByDerivation(KeyDerivationParams::CreateForPbkdf2(), - "password")); + std::unique_ptr<Nigori> nigori = Nigori::CreateByDerivation( + KeyDerivationParams::CreateForPbkdf2(), "password"); + ASSERT_THAT(nigori, NotNull()); std::string plaintext("value"); std::string encrypted1; - EXPECT_TRUE(nigori.Encrypt(plaintext, &encrypted1)); + EXPECT_TRUE(nigori->Encrypt(plaintext, &encrypted1)); std::string encrypted2; - EXPECT_TRUE(nigori.Encrypt(plaintext, &encrypted2)); + EXPECT_TRUE(nigori->Encrypt(plaintext, &encrypted2)); EXPECT_NE(encrypted1, encrypted2); } TEST(SyncNigoriTest, Decrypt) { - Nigori nigori; - EXPECT_TRUE(nigori.InitByDerivation(KeyDerivationParams::CreateForPbkdf2(), - "password")); + std::unique_ptr<Nigori> nigori = Nigori::CreateByDerivation( + KeyDerivationParams::CreateForPbkdf2(), "password"); + ASSERT_THAT(nigori, NotNull()); std::string encrypted = "NNYlnzaaLPXWXyzz8J+u4OKgLiKRBPu2GJdjHWk0m3ADZrJhnmer30" "Zgiy4Ulxlfh6fmS71k8rop+UvSJdL1k/fcNLJ1C6sY5Z86ijyl1Jo="; std::string plaintext; - EXPECT_TRUE(nigori.Decrypt(encrypted, &plaintext)); + EXPECT_TRUE(nigori->Decrypt(encrypted, &plaintext)); std::string expected("test, test, 1, 2, 3"); EXPECT_EQ(expected, plaintext); } TEST(SyncNigoriTest, EncryptDecrypt) { - Nigori nigori; - EXPECT_TRUE(nigori.InitByDerivation(KeyDerivationParams::CreateForPbkdf2(), - "password")); + std::unique_ptr<Nigori> nigori = Nigori::CreateByDerivation( + KeyDerivationParams::CreateForPbkdf2(), "password"); + ASSERT_THAT(nigori, NotNull()); std::string plaintext("value"); std::string encrypted; - EXPECT_TRUE(nigori.Encrypt(plaintext, &encrypted)); + EXPECT_TRUE(nigori->Encrypt(plaintext, &encrypted)); std::string decrypted; - EXPECT_TRUE(nigori.Decrypt(encrypted, &decrypted)); + EXPECT_TRUE(nigori->Decrypt(encrypted, &decrypted)); EXPECT_EQ(plaintext, decrypted); } TEST(SyncNigoriTest, CorruptedIv) { - Nigori nigori; - EXPECT_TRUE(nigori.InitByDerivation(KeyDerivationParams::CreateForPbkdf2(), - "password")); + std::unique_ptr<Nigori> nigori = Nigori::CreateByDerivation( + KeyDerivationParams::CreateForPbkdf2(), "password"); + ASSERT_THAT(nigori, NotNull()); std::string plaintext("test"); std::string encrypted; - EXPECT_TRUE(nigori.Encrypt(plaintext, &encrypted)); + EXPECT_TRUE(nigori->Encrypt(plaintext, &encrypted)); // Corrupt the IV by changing one of its byte. encrypted[0] = (encrypted[0] == 'a' ? 'b' : 'a'); std::string decrypted; - EXPECT_TRUE(nigori.Decrypt(encrypted, &decrypted)); + EXPECT_TRUE(nigori->Decrypt(encrypted, &decrypted)); EXPECT_NE(plaintext, decrypted); } TEST(SyncNigoriTest, CorruptedCiphertext) { - Nigori nigori; - EXPECT_TRUE(nigori.InitByDerivation(KeyDerivationParams::CreateForPbkdf2(), - "password")); + std::unique_ptr<Nigori> nigori = Nigori::CreateByDerivation( + KeyDerivationParams::CreateForPbkdf2(), "password"); + ASSERT_THAT(nigori, NotNull()); std::string plaintext("test"); std::string encrypted; - EXPECT_TRUE(nigori.Encrypt(plaintext, &encrypted)); + EXPECT_TRUE(nigori->Encrypt(plaintext, &encrypted)); // Corrput the ciphertext by changing one of its bytes. encrypted[Nigori::kIvSize + 10] = (encrypted[Nigori::kIvSize + 10] == 'a' ? 'b' : 'a'); std::string decrypted; - EXPECT_FALSE(nigori.Decrypt(encrypted, &decrypted)); + EXPECT_FALSE(nigori->Decrypt(encrypted, &decrypted)); EXPECT_NE(plaintext, decrypted); } TEST(SyncNigoriTest, ExportImport) { - Nigori nigori1; - EXPECT_TRUE(nigori1.InitByDerivation(KeyDerivationParams::CreateForPbkdf2(), - "password")); + std::unique_ptr<Nigori> nigori1 = Nigori::CreateByDerivation( + KeyDerivationParams::CreateForPbkdf2(), "password"); + ASSERT_THAT(nigori1, NotNull()); std::string user_key; std::string encryption_key; std::string mac_key; - nigori1.ExportKeys(&user_key, &encryption_key, &mac_key); + nigori1->ExportKeys(&user_key, &encryption_key, &mac_key); - Nigori nigori2; - EXPECT_TRUE(nigori2.InitByImport(user_key, encryption_key, mac_key)); + std::unique_ptr<Nigori> nigori2 = + Nigori::CreateByImport(user_key, encryption_key, mac_key); + ASSERT_THAT(nigori2, NotNull()); std::string original("test"); std::string plaintext; std::string ciphertext; - EXPECT_TRUE(nigori1.Encrypt(original, &ciphertext)); - EXPECT_TRUE(nigori2.Decrypt(ciphertext, &plaintext)); + EXPECT_TRUE(nigori1->Encrypt(original, &ciphertext)); + EXPECT_TRUE(nigori2->Decrypt(ciphertext, &plaintext)); EXPECT_EQ(original, plaintext); - EXPECT_TRUE(nigori2.Encrypt(original, &ciphertext)); - EXPECT_TRUE(nigori1.Decrypt(ciphertext, &plaintext)); + EXPECT_TRUE(nigori2->Encrypt(original, &ciphertext)); + EXPECT_TRUE(nigori1->Decrypt(ciphertext, &plaintext)); EXPECT_EQ(original, plaintext); std::string permuted1, permuted2; - EXPECT_TRUE(nigori1.Permute(Nigori::Password, original, &permuted1)); - EXPECT_TRUE(nigori2.Permute(Nigori::Password, original, &permuted2)); + EXPECT_TRUE(nigori1->Permute(Nigori::Password, original, &permuted1)); + EXPECT_TRUE(nigori2->Permute(Nigori::Password, original, &permuted2)); EXPECT_EQ(permuted1, permuted2); } -TEST(SyncNigoriTest, InitByDerivationSetsUserKey) { - Nigori nigori; - EXPECT_TRUE(nigori.InitByDerivation(KeyDerivationParams::CreateForPbkdf2(), - "password")); +TEST(SyncNigoriTest, CreateByDerivationSetsUserKey) { + std::unique_ptr<Nigori> nigori = Nigori::CreateByDerivation( + KeyDerivationParams::CreateForPbkdf2(), "password"); + ASSERT_THAT(nigori, NotNull()); std::string user_key; std::string encryption_key; std::string mac_key; - nigori.ExportKeys(&user_key, &encryption_key, &mac_key); + nigori->ExportKeys(&user_key, &encryption_key, &mac_key); EXPECT_NE(user_key, ""); } TEST(SyncNigoriTest, ToleratesEmptyUserKey) { - Nigori nigori1; - EXPECT_TRUE(nigori1.InitByDerivation(KeyDerivationParams::CreateForPbkdf2(), - "password")); + std::unique_ptr<Nigori> nigori1 = Nigori::CreateByDerivation( + KeyDerivationParams::CreateForPbkdf2(), "password"); + ASSERT_THAT(nigori1, NotNull()); std::string user_key; std::string encryption_key; std::string mac_key; - nigori1.ExportKeys(&user_key, &encryption_key, &mac_key); + nigori1->ExportKeys(&user_key, &encryption_key, &mac_key); EXPECT_FALSE(user_key.empty()); EXPECT_FALSE(encryption_key.empty()); EXPECT_FALSE(mac_key.empty()); - Nigori nigori2; - EXPECT_TRUE(nigori2.InitByImport("", encryption_key, mac_key)); + std::unique_ptr<Nigori> nigori2 = + Nigori::CreateByImport(/*user_key=*/"", encryption_key, mac_key); + ASSERT_THAT(nigori2, NotNull()); user_key = "non-empty-value"; - nigori2.ExportKeys(&user_key, &encryption_key, &mac_key); + nigori2->ExportKeys(&user_key, &encryption_key, &mac_key); EXPECT_TRUE(user_key.empty()); EXPECT_FALSE(encryption_key.empty()); EXPECT_FALSE(mac_key.empty()); } -TEST(SyncNigoriTest, InitByDerivationShouldDeriveCorrectKeyUsingPbkdf2) { +TEST(SyncNigoriTest, CreateByDerivationShouldDeriveCorrectKeyUsingPbkdf2) { const std::string kPassphrase = "hunter2"; - Nigori nigori; - EXPECT_TRUE(nigori.InitByDerivation(KeyDerivationParams::CreateForPbkdf2(), - kPassphrase)); + std::unique_ptr<Nigori> nigori = Nigori::CreateByDerivation( + KeyDerivationParams::CreateForPbkdf2(), kPassphrase); + ASSERT_THAT(nigori, NotNull()); std::string user_key; std::string encryption_key; std::string mac_key; - nigori.ExportKeys(&user_key, &encryption_key, &mac_key); + nigori->ExportKeys(&user_key, &encryption_key, &mac_key); // These are reference values obtained by running PBKDF2 with Nigori's // parameters and the input values given above. EXPECT_EQ( @@ -250,18 +258,18 @@ base::ToLowerASCII(base::HexEncode(mac_key.data(), mac_key.size()))); } -TEST(SyncNigoriTest, InitByDerivationShouldDeriveCorrectKeyUsingScrypt) { +TEST(SyncNigoriTest, CreateByDerivationShouldDeriveCorrectKeyUsingScrypt) { const std::string kSalt = "alpensalz"; const std::string kPassphrase = "hunter2"; - Nigori nigori; - EXPECT_TRUE(nigori.InitByDerivation( - KeyDerivationParams::CreateForScrypt(kSalt), kPassphrase)); + std::unique_ptr<Nigori> nigori = Nigori::CreateByDerivation( + KeyDerivationParams::CreateForScrypt(kSalt), kPassphrase); + ASSERT_THAT(nigori, NotNull()); std::string user_key; std::string encryption_key; std::string mac_key; - nigori.ExportKeys(&user_key, &encryption_key, &mac_key); + nigori->ExportKeys(&user_key, &encryption_key, &mac_key); // user_key is not used anymore, but is being set for backwards compatibility // (because legacy clients cannot import a Nigori node without one). // Therefore, we just initialize it to all zeroes. @@ -278,20 +286,13 @@ base::ToLowerASCII(base::HexEncode(mac_key.data(), mac_key.size()))); } -TEST(SyncNigoriTest, - InitByDerivationShouldFailWhenGivenUnsupportedKeyDerivationMethod) { - Nigori nigori; - EXPECT_FALSE(nigori.InitByDerivation( - KeyDerivationParams::CreateWithUnsupportedMethod(), "Passphrase!")); -} - -TEST(SyncNigoriTest, InitByDerivationShouldReportPbkdf2DurationInHistogram) { +TEST(SyncNigoriTest, CreateByDerivationShouldReportPbkdf2DurationInHistogram) { FakeTickClock fake_tick_clock; - Nigori nigori; - nigori.SetTickClockForTesting(&fake_tick_clock); base::HistogramTester histogram_tester; - ASSERT_TRUE(nigori.InitByDerivation(KeyDerivationParams::CreateForPbkdf2(), - "Passphrase!")); + + std::unique_ptr<Nigori> nigori = Nigori::CreateByDerivationForTesting( + KeyDerivationParams::CreateForPbkdf2(), "Passphrase!", &fake_tick_clock); + ASSERT_THAT(nigori, NotNull()); ASSERT_EQ(2, fake_tick_clock.call_count()); histogram_tester.ExpectUniqueSample( @@ -300,13 +301,14 @@ /*count=*/1); } -TEST(SyncNigoriTest, InitByDerivationShouldReportScryptDurationInHistogram) { +TEST(SyncNigoriTest, CreateByDerivationShouldReportScryptDurationInHistogram) { FakeTickClock fake_tick_clock; - Nigori nigori; - nigori.SetTickClockForTesting(&fake_tick_clock); base::HistogramTester histogram_tester; - ASSERT_TRUE(nigori.InitByDerivation( - KeyDerivationParams::CreateForScrypt("somesalt"), "Passphrase!")); + + std::unique_ptr<Nigori> nigori = Nigori::CreateByDerivationForTesting( + KeyDerivationParams::CreateForScrypt("somesalt"), "Passphrase!", + &fake_tick_clock); + ASSERT_THAT(nigori, NotNull()); ASSERT_EQ(2, fake_tick_clock.call_count()); histogram_tester.ExpectUniqueSample( @@ -333,5 +335,13 @@ EXPECT_TRUE(is_nontrivial); } +TEST(SyncNigoriTest, ShouldFailToImportEmpty) { + EXPECT_THAT(Nigori::CreateByImport("", "", ""), IsNull()); +} + +TEST(SyncNigoriTest, ShouldFailToImportInvalid) { + EXPECT_THAT(Nigori::CreateByImport("foo", "bar", "baz"), IsNull()); +} + } // anonymous namespace } // namespace syncer
diff --git a/components/ukm/ukm_recorder_impl.cc b/components/ukm/ukm_recorder_impl.cc index 7ff3c6d..cbcb5351 100644 --- a/components/ukm/ukm_recorder_impl.cc +++ b/components/ukm/ukm_recorder_impl.cc
@@ -198,7 +198,6 @@ scoped_refptr<base::FieldTrial> trial( base::FieldTrialList::FactoryGetFieldTrial( kUkmSamplingRateFeature.name, 100, sampled_group, - base::FieldTrialList::kNoExpirationYear, 1, 1, base::FieldTrial::ONE_TIME_RANDOMIZED, nullptr)); // Everybody (100%) should have a sampling configuration.
diff --git a/components/variations/entropy_provider_unittest.cc b/components/variations/entropy_provider_unittest.cc index 79040f4..121bc090 100644 --- a/components/variations/entropy_provider_unittest.cc +++ b/components/variations/entropy_provider_unittest.cc
@@ -185,14 +185,13 @@ // particular client_id we use for unit tests they won't. base::FieldTrialList field_trial_list( std::make_unique<SHA1EntropyProvider>("client_id")); - const int kNoExpirationYear = base::FieldTrialList::kNoExpirationYear; scoped_refptr<base::FieldTrial> trials[] = { base::FieldTrialList::FactoryGetFieldTrial( - "one", 100, "default", kNoExpirationYear, 1, 1, - base::FieldTrial::ONE_TIME_RANDOMIZED, nullptr), + "one", 100, "default", base::FieldTrial::ONE_TIME_RANDOMIZED, + nullptr), base::FieldTrialList::FactoryGetFieldTrial( - "two", 100, "default", kNoExpirationYear, 1, 1, - base::FieldTrial::ONE_TIME_RANDOMIZED, nullptr), + "two", 100, "default", base::FieldTrial::ONE_TIME_RANDOMIZED, + nullptr), }; for (size_t i = 0; i < base::size(trials); ++i) { @@ -216,14 +215,13 @@ base::FieldTrialList field_trial_list( std::make_unique<NormalizedMurmurHashEntropyProvider>( 1234, kMaxLowEntropySize)); - const int kNoExpirationYear = base::FieldTrialList::kNoExpirationYear; scoped_refptr<base::FieldTrial> trials[] = { base::FieldTrialList::FactoryGetFieldTrial( - "one", 100, "default", kNoExpirationYear, 1, 1, - base::FieldTrial::ONE_TIME_RANDOMIZED, nullptr), + "one", 100, "default", base::FieldTrial::ONE_TIME_RANDOMIZED, + nullptr), base::FieldTrialList::FactoryGetFieldTrial( - "two", 100, "default", kNoExpirationYear, 1, 1, - base::FieldTrial::ONE_TIME_RANDOMIZED, nullptr), + "two", 100, "default", base::FieldTrial::ONE_TIME_RANDOMIZED, + nullptr), }; for (size_t i = 0; i < base::size(trials); ++i) { @@ -242,15 +240,14 @@ // for one time randomization produce the same group assignments. base::FieldTrialList field_trial_list( std::make_unique<SHA1EntropyProvider>("client_id")); - const int kNoExpirationYear = base::FieldTrialList::kNoExpirationYear; const uint32_t kCustomSeed = 9001; scoped_refptr<base::FieldTrial> trials[] = { base::FieldTrialList::FactoryGetFieldTrialWithRandomizationSeed( - "one", 100, "default", kNoExpirationYear, 1, 1, - base::FieldTrial::ONE_TIME_RANDOMIZED, kCustomSeed, nullptr, nullptr), + "one", 100, "default", base::FieldTrial::ONE_TIME_RANDOMIZED, + kCustomSeed, nullptr, nullptr), base::FieldTrialList::FactoryGetFieldTrialWithRandomizationSeed( - "two", 100, "default", kNoExpirationYear, 1, 1, - base::FieldTrial::ONE_TIME_RANDOMIZED, kCustomSeed, nullptr, nullptr), + "two", 100, "default", base::FieldTrial::ONE_TIME_RANDOMIZED, + kCustomSeed, nullptr, nullptr), }; for (size_t i = 0; i < base::size(trials); ++i) { @@ -271,15 +268,14 @@ base::FieldTrialList field_trial_list( std::make_unique<NormalizedMurmurHashEntropyProvider>( 1234, kMaxLowEntropySize)); - const int kNoExpirationYear = base::FieldTrialList::kNoExpirationYear; const uint32_t kCustomSeed = 9001; scoped_refptr<base::FieldTrial> trials[] = { base::FieldTrialList::FactoryGetFieldTrialWithRandomizationSeed( - "one", 100, "default", kNoExpirationYear, 1, 1, - base::FieldTrial::ONE_TIME_RANDOMIZED, kCustomSeed, nullptr, nullptr), + "one", 100, "default", base::FieldTrial::ONE_TIME_RANDOMIZED, + kCustomSeed, nullptr, nullptr), base::FieldTrialList::FactoryGetFieldTrialWithRandomizationSeed( - "two", 100, "default", kNoExpirationYear, 1, 1, - base::FieldTrial::ONE_TIME_RANDOMIZED, kCustomSeed, nullptr, nullptr), + "two", 100, "default", base::FieldTrial::ONE_TIME_RANDOMIZED, + kCustomSeed, nullptr, nullptr), }; for (size_t i = 0; i < base::size(trials); ++i) {
diff --git a/components/variations/variations_associated_data_unittest.cc b/components/variations/variations_associated_data_unittest.cc index 71602a8f..6a91b69 100644 --- a/components/variations/variations_associated_data_unittest.cc +++ b/components/variations/variations_associated_data_unittest.cc
@@ -21,7 +21,7 @@ return GetGoogleVariationID(key, trial->trial_name(), trial->group_name()); } -// Call FieldTrialList::FactoryGetFieldTrial() with a future expiry date. +// Call FieldTrialList::FactoryGetFieldTrial(). scoped_refptr<base::FieldTrial> CreateFieldTrial( const std::string& trial_name, int total_probability, @@ -29,7 +29,6 @@ int* default_group_number) { return base::FieldTrialList::FactoryGetFieldTrial( trial_name, total_probability, default_group_name, - base::FieldTrialList::kNoExpirationYear, 1, 1, base::FieldTrial::SESSION_RANDOMIZED, default_group_number); }
diff --git a/components/variations/variations_seed_processor.cc b/components/variations/variations_seed_processor.cc index 653cf29..2a61928 100644 --- a/components/variations/variations_seed_processor.cc +++ b/components/variations/variations_seed_processor.cc
@@ -253,8 +253,7 @@ scoped_refptr<base::FieldTrial> trial( base::FieldTrialList::FactoryGetFieldTrialWithRandomizationSeed( study.name(), processed_study.total_probability(), - processed_study.GetDefaultExperimentName(), - base::FieldTrialList::kNoExpirationYear, 1, 1, randomization_type, + processed_study.GetDefaultExperimentName(), randomization_type, randomization_seed, nullptr, ShouldStudyUseLowEntropy(study) ? low_entropy_provider : nullptr));
diff --git a/components/variations/variations_seed_processor_unittest.cc b/components/variations/variations_seed_processor_unittest.cc index f41d36e..5a6e7bbd 100644 --- a/components/variations/variations_seed_processor_unittest.cc +++ b/components/variations/variations_seed_processor_unittest.cc
@@ -896,8 +896,8 @@ // group than the study config, which is expired. This tests that we don't // crash in such a case. auto* trial = base::FieldTrialList::FactoryGetFieldTrial( - "Study1", 100, "ExistingDefault", base::FieldTrialList::kNoExpirationYear, - 1, 1, base::FieldTrial::SESSION_RANDOMIZED, nullptr); + "Study1", 100, "ExistingDefault", base::FieldTrial::SESSION_RANDOMIZED, + nullptr); trial->AppendGroup("A", 100); trial->SetForced();
diff --git a/components/web_resource/web_resource_service.cc b/components/web_resource/web_resource_service.cc index 22fc070..85e2f6c 100644 --- a/components/web_resource/web_resource_service.cc +++ b/components/web_resource/web_resource_service.cc
@@ -83,11 +83,12 @@ if (response_body->empty() || *response_body == "{}") { OnUnpackFinished(base::Value(base::Value::Type::DICTIONARY)); } else { - parse_json_callback_.Run(*response_body, - base::Bind(&WebResourceService::OnUnpackFinished, - weak_ptr_factory_.GetWeakPtr()), - base::Bind(&WebResourceService::OnUnpackError, - weak_ptr_factory_.GetWeakPtr())); + parse_json_callback_.Run( + *response_body, + base::BindOnce(&WebResourceService::OnUnpackFinished, + weak_ptr_factory_.GetWeakPtr()), + base::BindOnce(&WebResourceService::OnUnpackError, + weak_ptr_factory_.GetWeakPtr())); } } else { // Don't parse data if attempt to download was unsuccessful.
diff --git a/components/web_resource/web_resource_service.h b/components/web_resource/web_resource_service.h index 749b4bc..61295f1 100644 --- a/components/web_resource/web_resource_service.h +++ b/components/web_resource/web_resource_service.h
@@ -37,10 +37,10 @@ class WebResourceService : public ResourceRequestAllowedNotifier::Observer { public: // Callbacks for JSON parsing. - using SuccessCallback = base::Callback<void(base::Value)>; - using ErrorCallback = base::Callback<void(const std::string&)>; - using ParseJSONCallback = base::Callback< - void(const std::string&, const SuccessCallback&, const ErrorCallback&)>; + using SuccessCallback = base::OnceCallback<void(base::Value)>; + using ErrorCallback = base::OnceCallback<void(const std::string&)>; + using ParseJSONCallback = base::RepeatingCallback< + void(const std::string&, SuccessCallback, ErrorCallback)>; // Creates a new WebResourceService. // If |application_locale| is not empty, it will be appended as a locale
diff --git a/components/web_resource/web_resource_service_unittest.cc b/components/web_resource/web_resource_service_unittest.cc index 00f3f22..cfb127c 100644 --- a/components/web_resource/web_resource_service_unittest.cc +++ b/components/web_resource/web_resource_service_unittest.cc
@@ -129,12 +129,12 @@ } static void Parse(const std::string& unsafe_json, - const WebResourceService::SuccessCallback& success_callback, - const WebResourceService::ErrorCallback& error_callback) { + WebResourceService::SuccessCallback success_callback, + WebResourceService::ErrorCallback error_callback) { if (!error_message_.empty()) - error_callback.Run(error_message_); + std::move(error_callback).Run(error_message_); else - success_callback.Run(base::Value()); + std::move(success_callback).Run(base::Value()); } WebResourceService* web_resource_service() {
diff --git a/content/browser/background_fetch/background_fetch_test_data_manager.cc b/content/browser/background_fetch/background_fetch_test_data_manager.cc index 27f5de6..5f9cf90 100644 --- a/content/browser/background_fetch/background_fetch_test_data_manager.cc +++ b/content/browser/background_fetch/background_fetch_test_data_manager.cc
@@ -71,7 +71,8 @@ cache_manager_ = CacheStorageManager::Create( storage_partition_->GetPath(), base::ThreadTaskRunnerHandle::Get(), - base::ThreadTaskRunnerHandle::Get(), quota_manager_proxy_); + base::ThreadTaskRunnerHandle::Get(), quota_manager_proxy_, + base::MakeRefCounted<CacheStorageContextImpl::ObserverList>()); DCHECK(cache_manager_); cache_manager_->SetBlobParametersForCache(
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index 80a9629..c196ecc5f 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -1627,9 +1627,9 @@ if (base::FeatureList::IsEnabled(features::kAudioServiceLaunchOnStartup)) { // Schedule the audio service startup on the main thread. - BrowserThread::PostAfterStartupTask( + base::PostTaskWithTraits( FROM_HERE, - base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}), + {content::BrowserThread::UI, base::TaskPriority::BEST_EFFORT}, base::BindOnce([]() { TRACE_EVENT0("audio", "Starting audio service"); ServiceManagerConnection* connection =
diff --git a/content/browser/cache_storage/cache_storage_context_impl.cc b/content/browser/cache_storage/cache_storage_context_impl.cc index bbb1e00..bf24b93 100644 --- a/content/browser/cache_storage/cache_storage_context_impl.cc +++ b/content/browser/cache_storage/cache_storage_context_impl.cc
@@ -25,7 +25,8 @@ CacheStorageContextImpl::CacheStorageContextImpl( BrowserContext* browser_context) : task_runner_( - base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO})) { + base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO})), + observers_(base::MakeRefCounted<ObserverList>()) { DCHECK_CURRENTLY_ON(BrowserThread::UI); } @@ -136,16 +137,14 @@ void CacheStorageContextImpl::AddObserver( CacheStorageContextImpl::Observer* observer) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (cache_manager_) - cache_manager_->AddObserver(observer); + // Any sequence + observers_->AddObserver(observer); } void CacheStorageContextImpl::RemoveObserver( CacheStorageContextImpl::Observer* observer) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (cache_manager_) - cache_manager_->RemoveObserver(observer); + // Any sequence + observers_->RemoveObserver(observer); } void CacheStorageContextImpl::CreateCacheStorageManager( @@ -157,7 +156,7 @@ DCHECK(!cache_manager_); cache_manager_ = CacheStorageManager::Create( user_data_directory, std::move(cache_task_runner), task_runner_, - std::move(quota_manager_proxy)); + std::move(quota_manager_proxy), observers_); } void CacheStorageContextImpl::ShutdownOnTaskRunner() {
diff --git a/content/browser/cache_storage/cache_storage_context_impl.h b/content/browser/cache_storage/cache_storage_context_impl.h index d3840fa..d9f1e70 100644 --- a/content/browser/cache_storage/cache_storage_context_impl.h +++ b/content/browser/cache_storage/cache_storage_context_impl.h
@@ -10,6 +10,7 @@ #include "base/files/file_path.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_refptr.h" +#include "base/observer_list_threadsafe.h" #include "base/threading/sequence_bound.h" #include "content/common/content_export.h" #include "content/public/browser/cache_storage_context.h" @@ -54,6 +55,8 @@ virtual ~Observer() {} }; + using ObserverList = base::ObserverListThreadSafe<Observer>; + // Init and Shutdown are for use on the UI thread when the profile, // storagepartition is being setup and torn down. void Init(const base::FilePath& user_data_directory, @@ -80,7 +83,7 @@ void GetAllOriginsInfo(GetUsageInfoCallback callback) override; void DeleteForOrigin(const GURL& origin) override; - // Only callable on the IO thread. + // Callable on any sequence. void AddObserver(CacheStorageContextImpl::Observer* observer); void RemoveObserver(CacheStorageContextImpl::Observer* observer); @@ -100,6 +103,7 @@ // Initialized at construction. const scoped_refptr<base::SequencedTaskRunner> task_runner_; + const scoped_refptr<ObserverList> observers_; // Initialized in Init(); true if the user data directory is empty. bool is_incognito_ = false;
diff --git a/content/browser/cache_storage/cache_storage_manager.cc b/content/browser/cache_storage/cache_storage_manager.cc index 9440a4a..8139a10 100644 --- a/content/browser/cache_storage/cache_storage_manager.cc +++ b/content/browser/cache_storage/cache_storage_manager.cc
@@ -159,7 +159,8 @@ const base::FilePath& path, scoped_refptr<base::SequencedTaskRunner> cache_task_runner, scoped_refptr<base::SequencedTaskRunner> scheduler_task_runner, - scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy) { + scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, + scoped_refptr<CacheStorageContextImpl::ObserverList> observers) { base::FilePath root_path = path; if (!path.empty()) { root_path = path.Append(ServiceWorkerContextCore::kServiceWorkerDirectory) @@ -168,18 +169,16 @@ return base::WrapRefCounted(new CacheStorageManager( root_path, std::move(cache_task_runner), std::move(scheduler_task_runner), - std::move(quota_manager_proxy))); + std::move(quota_manager_proxy), std::move(observers))); } // static -scoped_refptr<CacheStorageManager> CacheStorageManager::Create( +scoped_refptr<CacheStorageManager> CacheStorageManager::CreateForTesting( CacheStorageManager* old_manager) { scoped_refptr<CacheStorageManager> manager(new CacheStorageManager( old_manager->root_path(), old_manager->cache_task_runner(), old_manager->scheduler_task_runner(), - old_manager->quota_manager_proxy_.get())); - // These values may be NULL, in which case this will be called again later by - // the dispatcher host per usual. + old_manager->quota_manager_proxy_.get(), old_manager->observers_)); manager->SetBlobParametersForCache(old_manager->blob_storage_context()); return manager; } @@ -220,26 +219,17 @@ blob_context_ = blob_storage_context; } -void CacheStorageManager::AddObserver( - CacheStorageContextImpl::Observer* observer) { - DCHECK(!observers_.HasObserver(observer)); - observers_.AddObserver(observer); -} - -void CacheStorageManager::RemoveObserver( - CacheStorageContextImpl::Observer* observer) { - observers_.RemoveObserver(observer); -} - void CacheStorageManager::NotifyCacheListChanged(const url::Origin& origin) { - for (auto& observer : observers_) - observer.OnCacheListChanged(origin); + observers_->Notify(FROM_HERE, + &CacheStorageContextImpl::Observer::OnCacheListChanged, + origin); } void CacheStorageManager::NotifyCacheContentChanged(const url::Origin& origin, const std::string& name) { - for (auto& observer : observers_) - observer.OnCacheContentChanged(origin, name); + observers_->Notify(FROM_HERE, + &CacheStorageContextImpl::Observer::OnCacheContentChanged, + origin, name); } void CacheStorageManager::CacheStorageUnreferenced( @@ -448,11 +438,13 @@ const base::FilePath& path, scoped_refptr<base::SequencedTaskRunner> cache_task_runner, scoped_refptr<base::SequencedTaskRunner> scheduler_task_runner, - scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy) + scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, + scoped_refptr<CacheStorageContextImpl::ObserverList> observers) : root_path_(path), cache_task_runner_(std::move(cache_task_runner)), scheduler_task_runner_(std::move(scheduler_task_runner)), quota_manager_proxy_(std::move(quota_manager_proxy)), + observers_(std::move(observers)), weak_ptr_factory_(this) { if (quota_manager_proxy_.get()) { quota_manager_proxy_->RegisterClient(new CacheStorageQuotaClient(
diff --git a/content/browser/cache_storage/cache_storage_manager.h b/content/browser/cache_storage/cache_storage_manager.h index ad29f617..d601ec6 100644 --- a/content/browser/cache_storage/cache_storage_manager.h +++ b/content/browser/cache_storage/cache_storage_manager.h
@@ -65,9 +65,13 @@ const base::FilePath& path, scoped_refptr<base::SequencedTaskRunner> cache_task_runner, scoped_refptr<base::SequencedTaskRunner> scheduler_task_runner, - scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy); + scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, + scoped_refptr<CacheStorageContextImpl::ObserverList> observers); - static scoped_refptr<CacheStorageManager> Create( + // Create a new manager using the underlying configuration of the given + // manager, but with its own list of storage objects. This is only used + // for testing. + static scoped_refptr<CacheStorageManager> CreateForTesting( CacheStorageManager* old_manager); // Map a database identifier (computed from an origin) to the path. @@ -85,9 +89,6 @@ void SetBlobParametersForCache( base::WeakPtr<storage::BlobStorageContext> blob_storage_context); - void AddObserver(CacheStorageContextImpl::Observer* observer); - void RemoveObserver(CacheStorageContextImpl::Observer* observer); - void NotifyCacheListChanged(const url::Origin& origin); void NotifyCacheContentChanged(const url::Origin& origin, const std::string& name); @@ -122,7 +123,8 @@ const base::FilePath& path, scoped_refptr<base::SequencedTaskRunner> cache_task_runner, scoped_refptr<base::SequencedTaskRunner> scheduler_task_runner, - scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy); + scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, + scoped_refptr<CacheStorageContextImpl::ObserverList> observers); virtual ~CacheStorageManager(); @@ -179,7 +181,7 @@ // |cache_task_runner_|. CacheStorageMap cache_storage_map_; - base::ObserverList<CacheStorageContextImpl::Observer>::Unchecked observers_; + scoped_refptr<CacheStorageContextImpl::ObserverList> observers_; base::WeakPtr<storage::BlobStorageContext> blob_context_;
diff --git a/content/browser/cache_storage/cache_storage_manager_unittest.cc b/content/browser/cache_storage/cache_storage_manager_unittest.cc index 77737d1..7d87a2c 100644 --- a/content/browser/cache_storage/cache_storage_manager_unittest.cc +++ b/content/browser/cache_storage/cache_storage_manager_unittest.cc
@@ -196,17 +196,29 @@ class TestCacheStorageObserver : public CacheStorageContextImpl::Observer { public: + TestCacheStorageObserver() : loop_(std::make_unique<base::RunLoop>()) {} + void OnCacheListChanged(const url::Origin& origin) override { ++notify_list_changed_count; + loop_->Quit(); } void OnCacheContentChanged(const url::Origin& origin, const std::string& cache_name) override { ++notify_content_changed_count; + loop_->Quit(); } + void Wait() { + loop_->Run(); + loop_ = std::make_unique<base::RunLoop>(); + } + + base::OnceClosure callback; int notify_list_changed_count = 0; int notify_content_changed_count = 0; + + std::unique_ptr<base::RunLoop> loop_; }; class CacheStorageManagerTest : public testing::Test { @@ -214,6 +226,8 @@ CacheStorageManagerTest() : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP), blob_storage_context_(nullptr), + observers_( + base::MakeRefCounted<CacheStorageContextImpl::ObserverList>()), callback_bool_(false), callback_error_(CacheStorageError::kSuccess), origin1_(url::Origin::Create(GURL("http://example1.com"))), @@ -325,7 +339,7 @@ cache_manager_ = CacheStorageManager::Create( temp_dir_path, base::ThreadTaskRunnerHandle::Get(), - base::ThreadTaskRunnerHandle::Get(), quota_manager_proxy_); + base::ThreadTaskRunnerHandle::Get(), quota_manager_proxy_, observers_); cache_manager_->SetBlobParametersForCache( blob_storage_context->context()->AsWeakPtr()); @@ -733,6 +747,7 @@ scoped_refptr<MockSpecialStoragePolicy> quota_policy_; scoped_refptr<MockQuotaManager> mock_quota_manager_; scoped_refptr<MockCacheStorageQuotaManagerProxy> quota_manager_proxy_; + scoped_refptr<CacheStorageContextImpl::ObserverList> observers_; scoped_refptr<CacheStorageManager> cache_manager_; CacheStorageCacheHandle callback_cache_handle_; @@ -1070,7 +1085,7 @@ EXPECT_TRUE(Open(origin2_, "raz")); EXPECT_TRUE(Delete(origin1_, "bar")); quota_manager_proxy_->SimulateQuotaManagerDestroyed(); - cache_manager_ = CacheStorageManager::Create(cache_manager_.get()); + cache_manager_ = CacheStorageManager::CreateForTesting(cache_manager_.get()); EXPECT_EQ(2u, Keys(origin1_)); std::vector<std::string> expected_keys; expected_keys.push_back("foo"); @@ -1082,7 +1097,7 @@ EXPECT_TRUE(Open(origin1_, "foo")); EXPECT_TRUE(Open(origin2_, "baz")); quota_manager_proxy_->SimulateQuotaManagerDestroyed(); - cache_manager_ = CacheStorageManager::Create(cache_manager_.get()); + cache_manager_ = CacheStorageManager::CreateForTesting(cache_manager_.get()); EXPECT_EQ(0u, Keys(origin1_)); } @@ -1383,7 +1398,7 @@ // Create a new CacheStorageManager that hasn't yet loaded the origin. CreateStorageManager(); quota_manager_proxy_->SimulateQuotaManagerDestroyed(); - cache_manager_ = CacheStorageManager::Create(cache_manager_.get()); + cache_manager_ = CacheStorageManager::CreateForTesting(cache_manager_.get()); EXPECT_TRUE(Open(origin1_, kCacheName)); base::RunLoop().RunUntilIdle(); @@ -1455,7 +1470,7 @@ // Create a new CacheStorageManager that hasn't yet loaded the origin. CreateStorageManager(); quota_manager_proxy_->SimulateQuotaManagerDestroyed(); - cache_manager_ = CacheStorageManager::Create(cache_manager_.get()); + cache_manager_ = CacheStorageManager::CreateForTesting(cache_manager_.get()); // Reopening the origin/cache creates a new CacheStorage instance with a new // random key. @@ -1649,7 +1664,7 @@ // Create a new CacheStorageManager that hasn't yet loaded the origin. CreateStorageManager(); quota_manager_proxy_->SimulateQuotaManagerDestroyed(); - cache_manager_ = CacheStorageManager::Create(cache_manager_.get()); + cache_manager_ = CacheStorageManager::CreateForTesting(cache_manager_.get()); // Create a second value (V2) in the cache. EXPECT_TRUE(Open(origin1_, kCacheName)); @@ -1717,7 +1732,7 @@ // Create a new CacheStorageManager that hasn't yet loaded the origin. CreateStorageManager(); quota_manager_proxy_->SimulateQuotaManagerDestroyed(); - cache_manager_ = CacheStorageManager::Create(cache_manager_.get()); + cache_manager_ = CacheStorageManager::CreateForTesting(cache_manager_.get()); // Reopen the cache and write a second value (V2). EXPECT_TRUE(Open(origin1_, kCacheName)); @@ -1819,7 +1834,7 @@ // Create a new StorageManager so that the next time the cache is opened // the unreferenced directory can be deleted. quota_manager_proxy_->SimulateQuotaManagerDestroyed(); - cache_manager_ = CacheStorageManager::Create(cache_manager_.get()); + cache_manager_ = CacheStorageManager::CreateForTesting(cache_manager_.get()); // Verify that the referenced cache still works. EXPECT_TRUE(Open(origin1_, "foo")); @@ -1882,97 +1897,121 @@ TEST_P(CacheStorageManagerTestP, NotifyCacheListChanged_Created) { TestCacheStorageObserver observer; - cache_manager_->AddObserver(&observer); + observers_->AddObserver(&observer); EXPECT_EQ(0, observer.notify_list_changed_count); EXPECT_TRUE(Open(origin1_, "foo")); + observer.Wait(); EXPECT_EQ(1, observer.notify_list_changed_count); EXPECT_TRUE( CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo"))); + observer.Wait(); EXPECT_EQ(1, observer.notify_list_changed_count); } TEST_P(CacheStorageManagerTestP, NotifyCacheListChanged_Deleted) { TestCacheStorageObserver observer; - cache_manager_->AddObserver(&observer); + observers_->AddObserver(&observer); EXPECT_EQ(0, observer.notify_list_changed_count); EXPECT_FALSE(Delete(origin1_, "foo")); + // Give any unexpected observer tasks a chance to run. + base::RunLoop().RunUntilIdle(); EXPECT_EQ(0, observer.notify_list_changed_count); EXPECT_TRUE(Open(origin1_, "foo")); + observer.Wait(); EXPECT_EQ(1, observer.notify_list_changed_count); EXPECT_TRUE(Delete(origin1_, "foo")); + observer.Wait(); EXPECT_EQ(2, observer.notify_list_changed_count); } TEST_P(CacheStorageManagerTestP, NotifyCacheListChanged_DeletedThenCreated) { TestCacheStorageObserver observer; - cache_manager_->AddObserver(&observer); + observers_->AddObserver(&observer); EXPECT_EQ(0, observer.notify_list_changed_count); EXPECT_TRUE(Open(origin1_, "foo")); + observer.Wait(); EXPECT_EQ(1, observer.notify_list_changed_count); EXPECT_TRUE(Delete(origin1_, "foo")); + observer.Wait(); EXPECT_EQ(2, observer.notify_list_changed_count); EXPECT_TRUE(Open(origin2_, "foo2")); + observer.Wait(); EXPECT_EQ(3, observer.notify_list_changed_count); } TEST_P(CacheStorageManagerTestP, NotifyCacheContentChanged_PutEntry) { TestCacheStorageObserver observer; - cache_manager_->AddObserver(&observer); + observers_->AddObserver(&observer); EXPECT_EQ(0, observer.notify_content_changed_count); EXPECT_TRUE(Open(origin1_, "foo")); + observer.Wait(); EXPECT_EQ(0, observer.notify_content_changed_count); EXPECT_TRUE( CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo"))); + observer.Wait(); EXPECT_EQ(1, observer.notify_content_changed_count); EXPECT_TRUE(CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo1"))); + observer.Wait(); EXPECT_TRUE(CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo2"))); + observer.Wait(); EXPECT_EQ(3, observer.notify_content_changed_count); } TEST_P(CacheStorageManagerTestP, NotifyCacheContentChanged_DeleteEntry) { TestCacheStorageObserver observer; - cache_manager_->AddObserver(&observer); + observers_->AddObserver(&observer); EXPECT_EQ(0, observer.notify_content_changed_count); EXPECT_FALSE(Delete(origin1_, "foo")); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(0, observer.notify_content_changed_count); EXPECT_TRUE(Open(origin1_, "foo")); + observer.Wait(); EXPECT_EQ(0, observer.notify_content_changed_count); EXPECT_TRUE( CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo"))); + observer.Wait(); EXPECT_EQ(1, observer.notify_content_changed_count); EXPECT_TRUE(CacheDelete(callback_cache_handle_.value(), GURL("http://example.com/foo"))); + observer.Wait(); EXPECT_EQ(2, observer.notify_content_changed_count); EXPECT_FALSE(CacheDelete(callback_cache_handle_.value(), GURL("http://example.com/foo"))); + // Give any unexpected observer tasks a chance to run. + base::RunLoop().RunUntilIdle(); EXPECT_EQ(2, observer.notify_content_changed_count); } TEST_P(CacheStorageManagerTestP, NotifyCacheContentChanged_DeleteThenPutEntry) { TestCacheStorageObserver observer; - cache_manager_->AddObserver(&observer); + observers_->AddObserver(&observer); EXPECT_EQ(0, observer.notify_content_changed_count); EXPECT_TRUE(Open(origin1_, "foo")); + observer.Wait(); EXPECT_EQ(0, observer.notify_content_changed_count); EXPECT_TRUE( CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo"))); + observer.Wait(); EXPECT_EQ(1, observer.notify_content_changed_count); EXPECT_TRUE(CacheDelete(callback_cache_handle_.value(), GURL("http://example.com/foo"))); + observer.Wait(); EXPECT_EQ(2, observer.notify_content_changed_count); EXPECT_TRUE( CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo"))); + observer.Wait(); EXPECT_EQ(3, observer.notify_content_changed_count); EXPECT_TRUE(CacheDelete(callback_cache_handle_.value(), GURL("http://example.com/foo"))); + observer.Wait(); EXPECT_EQ(4, observer.notify_content_changed_count); } @@ -2385,7 +2424,7 @@ // Create a new CacheStorageManager that hasn't yet loaded the origin. quota_manager_proxy_->SimulateQuotaManagerDestroyed(); - cache_manager_ = CacheStorageManager::Create(cache_manager_.get()); + cache_manager_ = CacheStorageManager::CreateForTesting(cache_manager_.get()); quota_client_.reset(new CacheStorageQuotaClient( cache_manager_->AsWeakPtr(), CacheStorageOwner::kCacheAPI));
diff --git a/content/browser/devtools/protocol/storage_handler.cc b/content/browser/devtools/protocol/storage_handler.cc index 84ff5fc..a6586fa 100644 --- a/content/browser/devtools/protocol/storage_handler.cc +++ b/content/browser/devtools/protocol/storage_handler.cc
@@ -110,55 +110,44 @@ CacheStorageObserver(base::WeakPtr<StorageHandler> owner_storage_handler, CacheStorageContextImpl* cache_storage_context) : owner_(owner_storage_handler), context_(cache_storage_context) { - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&CacheStorageObserver::AddObserverOnIOThread, - base::Unretained(this))); + DCHECK_CURRENTLY_ON(BrowserThread::UI); + context_->AddObserver(this); } ~CacheStorageObserver() override { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK_CURRENTLY_ON(BrowserThread::UI); context_->RemoveObserver(this); } - void TrackOriginOnIOThread(const url::Origin& origin) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + void TrackOrigin(const url::Origin& origin) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (origins_.find(origin) != origins_.end()) return; origins_.insert(origin); } - void UntrackOriginOnIOThread(const url::Origin& origin) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + void UntrackOrigin(const url::Origin& origin) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); origins_.erase(origin); } void OnCacheListChanged(const url::Origin& origin) override { + DCHECK_CURRENTLY_ON(BrowserThread::UI); auto found = origins_.find(origin); if (found == origins_.end()) return; - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&StorageHandler::NotifyCacheStorageListChanged, owner_, - origin.Serialize())); + owner_->NotifyCacheStorageListChanged(origin.Serialize()); } void OnCacheContentChanged(const url::Origin& origin, const std::string& cache_name) override { + DCHECK_CURRENTLY_ON(BrowserThread::UI); if (origins_.find(origin) == origins_.end()) return; - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::UI}, - base::BindOnce(&StorageHandler::NotifyCacheStorageContentChanged, - owner_, origin.Serialize(), cache_name)); + owner_->NotifyCacheStorageContentChanged(origin.Serialize(), cache_name); } private: - void AddObserverOnIOThread() { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - context_->AddObserver(this); - } - // Maintained on the IO thread to avoid thread contention. base::flat_set<url::Origin> origins_; @@ -265,10 +254,7 @@ } Response StorageHandler::Disable() { - if (cache_storage_observer_) { - BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, - cache_storage_observer_.release()); - } + cache_storage_observer_.reset(); if (indexed_db_observer_) { scoped_refptr<base::SequencedTaskRunner> observer_task_runner = indexed_db_observer_->TaskRunner(); @@ -350,11 +336,7 @@ if (!origin_url.is_valid()) return Response::InvalidParams(origin + " is not a valid URL"); - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&CacheStorageObserver::TrackOriginOnIOThread, - base::Unretained(GetCacheStorageObserver()), - url::Origin::Create(origin_url))); + GetCacheStorageObserver()->TrackOrigin(url::Origin::Create(origin_url)); return Response::OK(); } @@ -367,11 +349,7 @@ if (!origin_url.is_valid()) return Response::InvalidParams(origin + " is not a valid URL"); - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&CacheStorageObserver::UntrackOriginOnIOThread, - base::Unretained(GetCacheStorageObserver()), - url::Origin::Create(origin_url))); + GetCacheStorageObserver()->UntrackOrigin(url::Origin::Create(origin_url)); return Response::OK(); }
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc index 25f8796..a115e10d 100644 --- a/content/browser/frame_host/navigation_controller_impl.cc +++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -2137,7 +2137,8 @@ bool NavigationControllerImpl::StartHistoryNavigationInNewSubframe( RenderFrameHostImpl* render_frame_host, - const GURL& default_url) { + const GURL& default_url, + mojom::NavigationClientAssociatedPtrInfo* navigation_client) { NavigationEntryImpl* entry = GetEntryWithUniqueID(render_frame_host->nav_entry_id()); if (!entry) @@ -2176,6 +2177,9 @@ if (!request) return false; + request->SetNavigationClient(std::move(*navigation_client), + render_frame_host->GetSiteInstance()->GetId()); + render_frame_host->frame_tree_node()->navigator()->Navigate( std::move(request), ReloadType::NONE, RestoreType::NONE); @@ -3103,15 +3107,15 @@ params.load_type == LOAD_TYPE_HTTP_POST ? "POST" : "GET", params.post_data, base::Optional<SourceLocation>(), params.started_from_context_menu, has_user_gesture, InitiatorCSPInfo(), - params.href_translate, params.input_start); + params.href_translate, + false /* is_history_navigation_in_new_child_frame */, params.input_start); CommitNavigationParams commit_params( frame_entry->committed_origin(), override_user_agent, params.redirect_chain, common_params.url, common_params.method, params.can_load_local_resources, frame_entry->page_state(), - entry->GetUniqueID(), false /* is_history_navigation_in_new_child */, - entry->GetSubframeUniqueNames(node), true /* intended_as_new_entry */, - -1 /* pending_history_list_offset */, + entry->GetUniqueID(), entry->GetSubframeUniqueNames(node), + true /* intended_as_new_entry */, -1 /* pending_history_list_offset */, params.should_clear_history_list ? -1 : GetLastCommittedEntryIndex(), params.should_clear_history_list ? 0 : GetEntryCount(), is_view_source_mode, params.should_clear_history_list); @@ -3143,7 +3147,7 @@ FrameNavigationEntry* frame_entry, ReloadType reload_type, bool is_same_document_history_load, - bool is_history_navigation_in_new_child) { + bool is_history_navigation_in_new_child_frame) { GURL dest_url = frame_entry->url(); base::Optional<url::Origin> origin_to_commit = frame_entry->committed_origin(); @@ -3218,13 +3222,14 @@ CommonNavigationParams common_params = entry->ConstructCommonNavigationParams( *frame_entry, request_body, dest_url, dest_referrer, navigation_type, previews_state, navigation_start, base::TimeTicks() /* input_start */); + common_params.is_history_navigation_in_new_child_frame = + is_history_navigation_in_new_child_frame; // TODO(clamy): |intended_as_new_entry| below should always be false once // Reload no longer leads to this being called for a pending NavigationEntry // of index -1. CommitNavigationParams commit_params = entry->ConstructCommitNavigationParams( *frame_entry, common_params.url, origin_to_commit, common_params.method, - is_history_navigation_in_new_child, entry->GetSubframeUniqueNames(frame_tree_node), GetPendingEntryIndex() == -1 /* intended_as_new_entry */, GetIndexOfEntry(entry), GetLastCommittedEntryIndex(), GetEntryCount());
diff --git a/content/browser/frame_host/navigation_controller_impl.h b/content/browser/frame_host/navigation_controller_impl.h index e14e48f..f491545 100644 --- a/content/browser/frame_host/navigation_controller_impl.h +++ b/content/browser/frame_host/navigation_controller_impl.h
@@ -99,7 +99,8 @@ // navigation to |default_url| should be done instead. bool StartHistoryNavigationInNewSubframe( RenderFrameHostImpl* render_frame_host, - const GURL& default_url); + const GURL& default_url, + mojom::NavigationClientAssociatedPtrInfo* navigation_client); // Navigates to a specified offset from the "current entry". Currently records // a histogram indicating whether the session history navigation would only @@ -353,7 +354,7 @@ FrameNavigationEntry* frame_entry, ReloadType reload_type, bool is_same_document_history_load, - bool is_history_navigation_in_new_child); + bool is_history_navigation_in_new_child_frame); // Returns whether there is a pending NavigationEntry whose unique ID matches // the given NavigationHandle's pending_nav_entry_id.
diff --git a/content/browser/frame_host/navigation_entry_impl.cc b/content/browser/frame_host/navigation_entry_impl.cc index 85482344..f35daf5 100644 --- a/content/browser/frame_host/navigation_entry_impl.cc +++ b/content/browser/frame_host/navigation_entry_impl.cc
@@ -680,7 +680,8 @@ GetHistoryURLForDataURL(), previews_state, navigation_start, frame_entry.method(), post_body ? post_body : post_data_, base::Optional<SourceLocation>(), has_started_from_context_menu(), - has_user_gesture(), InitiatorCSPInfo(), std::string(), input_start); + has_user_gesture(), InitiatorCSPInfo(), std::string(), + false /* is_history_navigation_in_new_child_frame */, input_start); } CommitNavigationParams NavigationEntryImpl::ConstructCommitNavigationParams( @@ -688,7 +689,6 @@ const GURL& original_url, const base::Optional<url::Origin>& origin_to_commit, const std::string& original_method, - bool is_history_navigation_in_new_child, const std::map<std::string, bool>& subframe_unique_names, bool intended_as_new_entry, int pending_history_list_offset, @@ -716,9 +716,9 @@ CommitNavigationParams commit_params( origin_to_commit, GetIsOverridingUserAgent(), redirects, original_url, original_method, GetCanLoadLocalResources(), frame_entry.page_state(), - GetUniqueID(), is_history_navigation_in_new_child, subframe_unique_names, - intended_as_new_entry, pending_offset_to_send, current_offset_to_send, - current_length_to_send, IsViewSourceMode(), should_clear_history_list()); + GetUniqueID(), subframe_unique_names, intended_as_new_entry, + pending_offset_to_send, current_offset_to_send, current_length_to_send, + IsViewSourceMode(), should_clear_history_list()); #if defined(OS_ANDROID) if (NavigationControllerImpl::ValidateDataURLAsString(GetDataURLAsString())) { commit_params.data_url_as_string = GetDataURLAsString()->data();
diff --git a/content/browser/frame_host/navigation_entry_impl.h b/content/browser/frame_host/navigation_entry_impl.h index f7f3b75f..4323013c 100644 --- a/content/browser/frame_host/navigation_entry_impl.h +++ b/content/browser/frame_host/navigation_entry_impl.h
@@ -189,7 +189,6 @@ const GURL& original_url, const base::Optional<url::Origin>& origin_to_commit, const std::string& original_method, - bool is_history_navigation_in_new_child, const std::map<std::string, bool>& subframe_unique_names, bool intended_as_new_entry, int pending_offset_to_send,
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index c633e38a..c1f46d0 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -509,7 +509,6 @@ false, // can_load_local_resources PageState(), // page_state 0, // nav_entry_id - false, // is_history_navigation_in_new_child std::map<std::string, bool>(), // subframe_unique_names false, // intended_as_new_entry -1, // |pending_history_list_offset| is set to -1 because @@ -553,12 +552,14 @@ base::TimeTicks::Now(), params.method, nullptr, base::Optional<SourceLocation>(), false /* started_from_context_menu */, params.gesture == NavigationGestureUser, InitiatorCSPInfo(), - std::string() /* href_translate */, base::TimeTicks::Now()); + std::string() /* href_translate */, + false /* is_history_navigation_in_new_child_frame */, + base::TimeTicks::Now()); CommitNavigationParams commit_params( params.origin, params.is_overriding_user_agent, params.redirects, params.original_request_url, params.method, false /* can_load_local_resources */, params.page_state, - params.nav_entry_id, false /* is_history_navigation_in_new_child */, + params.nav_entry_id, std::map<std::string, bool>() /* subframe_unique_names */, params.intended_as_new_entry, -1 /* pending_history_list_offset */, -1 /* current_history_list_offset */, @@ -637,14 +638,8 @@ if (IsPerNavigationMojoInterfaceEnabled()) { DCHECK(navigation_client.is_valid()); - request_navigation_client_ = mojom::NavigationClientAssociatedPtr(); - request_navigation_client_.Bind(std::move(navigation_client)); - // Binds the OnAbort callback - HandleInterfaceDisconnection( - &request_navigation_client_, - base::BindOnce(&NavigationRequest::OnRendererAbortedNavigation, - base::Unretained(this))); - associated_site_instance_id_ = source_site_instance_->GetId(); + SetNavigationClient(std::move(navigation_client), + source_site_instance_->GetId()); } } else if (entry) { DCHECK(!navigation_client.is_valid()); @@ -2760,4 +2755,24 @@ navigation_handle_->SetCompleteCallback(std::move(callback)); } +void NavigationRequest::SetNavigationClient( + mojom::NavigationClientAssociatedPtrInfo navigation_client, + int32_t associated_site_instance_id) { + DCHECK(from_begin_navigation_ || + common_params_.is_history_navigation_in_new_child_frame); + DCHECK(!request_navigation_client_); + if (!navigation_client.is_valid()) + return; + + request_navigation_client_ = mojom::NavigationClientAssociatedPtr(); + request_navigation_client_.Bind(std::move(navigation_client)); + + // Binds the OnAbort callback + HandleInterfaceDisconnection( + &request_navigation_client_, + base::BindOnce(&NavigationRequest::OnRendererAbortedNavigation, + base::Unretained(this))); + associated_site_instance_id_ = associated_site_instance_id; +} + } // namespace content
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h index df85f2d..d56e176 100644 --- a/content/browser/frame_host/navigation_request.h +++ b/content/browser/frame_host/navigation_request.h
@@ -419,6 +419,14 @@ Referrer& sanitized_referrer() { return sanitized_referrer_; } + // This should be a private method. The only valid reason to be used + // outside of the class constructor is in the case of an initial history + // navigation in a subframe. This allows a browser-initiated NavigationRequest + // to be canceled by the renderer. + void SetNavigationClient( + mojom::NavigationClientAssociatedPtrInfo navigation_client, + int32_t associated_site_instance_id); + private: // TODO(clamy): Transform NavigationHandleImplTest into NavigationRequestTest // once NavigationHandleImpl has become a wrapper around NavigationRequest.
diff --git a/content/browser/frame_host/navigator.cc b/content/browser/frame_host/navigator.cc index 9d05080..b1106e0 100644 --- a/content/browser/frame_host/navigator.cc +++ b/content/browser/frame_host/navigator.cc
@@ -20,7 +20,8 @@ bool Navigator::StartHistoryNavigationInNewSubframe( RenderFrameHostImpl* render_frame_host, - const GURL& default_url) { + const GURL& default_url, + mojom::NavigationClientAssociatedPtrInfo* navigation_client) { return false; }
diff --git a/content/browser/frame_host/navigator.h b/content/browser/frame_host/navigator.h index f7f6fc2..abc1a57 100644 --- a/content/browser/frame_host/navigator.h +++ b/content/browser/frame_host/navigator.h
@@ -88,7 +88,8 @@ // cases that we use a different URL from history than the frame's src. virtual bool StartHistoryNavigationInNewSubframe( RenderFrameHostImpl* render_frame_host, - const GURL& default_url); + const GURL& default_url, + mojom::NavigationClientAssociatedPtrInfo* navigation_client); // Navigation requests -------------------------------------------------------
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc index 5eca1407..5d8269e 100644 --- a/content/browser/frame_host/navigator_impl.cc +++ b/content/browser/frame_host/navigator_impl.cc
@@ -171,9 +171,10 @@ bool NavigatorImpl::StartHistoryNavigationInNewSubframe( RenderFrameHostImpl* render_frame_host, - const GURL& default_url) { - return controller_->StartHistoryNavigationInNewSubframe(render_frame_host, - default_url); + const GURL& default_url, + mojom::NavigationClientAssociatedPtrInfo* navigation_client) { + return controller_->StartHistoryNavigationInNewSubframe( + render_frame_host, default_url, navigation_client); } void NavigatorImpl::DidNavigate( @@ -339,7 +340,7 @@ bool should_dispatch_beforeunload = !FrameMsg_Navigate_Type::IsSameDocument( request->common_params().navigation_type) && - !request->commit_params().is_history_navigation_in_new_child && + !request->common_params().is_history_navigation_in_new_child_frame && frame_tree_node->current_frame_host()->ShouldDispatchBeforeUnload( false /* check_subframes_only */); @@ -594,14 +595,26 @@ // This is a renderer-initiated navigation. DCHECK(frame_tree_node); + if (common_params.is_history_navigation_in_new_child_frame) { + // Try to find a FrameNavigationEntry that matches this frame instead, based + // on the frame's unique name. If this can't be found, fall back to the + // default path below. + if (frame_tree_node->navigator()->StartHistoryNavigationInNewSubframe( + frame_tree_node->current_frame_host(), common_params.url, + &navigation_client)) { + return; + } + } + NavigationRequest* ongoing_navigation_request = frame_tree_node->navigation_request(); // Client redirects during the initial history navigation of a child frame // should take precedence over the history navigation (despite being renderer- // initiated). See https://crbug.com/348447 and https://crbug.com/691168. - if (ongoing_navigation_request && ongoing_navigation_request->commit_params() - .is_history_navigation_in_new_child) { + if (ongoing_navigation_request && + ongoing_navigation_request->common_params() + .is_history_navigation_in_new_child_frame) { // Preemptively clear this local pointer before deleting the request. ongoing_navigation_request = nullptr; frame_tree_node->ResetNavigationRequest(false, true);
diff --git a/content/browser/frame_host/navigator_impl.h b/content/browser/frame_host/navigator_impl.h index b61f645..7c0db61 100644 --- a/content/browser/frame_host/navigator_impl.h +++ b/content/browser/frame_host/navigator_impl.h
@@ -56,7 +56,8 @@ bool was_within_same_document) override; bool StartHistoryNavigationInNewSubframe( RenderFrameHostImpl* render_frame_host, - const GURL& default_url) override; + const GURL& default_url, + mojom::NavigationClientAssociatedPtrInfo* navigation_client) override; void Navigate(std::unique_ptr<NavigationRequest> request, ReloadType reload_type, RestoreType restore_type) override;
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 25c1ae8..482cf6a 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -2179,16 +2179,6 @@ return; } - if (params.is_history_navigation_in_new_child) { - // Try to find a FrameNavigationEntry that matches this frame instead, based - // on the frame's unique name. If this can't be found, fall back to the - // default params using RequestOpenURL below. - if (frame_tree_node_->navigator()->StartHistoryNavigationInNewSubframe( - this, validated_url)) { - return; - } - } - TRACE_EVENT1("navigation", "RenderFrameHostImpl::OpenURL", "url", validated_url.possibly_invalid_spec()); @@ -4298,7 +4288,8 @@ FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT, download_policy, false, GURL(), GURL(), PREVIEWS_OFF, base::TimeTicks::Now(), "GET", nullptr, base::Optional<SourceLocation>(), false /* started_from_context_menu */, - false /* has_user_gesture */, InitiatorCSPInfo(), std::string()); + false /* has_user_gesture */, InitiatorCSPInfo(), std::string(), + false /* is_history_navigation_in_new_child_frame */); CommitNavigation(nullptr /* navigation_request */, nullptr /* response */, network::mojom::URLLoaderClientEndpointsPtr(), common_params, CommitNavigationParams(), false, base::nullopt,
diff --git a/content/browser/frame_host/render_frame_host_manager_unittest.cc b/content/browser/frame_host/render_frame_host_manager_unittest.cc index 94b8987b..230cfb76 100644 --- a/content/browser/frame_host/render_frame_host_manager_unittest.cc +++ b/content/browser/frame_host/render_frame_host_manager_unittest.cc
@@ -408,7 +408,7 @@ CommitNavigationParams commit_params = entry->ConstructCommitNavigationParams( *frame_entry, common_params.url, frame_entry->committed_origin(), - common_params.method, false, + common_params.method, entry->GetSubframeUniqueNames(frame_tree_node), controller->GetPendingEntryIndex() == -1 /* intended_as_new_entry */, @@ -2870,8 +2870,7 @@ base::TimeTicks::Now(), base::TimeTicks::Now()); CommitNavigationParams commit_params = entry.ConstructCommitNavigationParams( *frame_entry, common_params.url, frame_entry->committed_origin(), - common_params.method, false, - entry.GetSubframeUniqueNames(frame_tree_node), + common_params.method, entry.GetSubframeUniqueNames(frame_tree_node), controller().GetPendingEntryIndex() == -1 /* intended_as_new_entry */, static_cast<NavigationControllerImpl&>(controller()) .GetIndexOfEntry(&entry),
diff --git a/content/browser/navigation_browsertest.cc b/content/browser/navigation_browsertest.cc index e15a5d2e..4761fe8b 100644 --- a/content/browser/navigation_browsertest.cc +++ b/content/browser/navigation_browsertest.cc
@@ -665,7 +665,8 @@ base::TimeTicks::Now() /* navigation_start */, "GET", nullptr /* post_data */, base::Optional<SourceLocation>(), false /* started_from_context_menu */, false /* has_user_gesture */, - InitiatorCSPInfo(), std::string() /* href_translate */); + InitiatorCSPInfo(), std::string() /* href_translate */, + false /* is_history_navigation_in_new_child_frame */); mojom::BeginNavigationParamsPtr begin_params = mojom::BeginNavigationParams::New( std::string() /* headers */, net::LOAD_NORMAL,
diff --git a/content/browser/renderer_host/dwrite_font_lookup_table_builder_win.cc b/content/browser/renderer_host/dwrite_font_lookup_table_builder_win.cc index 7d0d084..e02e585c 100644 --- a/content/browser/renderer_host/dwrite_font_lookup_table_builder_win.cc +++ b/content/browser/renderer_host/dwrite_font_lookup_table_builder_win.cc
@@ -30,6 +30,7 @@ #include "base/trace_event/trace_event.h" #include "base/win/registry.h" #include "content/browser/renderer_host/dwrite_font_file_util_win.h" +#include "content/browser/renderer_host/dwrite_font_proxy_impl_win.h" #include "content/browser/renderer_host/dwrite_font_uma_logging_win.h" #include "content/public/browser/content_browser_client.h" #include "content/public/common/content_features.h" @@ -89,21 +90,6 @@ return true; } -// Used in the BuildFontUniqueNameTable() method to ensure that -// |font_table_built_| is signaled whenever the function exits due to an error -// or otherwise. -class ScopedAutoSignal { - public: - ScopedAutoSignal(base::WaitableEvent* waitable_event) - : waitable_event_(waitable_event) {} - ~ScopedAutoSignal() { waitable_event_->Signal(); } - - private: - base::WaitableEvent* const waitable_event_; - - DISALLOW_COPY_AND_ASSIGN(ScopedAutoSignal); -}; - bool EnsureCacheDirectory(base::FilePath cache_directory) { // If the directory does not exist already, ensure that the parent directory // exists, which is usually the User Data directory. If it exists, we can try @@ -144,7 +130,7 @@ base::ReadOnlySharedMemoryRegion DWriteFontLookupTableBuilder::DuplicateMemoryRegion() { - DCHECK(EnsureFontUniqueNameTable()); + DCHECK(FontUniqueNameTableReady()); return font_table_memory_.region.Duplicate(); } @@ -242,10 +228,29 @@ factory3_.Reset(); } +bool DWriteFontLookupTableBuilder::EnsureFontUniqueNameTableForTesting() { + TRACE_EVENT0("dwrite,fonts", + "DWriteFontLookupTableBuilder::EnsureFontUniqueNameTable"); + DCHECK(base::FeatureList::IsEnabled(features::kFontSrcLocalMatching)); + DCHECK(!HasDWriteUniqueFontLookups()); + base::ScopedAllowBaseSyncPrimitives allow_base_sync_primitives; + font_table_built_.Wait(); + return IsFontUniqueNameTableValid(); +} + base::TimeDelta DWriteFontLookupTableBuilder::IndexingTimeout() { return font_indexing_timeout_; } +void DWriteFontLookupTableBuilder::PostCallbacks() { + for (auto& pending_callback : pending_callbacks_) { + pending_callback.task_runner->PostTask( + FROM_HERE, base::BindOnce(std::move(pending_callback.mojo_callback), + DuplicateMemoryRegion())); + } + pending_callbacks_.clear(); +} + base::FilePath DWriteFontLookupTableBuilder::TableCacheFilePath() { if (!EnsureCacheDirectory(cache_directory_)) return base::FilePath(); @@ -317,17 +322,38 @@ return true; } -bool DWriteFontLookupTableBuilder::EnsureFontUniqueNameTable() { +DWriteFontLookupTableBuilder::CallbackOnTaskRunner::CallbackOnTaskRunner( + scoped_refptr<base::SequencedTaskRunner> runner, + blink::mojom::DWriteFontProxy::GetUniqueNameLookupTableCallback callback) + : task_runner(std::move(runner)), mojo_callback(std::move(callback)) {} + +DWriteFontLookupTableBuilder::CallbackOnTaskRunner::CallbackOnTaskRunner( + CallbackOnTaskRunner&& other) { + task_runner = std::move(other.task_runner); + mojo_callback = std::move(other.mojo_callback); + other.task_runner = nullptr; + other.mojo_callback = + blink::mojom::DWriteFontProxy::GetUniqueNameLookupTableCallback(); +} + +DWriteFontLookupTableBuilder::CallbackOnTaskRunner::~CallbackOnTaskRunner() = + default; + +void DWriteFontLookupTableBuilder::QueueShareMemoryRegionWhenReady( + scoped_refptr<base::SequencedTaskRunner> task_runner, + blink::mojom::DWriteFontProxy::GetUniqueNameLookupTableCallback callback) { TRACE_EVENT0("dwrite,fonts", - "DWriteFontLookupTableBuilder::EnsureFontUniqueNameTable"); - DCHECK(base::FeatureList::IsEnabled(features::kFontSrcLocalMatching)); + "DWriteFontLookupTableBuilder::QueueShareMemoryRegionWhenReady"); DCHECK(!HasDWriteUniqueFontLookups()); - base::ScopedAllowBaseSyncPrimitives allow_base_sync_primitives; - font_table_built_.Wait(); - return IsFontUniqueNameTableValid(); + DCHECK(!font_table_built_.IsSignaled()); + pending_callbacks_.emplace_back(std::move(task_runner), std::move(callback)); } bool DWriteFontLookupTableBuilder::FontUniqueNameTableReady() { + TRACE_EVENT0("dwrite,fonts", + "DWriteFontLookupTableBuilder::FontUniqueNameTableReady"); + DCHECK(base::FeatureList::IsEnabled(features::kFontSrcLocalMatching)); + DCHECK(!HasDWriteUniqueFontLookups()); return font_table_built_.IsSignaled() && IsFontUniqueNameTableValid(); } @@ -382,6 +408,7 @@ UMA_HISTOGRAM_MEDIUM_TIMES("DirectWrite.Fonts.Proxy.LookupTableReadyTime", duration); font_table_built_.Signal(); + PostCallbacks(); return; } } @@ -592,7 +619,6 @@ TRACE_EVENT0("dwrite,fonts", "DWriteFontLookupTableBuilder::FinalizeFontTable"); DCHECK(!font_table_built_.IsSignaled()); - ScopedAutoSignal auto_signal(&font_table_built_); timeout_callback_.Cancel(); @@ -622,15 +648,12 @@ font_table_memory_ = base::ReadOnlySharedMemoryRegion::Create( font_unique_name_table->ByteSizeLong()); - if (!IsFontUniqueNameTableValid()) { - return; - } - if (!font_unique_name_table->SerializeToArray( + if (!IsFontUniqueNameTableValid() || + !font_unique_name_table->SerializeToArray( font_table_memory_.mapping.memory(), font_table_memory_.mapping.size())) { font_table_memory_ = base::MappedReadOnlyRegion(); - return; } if (caching_enabled_) { @@ -639,6 +662,12 @@ persist_succeeded); } + font_table_built_.Signal(); + PostCallbacks(); + + if (!IsFontUniqueNameTableValid()) + return; + base::TimeDelta duration = base::TimeTicks::Now() - start_time_table_build_; UMA_HISTOGRAM_MEDIUM_TIMES("DirectWrite.Fonts.Proxy.LookupTableBuildTime", duration);
diff --git a/content/browser/renderer_host/dwrite_font_lookup_table_builder_win.h b/content/browser/renderer_host/dwrite_font_lookup_table_builder_win.h index e15f8ab..0543a28 100644 --- a/content/browser/renderer_host/dwrite_font_lookup_table_builder_win.h +++ b/content/browser/renderer_host/dwrite_font_lookup_table_builder_win.h
@@ -23,6 +23,7 @@ #include "base/time/time.h" #include "content/common/content_export.h" #include "third_party/blink/public/common/font_unique_name_lookup/font_unique_name_table.pb.h" +#include "third_party/blink/public/mojom/dwrite_font_proxy/dwrite_font_proxy.mojom.h" namespace base { template <typename T> @@ -48,10 +49,14 @@ // EnsureFontUniqueNameTable() must be checked before. base::ReadOnlySharedMemoryRegion DuplicateMemoryRegion(); - // Wait for the internal WaitableEvent to be signaled if needed and return - // true if the font unique name lookup table was successfully - // constructed. Call only after ScheduleBuildFontUniqueNameTable(). - bool EnsureFontUniqueNameTable(); + // Enqueue a request to get notified about the availability of the shared + // memory region holding the unique font lookup table. + // https://crbug.com/967316 shows that we do have a higher number of + // DWriteFontProxyImpl instances, potentially running on different + // TaskRunners. Capture each relevant task runner with a call to this method. + void QueueShareMemoryRegionWhenReady( + scoped_refptr<base::SequencedTaskRunner> task_runner, + blink::mojom::DWriteFontProxy::GetUniqueNameLookupTableCallback callback); // Returns whether the indexing has completed and the shared memory region is // immediately ready without any sync operations. @@ -59,9 +64,9 @@ // If needed, i.e. if we're on pre-Windows 10, posts a task to load from cache // or build (if cache not available) the unique name table index, should only - // be called once at browser startup, after that, use - // EnsureFontUniqueNameTable() and DuplicatedMemoryRegion() to retrieve the - // lookup structure buffer. + // be called once at browser startup, after that, + // QueueShareMemoryRegionWhenReady() to trigger the mojo callbacks when the + // table is ready. void SchedulePrepareFontUniqueNameTableIfNeeded(); enum class SlowDownMode { kDelayEachTask, kHangOneTask, kNoSlowdown }; @@ -101,6 +106,8 @@ // Windows 10, used for testing only to allow running the tests on Windows 10. void OverrideDWriteVersionChecksForTesting(); + bool EnsureFontUniqueNameTableForTesting(); + private: friend class base::NoDestructor<DWriteFontLookupTableBuilder>; @@ -167,6 +174,8 @@ base::TimeDelta IndexingTimeout(); + void PostCallbacks(); + DWriteFontLookupTableBuilder(); ~DWriteFontLookupTableBuilder(); @@ -192,6 +201,19 @@ base::Optional<base::WaitableEvent> hang_event_for_testing_; base::CancelableOnceCallback<void()> timeout_callback_; + struct CallbackOnTaskRunner { + CallbackOnTaskRunner( + scoped_refptr<base::SequencedTaskRunner>, + blink::mojom::DWriteFontProxy::GetUniqueNameLookupTableCallback); + CallbackOnTaskRunner(CallbackOnTaskRunner&&); + ~CallbackOnTaskRunner(); + scoped_refptr<base::SequencedTaskRunner> task_runner; + blink::mojom::DWriteFontProxy::GetUniqueNameLookupTableCallback + mojo_callback; + }; + + std::vector<CallbackOnTaskRunner> pending_callbacks_; + DISALLOW_COPY_AND_ASSIGN(DWriteFontLookupTableBuilder); };
diff --git a/content/browser/renderer_host/dwrite_font_lookup_table_builder_win_unittest.cc b/content/browser/renderer_host/dwrite_font_lookup_table_builder_win_unittest.cc index 24be3b89..7cc8d19b 100644 --- a/content/browser/renderer_host/dwrite_font_lookup_table_builder_win_unittest.cc +++ b/content/browser/renderer_host/dwrite_font_lookup_table_builder_win_unittest.cc
@@ -92,7 +92,7 @@ // class directly. TEST_F(DWriteFontLookupTableBuilderTest, TestFindUniqueFontDirect) { font_lookup_table_builder_->SchedulePrepareFontUniqueNameTableIfNeeded(); - font_lookup_table_builder_->EnsureFontUniqueNameTable(); + font_lookup_table_builder_->EnsureFontUniqueNameTableForTesting(); TestMatchFonts(); } @@ -100,7 +100,7 @@ font_lookup_table_builder_->SetSlowDownIndexingForTestingWithTimeout( GetParam(), kTestingTimeout); font_lookup_table_builder_->SchedulePrepareFontUniqueNameTableIfNeeded(); - font_lookup_table_builder_->EnsureFontUniqueNameTable(); + font_lookup_table_builder_->EnsureFontUniqueNameTableForTesting(); base::ReadOnlySharedMemoryRegion font_table_memory = font_lookup_table_builder_->DuplicateMemoryRegion(); blink::FontTableMatcher font_table_matcher(font_table_memory.Map()); @@ -128,7 +128,7 @@ font_lookup_table_builder_->SchedulePrepareFontUniqueNameTableIfNeeded(); ASSERT_FALSE(font_lookup_table_builder_->FontUniqueNameTableReady()); font_lookup_table_builder_->ResumeFromHangForTesting(); - font_lookup_table_builder_->EnsureFontUniqueNameTable(); + font_lookup_table_builder_->EnsureFontUniqueNameTableForTesting(); ASSERT_TRUE(font_lookup_table_builder_->FontUniqueNameTableReady()); } @@ -137,7 +137,7 @@ font_lookup_table_builder_->ResetLookupTableForTesting(); font_lookup_table_builder_->SetCachingEnabledForTesting(false); font_lookup_table_builder_->SchedulePrepareFontUniqueNameTableIfNeeded(); - font_lookup_table_builder_->EnsureFontUniqueNameTable(); + font_lookup_table_builder_->EnsureFontUniqueNameTableForTesting(); } } @@ -149,7 +149,8 @@ // Cycle once to build cache file. font_lookup_table_builder_->ResetLookupTableForTesting(); font_lookup_table_builder_->SchedulePrepareFontUniqueNameTableIfNeeded(); - font_lookup_table_builder_->EnsureFontUniqueNameTable(); + ASSERT_TRUE( + font_lookup_table_builder_->EnsureFontUniqueNameTableForTesting()); // Truncate table for testing base::FilePath cache_file_path = scoped_temp_dir_.GetPath().Append( FILE_PATH_LITERAL("font_unique_name_table.pb")); @@ -170,13 +171,15 @@ // Reload the cache file. font_lookup_table_builder_->ResetLookupTableForTesting(); font_lookup_table_builder_->SchedulePrepareFontUniqueNameTableIfNeeded(); - ASSERT_TRUE(font_lookup_table_builder_->EnsureFontUniqueNameTable()); + ASSERT_TRUE( + font_lookup_table_builder_->EnsureFontUniqueNameTableForTesting()); TestMatchFonts(); // Ensure that the table is still valid even though persisting has failed due // to the exclusive write lock on the file. - ASSERT_TRUE(font_lookup_table_builder_->EnsureFontUniqueNameTable()); + ASSERT_TRUE( + font_lookup_table_builder_->EnsureFontUniqueNameTableForTesting()); } } // namespace content
diff --git a/content/browser/renderer_host/dwrite_font_proxy_impl_win.cc b/content/browser/renderer_host/dwrite_font_proxy_impl_win.cc index 5b64a37..2fae4d0 100644 --- a/content/browser/renderer_host/dwrite_font_proxy_impl_win.cc +++ b/content/browser/renderer_host/dwrite_font_proxy_impl_win.cc
@@ -503,14 +503,8 @@ callback = mojo::WrapCallbackWithDefaultInvokeIfNotRun( std::move(callback), base::ReadOnlySharedMemoryRegion()); - // ScheduleBuildFontUniqueNameTable() is called early in browser startup - // before EnsureFontUniqueNameTable() can be called. See - // BrowserMainLoop::BrowserThreadsStarted(). - if (!DWriteFontLookupTableBuilder::GetInstance()->EnsureFontUniqueNameTable()) - return; - - std::move(callback).Run( - DWriteFontLookupTableBuilder::GetInstance()->DuplicateMemoryRegion()); + DWriteFontLookupTableBuilder::GetInstance()->QueueShareMemoryRegionWhenReady( + base::SequencedTaskRunnerHandle::Get(), std::move(callback)); } void DWriteFontProxyImpl::InitializeDirectWrite() {
diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc index 6bbc396..1762c57 100644 --- a/content/browser/security_exploit_browsertest.cc +++ b/content/browser/security_exploit_browsertest.cc
@@ -809,7 +809,6 @@ params.disposition = WindowOpenDisposition::CURRENT_TAB; params.should_replace_current_entry = true; params.user_gesture = true; - params.is_history_navigation_in_new_child = false; FrameHostMsg_OpenURL msg(root->current_frame_host()->routing_id(), params); IPC::IpcSecurityTestUtil::PwnMessageReceived( @@ -1095,7 +1094,6 @@ params.disposition = WindowOpenDisposition::CURRENT_TAB; params.should_replace_current_entry = false; params.user_gesture = true; - params.is_history_navigation_in_new_child = false; SiteInstance* a_com_instance = root->current_frame_host()->GetSiteInstance(); RenderFrameProxyHost* proxy =
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index 34faf88..176219f 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -14724,4 +14724,47 @@ testing::Bool(), testing::Bool())); +// This checks what process is used when an iframe is navigated to about:blank. +// The new document should be loaded in the process of its initiator. +// +// Test case: +// 1. Navigate to A1(B2). +// 2. B2 navigates itself to B3 = about:blank. Process B is used. +// 3. A1 makes B3 to navigate to A4 = about:blank. Process A is used. +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, + SameAndCrossProcessIframeAboutBlankNavigation) { + // 1. Navigate to A1(B2). + GURL a1_url(embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(b)")); + EXPECT_TRUE(NavigateToURL(shell(), a1_url)); + RenderFrameHostImpl* a1_rfh = web_contents()->GetMainFrame(); + RenderFrameHostImpl* b2_rfh = a1_rfh->child_at(0)->current_frame_host(); + + // 2. B2 navigates itself to B3 = about:blank. Process B is used. + { + scoped_refptr<SiteInstance> b2_site_instance = b2_rfh->GetSiteInstance(); + TestNavigationManager navigation_manager(web_contents(), + GURL("about:blank")); + EXPECT_TRUE(ExecJs(b2_rfh, "location.href = 'about:blank';")); + navigation_manager.WaitForNavigationFinished(); + + RenderFrameHostImpl* b3_rfh = a1_rfh->child_at(0)->current_frame_host(); + DCHECK_EQ(b3_rfh->GetSiteInstance(), b2_site_instance); + DCHECK_NE(a1_rfh->GetProcess(), b3_rfh->GetProcess()); + } + + // 3. A1 makes B3 to navigate to A4 = about:blank. Process A is used. + { + TestNavigationManager navigation_manager(web_contents(), + GURL("about:blank")); + EXPECT_TRUE(ExecJs(a1_rfh, R"( + document.querySelector("iframe").src = "about:blank"; + )")); + navigation_manager.WaitForNavigationFinished(); + + RenderFrameHostImpl* b4_rfh = a1_rfh->child_at(0)->current_frame_host(); + DCHECK_EQ(a1_rfh->GetSiteInstance(), b4_rfh->GetSiteInstance()); + } +} + } // namespace content
diff --git a/content/browser/site_per_process_unload_browsertest.cc b/content/browser/site_per_process_unload_browsertest.cc index a24dc3e..faa0669 100644 --- a/content/browser/site_per_process_unload_browsertest.cc +++ b/content/browser/site_per_process_unload_browsertest.cc
@@ -1222,6 +1222,7 @@ auto filter = base::MakeRefCounted<DropMessageFilter>( FrameMsgStart, FrameHostMsg_Detach::ID); B2->GetProcess()->AddFilter(filter.get()); + B2->SetSubframeUnloadTimeoutForTesting(base::TimeDelta::FromSeconds(30)); EXPECT_FALSE(B2->GetSuddenTerminationDisablerState(blink::kUnloadHandler)); EXPECT_TRUE(ExecJs(B2, "window.onunload = ()=>{};"));
diff --git a/content/browser/web_package/signed_exchange_request_handler_browsertest.cc b/content/browser/web_package/signed_exchange_request_handler_browsertest.cc index bbb9a46..93331d0 100644 --- a/content/browser/web_package/signed_exchange_request_handler_browsertest.cc +++ b/content/browser/web_package/signed_exchange_request_handler_browsertest.cc
@@ -5,7 +5,6 @@ #include <tuple> #include "base/bind.h" -#include "base/cfi_buildflags.h" #include "base/files/file_path.h" #include "base/path_service.h" #include "base/strings/string_util.h" @@ -468,10 +467,8 @@ PrefetchIsEnabled() ? 2 : 1); } -#if defined(OS_ANDROID) && \ - (BUILDFLAG(CFI_CAST_CHECK) || BUILDFLAG(CFI_ICALL_CHECK) || \ - BUILDFLAG(CFI_ENFORCEMENT_TRAP) || BUILDFLAG(CFI_ENFORCEMENT_DIAGNOSTIC)) -// https://crbug.com/966820. Fails pretty often on Android CFI. +#if defined(OS_ANDROID) +// https://crbug.com/966820. Fails pretty often on Android. #define MAYBE_BadMICE DISABLED_BadMICE #else #define MAYBE_BadMICE BadMICE
diff --git a/content/child/blink_platform_impl.cc b/content/child/blink_platform_impl.cc index 4158908..353e35a 100644 --- a/content/child/blink_platform_impl.cc +++ b/content/child/blink_platform_impl.cc
@@ -33,6 +33,7 @@ #include "content/app/resources/grit/content_resources.h" #include "content/app/strings/grit/content_strings.h" #include "content/child/child_thread_impl.h" +#include "content/common/appcache_interfaces.h" #include "content/common/service_worker/service_worker_utils.h" #include "content/public/common/content_client.h" #include "content/public/common/content_features.h" @@ -651,6 +652,10 @@ return native_theme_engine_.get(); } +bool BlinkPlatformImpl::IsURLSupportedForAppCache(const blink::WebURL& url) { + return IsSchemeSupportedForAppCache(url); +} + base::File BlinkPlatformImpl::DatabaseOpenFile( const blink::WebString& vfs_file_name, int desired_flags) {
diff --git a/content/child/blink_platform_impl.h b/content/child/blink_platform_impl.h index 2466cf3e..7bde51bf3 100644 --- a/content/child/blink_platform_impl.h +++ b/content/child/blink_platform_impl.h
@@ -36,6 +36,7 @@ // Platform methods (partial implementation): blink::WebThemeEngine* ThemeEngine() override; + bool IsURLSupportedForAppCache(const blink::WebURL& url) override; base::File DatabaseOpenFile(const blink::WebString& vfs_file_name, int desired_flags) override; int DatabaseDeleteFile(const blink::WebString& vfs_file_name,
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index 423050f..6851c17 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -499,6 +499,7 @@ IPC_STRUCT_TRAITS_MEMBER(origin_policy) IPC_STRUCT_TRAITS_MEMBER(href_translate) IPC_STRUCT_TRAITS_MEMBER(input_start) + IPC_STRUCT_TRAITS_MEMBER(is_history_navigation_in_new_child_frame) IPC_STRUCT_TRAITS_END() IPC_STRUCT_TRAITS_BEGIN(content::NavigationTiming) @@ -519,7 +520,6 @@ IPC_STRUCT_TRAITS_MEMBER(can_load_local_resources) IPC_STRUCT_TRAITS_MEMBER(page_state) IPC_STRUCT_TRAITS_MEMBER(nav_entry_id) - IPC_STRUCT_TRAITS_MEMBER(is_history_navigation_in_new_child) IPC_STRUCT_TRAITS_MEMBER(subframe_unique_names) IPC_STRUCT_TRAITS_MEMBER(intended_as_new_entry) IPC_STRUCT_TRAITS_MEMBER(pending_history_list_offset) @@ -577,7 +577,6 @@ IPC_STRUCT_MEMBER(WindowOpenDisposition, disposition) IPC_STRUCT_MEMBER(bool, should_replace_current_entry) IPC_STRUCT_MEMBER(bool, user_gesture) - IPC_STRUCT_MEMBER(bool, is_history_navigation_in_new_child) IPC_STRUCT_MEMBER(blink::WebTriggeringEventInfo, triggering_event_info) IPC_STRUCT_MEMBER(mojo::MessagePipeHandle, blob_url_token) IPC_STRUCT_MEMBER(std::string, href_translate)
diff --git a/content/common/navigation_params.cc b/content/common/navigation_params.cc index 803e077..4ef5a0a8 100644 --- a/content/common/navigation_params.cc +++ b/content/common/navigation_params.cc
@@ -56,6 +56,7 @@ bool has_user_gesture, const InitiatorCSPInfo& initiator_csp_info, const std::string& href_translate, + bool is_history_navigation_in_new_child_frame, base::TimeTicks input_start) : url(url), initiator_origin(initiator_origin), @@ -75,6 +76,8 @@ has_user_gesture(has_user_gesture), initiator_csp_info(initiator_csp_info), href_translate(href_translate), + is_history_navigation_in_new_child_frame( + is_history_navigation_in_new_child_frame), input_start(input_start) { // |method != "POST"| should imply absence of |post_data|. if (method != "POST" && post_data) { @@ -100,7 +103,6 @@ bool can_load_local_resources, const PageState& page_state, int nav_entry_id, - bool is_history_navigation_in_new_child, std::map<std::string, bool> subframe_unique_names, bool intended_as_new_entry, int pending_history_list_offset, @@ -116,7 +118,6 @@ can_load_local_resources(can_load_local_resources), page_state(page_state), nav_entry_id(nav_entry_id), - is_history_navigation_in_new_child(is_history_navigation_in_new_child), subframe_unique_names(subframe_unique_names), intended_as_new_entry(intended_as_new_entry), pending_history_list_offset(pending_history_list_offset),
diff --git a/content/common/navigation_params.h b/content/common/navigation_params.h index 38ebd46..85a6e09 100644 --- a/content/common/navigation_params.h +++ b/content/common/navigation_params.h
@@ -103,6 +103,7 @@ bool has_user_gesture, const InitiatorCSPInfo& initiator_csp_info, const std::string& href_translate, + bool is_history_navigation_in_new_child_frame, base::TimeTicks input_start = base::TimeTicks()); CommonNavigationParams(const CommonNavigationParams& other); ~CommonNavigationParams(); @@ -185,6 +186,13 @@ // from a link that had that attribute set. std::string href_translate; + // Whether this is a history navigation in a newly created child frame, in + // which case the browser process is instructing the renderer process to load + // a URL from a session history item. Defaults to false. + // TODO(ahemery): Move this to BeginNavigationParams once we default to + // IsPerNavigationMojoInterface(). + bool is_history_navigation_in_new_child_frame = false; + // The time the input event leading to the navigation occurred. This will // not always be set; it depends on the creator of the CommonNavigationParams // setting it. @@ -214,7 +222,6 @@ bool can_load_local_resources, const PageState& page_state, int nav_entry_id, - bool is_history_navigation_in_new_child, std::map<std::string, bool> subframe_unique_names, bool intended_as_new_entry, int pending_history_list_offset, @@ -266,11 +273,6 @@ // the resulting FrameHostMsg_DidCommitProvisionalLoad_Params. int nav_entry_id = 0; - // Whether this is a history navigation in a newly created child frame, in - // which case the browser process is instructing the renderer process to load - // a URL from a session history item. Defaults to false. - bool is_history_navigation_in_new_child = false; - // If this is a history navigation, this contains a map of frame unique names // to |is_about_blank| for immediate children of the frame being navigated for // which there are history items. The renderer process only needs to check
diff --git a/content/public/test/render_view_test.cc b/content/public/test/render_view_test.cc index 6f46835..f8e2b19 100644 --- a/content/public/test/render_view_test.cc +++ b/content/public/test/render_view_test.cc
@@ -586,7 +586,8 @@ FrameMsg_Navigate_Type::RELOAD, NavigationDownloadPolicy(), false, GURL(), GURL(), PREVIEWS_UNSPECIFIED, base::TimeTicks::Now(), "GET", nullptr, base::Optional<SourceLocation>(), false /* started_from_context_menu */, - false /* has_user_gesture */, InitiatorCSPInfo(), std::string()); + false /* has_user_gesture */, InitiatorCSPInfo(), std::string(), + false /* is_history_navigation_in_new_child_frame */); RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_); TestRenderFrame* frame = static_cast<TestRenderFrame*>(impl->GetMainRenderFrame()); @@ -731,7 +732,8 @@ NavigationDownloadPolicy(), false, GURL(), GURL(), PREVIEWS_UNSPECIFIED, base::TimeTicks::Now(), "GET", nullptr, base::Optional<SourceLocation>(), false /* started_from_context_menu */, false /* has_user_gesture */, - InitiatorCSPInfo(), std::string()); + InitiatorCSPInfo(), std::string(), + false /* is_history_navigation_in_new_child_frame */); CommitNavigationParams commit_params; commit_params.page_state = state; commit_params.nav_entry_id = pending_offset + 1;
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index 8ad2c14..b266299 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -47,8 +47,6 @@ "android/synchronous_compositor_registry.h", "android/synchronous_layer_tree_frame_sink.cc", "android/synchronous_layer_tree_frame_sink.h", - "appcache/web_application_cache_host_impl.cc", - "appcache/web_application_cache_host_impl.h", "blob_storage/webblobregistry_impl.cc", "blob_storage/webblobregistry_impl.h", "browser_plugin/browser_plugin.cc", @@ -450,8 +448,6 @@ "renderer_main_platform_delegate_linux.cc", "renderer_main_platform_delegate_mac.mm", "renderer_main_platform_delegate_win.cc", - "renderer_webapplicationcachehost_impl.cc", - "renderer_webapplicationcachehost_impl.h", "renderer_webcookiejar_impl.cc", "renderer_webcookiejar_impl.h", "resource_timing_info_conversions.cc", @@ -510,8 +506,6 @@ "web_ui_extension_data.h", "webgraphicscontext3d_provider_impl.cc", "webgraphicscontext3d_provider_impl.h", - "worker/application_cache_host_for_shared_worker.cc", - "worker/application_cache_host_for_shared_worker.h", "worker/dedicated_worker_host_factory_client.cc", "worker/dedicated_worker_host_factory_client.h", "worker/embedded_shared_worker_stub.cc",
diff --git a/content/renderer/appcache/OWNERS b/content/renderer/appcache/OWNERS deleted file mode 100644 index ad46687e..0000000 --- a/content/renderer/appcache/OWNERS +++ /dev/null
@@ -1,4 +0,0 @@ -file://content/browser/appcache/OWNERS - -# TEAM: storage-dev@chromium.org -# COMPONENT: Blink>Storage>AppCache
diff --git a/content/renderer/appcache/web_application_cache_host_impl.h b/content/renderer/appcache/web_application_cache_host_impl.h deleted file mode 100644 index 36c757b4..0000000 --- a/content/renderer/appcache/web_application_cache_host_impl.h +++ /dev/null
@@ -1,91 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_RENDERER_APPCACHE_WEB_APPLICATION_CACHE_HOST_IMPL_H_ -#define CONTENT_RENDERER_APPCACHE_WEB_APPLICATION_CACHE_HOST_IMPL_H_ - -#include <string> - -#include "base/unguessable_token.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "third_party/blink/public/mojom/appcache/appcache.mojom.h" -#include "third_party/blink/public/mojom/appcache/appcache_info.mojom.h" -#include "third_party/blink/public/mojom/devtools/console_message.mojom.h" -#include "third_party/blink/public/platform/web_application_cache_host.h" -#include "third_party/blink/public/platform/web_application_cache_host_client.h" -#include "third_party/blink/public/platform/web_url_response.h" -#include "third_party/blink/public/platform/web_vector.h" -#include "url/gurl.h" - -namespace blink { -namespace mojom { -class DocumentInterfaceBroker; -} -} // namespace blink - -namespace content { - -class WebApplicationCacheHostImpl : public blink::WebApplicationCacheHost, - public blink::mojom::AppCacheFrontend { - public: - // |interface_broker| can be null for workers. - WebApplicationCacheHostImpl( - blink::mojom::DocumentInterfaceBroker* interface_broker, - blink::WebApplicationCacheHostClient* client, - const base::UnguessableToken& appcache_host_id, - scoped_refptr<base::SingleThreadTaskRunner> task_runner); - ~WebApplicationCacheHostImpl() override; - - const base::UnguessableToken& host_id() const { return host_id_; } - blink::WebApplicationCacheHostClient* client() const { return client_; } - - // blink::mojom::AppCacheFrontend - void CacheSelected(blink::mojom::AppCacheInfoPtr info) override; - void EventRaised(blink::mojom::AppCacheEventID event_id) override; - void ProgressEventRaised(const GURL& url, - int32_t num_total, - int32_t num_complete) override; - void ErrorEventRaised(blink::mojom::AppCacheErrorDetailsPtr details) override; - - // blink::WebApplicationCacheHost: - void WillStartMainResourceRequest( - const blink::WebURL& url, - const blink::WebString& method, - const WebApplicationCacheHost* spawning_host) override; - void SelectCacheWithoutManifest() override; - bool SelectCacheWithManifest(const blink::WebURL& manifestURL) override; - void DidReceiveResponseForMainResource(const blink::WebURLResponse&) override; - blink::mojom::AppCacheStatus GetStatus() override; - bool StartUpdate() override; - bool SwapCache() override; - void GetResourceList(blink::WebVector<ResourceInfo>* resources) override; - void GetAssociatedCacheInfo(CacheInfo* info) override; - const base::UnguessableToken& GetHostID() const override; - - void SelectCacheForSharedWorker(long long app_cache_id, - base::OnceClosure completion_callback); - - private: - enum IsNewMasterEntry { MAYBE_NEW_ENTRY, NEW_ENTRY, OLD_ENTRY }; - - mojo::Binding<blink::mojom::AppCacheFrontend> binding_; - blink::WebApplicationCacheHostClient* client_; - blink::mojom::AppCacheHostPtr backend_host_; - base::UnguessableToken host_id_; - blink::mojom::AppCacheStatus status_; - blink::WebURLResponse document_response_; - GURL document_url_; - bool is_scheme_supported_; - bool is_get_method_; - IsNewMasterEntry is_new_master_entry_; - blink::mojom::AppCacheInfo cache_info_; - GURL original_main_resource_url_; // Used to detect redirection. - bool was_select_cache_called_; - // Invoked when CacheSelected() is called. - base::OnceClosure select_cache_for_shared_worker_completion_callback_; -}; - -} // namespace content - -#endif // CONTENT_RENDERER_APPCACHE_WEB_APPLICATION_CACHE_HOST_IMPL_H_
diff --git a/content/renderer/loader/web_worker_fetch_context_impl.h b/content/renderer/loader/web_worker_fetch_context_impl.h index ab0615e..3fe0c83 100644 --- a/content/renderer/loader/web_worker_fetch_context_impl.h +++ b/content/renderer/loader/web_worker_fetch_context_impl.h
@@ -24,7 +24,6 @@ #include "third_party/blink/public/mojom/service_worker/service_worker_container.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_provider.mojom.h" -#include "third_party/blink/public/platform/web_application_cache_host.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_worker_fetch_context.h" #include "url/gurl.h"
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index f7e38abe..99fe5b4 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -139,7 +139,6 @@ #include "content/renderer/render_view_impl.h" #include "content/renderer/render_widget_fullscreen_pepper.h" #include "content/renderer/renderer_blink_platform_impl.h" -#include "content/renderer/renderer_webapplicationcachehost_impl.h" #include "content/renderer/resource_timing_info_conversions.h" #include "content/renderer/savable_resources.h" #include "content/renderer/service_worker/service_worker_network_provider_for_frame.h" @@ -529,7 +528,8 @@ std::unique_ptr<blink::WebNavigationInfo> info, int load_flags, bool has_download_sandbox_flag, - bool from_ad) { + bool from_ad, + bool is_history_navigation_in_new_child_frame) { // A valid RequestorOrigin is always expected to be present. DCHECK(!info->url_request.RequestorOrigin().IsNull()); @@ -590,7 +590,8 @@ ? base::Optional<CSPSource>(BuildCSPSource( info->initiator_csp.self_source.value())) : base::nullopt), - info->href_translate.Latin1(), info->input_start); + info->href_translate.Latin1(), is_history_navigation_in_new_child_frame, + info->input_start); } WebFrameLoadType NavigationTypeToLoadType( @@ -3566,8 +3567,7 @@ // Check that the history navigation can commit. commit_status = PrepareForHistoryNavigationCommit( - common_params.navigation_type, commit_params, - &item_for_history_navigation, &load_type); + common_params, commit_params, &item_for_history_navigation, &load_type); } if (commit_status != blink::mojom::CommitResult::Ok) { @@ -3819,10 +3819,9 @@ // which should be the case because history navigations are routed via the // browser. DCHECK_NE(0, commit_params.nav_entry_id); - DCHECK(!commit_params.is_history_navigation_in_new_child); + DCHECK(!common_params.is_history_navigation_in_new_child_frame); commit_status = PrepareForHistoryNavigationCommit( - common_params.navigation_type, commit_params, - &item_for_history_navigation, &load_type); + common_params, commit_params, &item_for_history_navigation, &load_type); } if (commit_status == blink::mojom::CommitResult::Ok) { @@ -3981,6 +3980,13 @@ #endif } +void RenderFrameImpl::UpdateSubresourceFactory( + std::unique_ptr<blink::URLLoaderFactoryBundleInfo> info) { + auto child_info = + std::make_unique<ChildURLLoaderFactoryBundleInfo>(std::move(info)); + GetLoaderFactoryBundle()->Update(std::move(child_info)); +} + void RenderFrameImpl::BindToFrame(blink::WebNavigationControl* frame) { DCHECK(!frame_); @@ -4056,8 +4062,8 @@ scoped_refptr<base::SingleThreadTaskRunner> task_runner = frame_->GetTaskRunner(blink::TaskType::kNetworking); - return std::make_unique<RendererWebApplicationCacheHostImpl>( - this, client, + return blink::WebApplicationCacheHost::CreateWebApplicationCacheHostForFrame( + frame_, client, navigation_state->commit_params().appcache_host_id.value_or( base::UnguessableToken()), std::move(task_runner)); @@ -6122,10 +6128,11 @@ } blink::mojom::CommitResult RenderFrameImpl::PrepareForHistoryNavigationCommit( - FrameMsg_Navigate_Type::Value navigation_type, + const CommonNavigationParams& common_params, const CommitNavigationParams& commit_params, WebHistoryItem* item_for_history_navigation, blink::WebFrameLoadType* load_type) { + FrameMsg_Navigate_Type::Value navigation_type = common_params.navigation_type; DCHECK(navigation_type == FrameMsg_Navigate_Type::HISTORY_SAME_DOCUMENT || navigation_type == FrameMsg_Navigate_Type::HISTORY_DIFFERENT_DOCUMENT || @@ -6167,12 +6174,22 @@ } // If this navigation is to a history item for a new child frame, we may - // want to ignore it in some cases. If a Javascript navigation (i.e., - // client redirect) interrupted it and has either been scheduled, - // started loading, or has committed, we should ignore the history item. + // want to ignore it if a Javascript navigation (i.e., client redirect) + // interrupted it. + // To detect this we need to check for the interrupt at different stages of + // navigation: bool interrupted_by_client_redirect = - frame_->IsNavigationScheduledWithin(0) || !current_history_item_.IsNull(); - if (commit_params.is_history_navigation_in_new_child && + // IsNavigationScheduleWithin() checks that we have something just + // started, sent to the browser or loading. + (frame_->IsNavigationScheduledWithin(0) && + // The current navigation however is just returning from the browser. To + // check that it is not the current navigation, we verify the "initial + // history navigation in a subframe" flag of ClientNavigationState. + !frame_->IsClientNavigationInitialHistoryLoad()) || + // The client navigation could already have finished, in which case there + // will be an history item. + !current_history_item_.IsNull(); + if (common_params.is_history_navigation_in_new_child_frame && interrupted_by_client_redirect) { return blink::mojom::CommitResult::Aborted; } @@ -6336,7 +6353,7 @@ if (IsTopLevelNavigation(frame_) && render_view_->renderer_preferences_ .browser_handles_all_top_level_requests) { - OpenURL(std::move(info), /*is_history_navigation_in_new_child=*/false); + OpenURL(std::move(info)); return; // Suppress the load here. } @@ -6348,38 +6365,33 @@ // it, because it will only be used once as the frame is created.) // Note: Skip this logic for MHTML files (|use_archive|), which should load // their subframes from the archive and not from history. + bool is_history_navigation_in_new_child_frame = false; if (info->is_history_navigation_in_new_child_frame && frame_->Parent() && !use_archive) { // Check whether the browser has a history item for this frame that isn't // just staying at the initial about:blank document. - bool should_ask_browser = false; RenderFrameImpl* parent = RenderFrameImpl::FromWebFrame(frame_->Parent()); auto iter = parent->history_subframe_unique_names_.find( unique_name_helper_.value()); if (iter != parent->history_subframe_unique_names_.end()) { bool history_item_is_about_blank = iter->second; - should_ask_browser = + is_history_navigation_in_new_child_frame = !history_item_is_about_blank || url != url::kAboutBlankURL; parent->history_subframe_unique_names_.erase(iter); } + } - if (should_ask_browser) { - // Don't do this if |info| also says it is a client redirect, in which - // case JavaScript on the page is trying to interrupt the history - // navigation. - if (!info->is_client_redirect) { - OpenURL(std::move(info), /*is_history_navigation_in_new_child=*/true); - // TODO(japhet): This case wants to flag the frame as loading and do - // nothing else. It'd be nice if it could go through the - // WillStartNavigation, too. - frame_->MarkAsLoading(); - return; - } + if (is_history_navigation_in_new_child_frame) { + // Don't do this if |info| also says it is a client redirect, in which + // case JavaScript on the page is trying to interrupt the history + // navigation. + if (info->is_client_redirect) { // Client redirects during an initial history load should attempt to // cancel the history navigation. They will create a provisional // document loader, causing the history load to be ignored in // NavigateInternal, and this IPC will try to cancel any cross-process // history load. + is_history_navigation_in_new_child_frame = false; GetFrameHost()->CancelInitialHistoryLoad(); } } @@ -6428,7 +6440,7 @@ } if (should_fork) { - OpenURL(std::move(info), /*is_history_navigation_in_new_child=*/false); + OpenURL(std::move(info)); return; // Suppress the load here. } } @@ -6471,7 +6483,8 @@ WebDocumentLoader::WillLoadUrlAsEmpty(url) && !frame_->HasCommittedFirstRealLoad(); - if (is_first_real_empty_document_navigation) { + if (is_first_real_empty_document_navigation && + !is_history_navigation_in_new_child_frame) { CommitSyncNavigation(std::move(info)); return; } @@ -6481,9 +6494,11 @@ // renderer process. // TODO(arthursonzogni): Remove this. Everything should use the default code // path and be driven by the browser process. - if (use_archive || url == content::kAboutSrcDocURL || - WebDocumentLoader::WillLoadUrlAsEmpty(url)) { - if (!frame_->WillStartNavigation(*info)) + if (use_archive || (((url == content::kAboutSrcDocURL) || + WebDocumentLoader::WillLoadUrlAsEmpty(url)) && + !is_history_navigation_in_new_child_frame)) { + if (!frame_->WillStartNavigation( + *info, false /* is_history_navigation_in_new_child_frame */)) return; // Only the first navigation in a frame to an empty document must be // handled synchronously, the others are required to happen @@ -6498,7 +6513,8 @@ // Everything else is handled asynchronously by the browser process through // BeginNavigation. - BeginNavigationInternal(std::move(info)); + BeginNavigationInternal(std::move(info), + is_history_navigation_in_new_child_frame); return; } @@ -6509,7 +6525,7 @@ blink::WebLocalFrameClient::CrossOriginRedirects::kFollow, blob_url_token.PassHandle()); } else { - OpenURL(std::move(info), /*is_history_navigation_in_new_child=*/false); + OpenURL(std::move(info)); } } @@ -6766,8 +6782,7 @@ #endif #endif -void RenderFrameImpl::OpenURL(std::unique_ptr<blink::WebNavigationInfo> info, - bool is_history_navigation_in_new_child) { +void RenderFrameImpl::OpenURL(std::unique_ptr<blink::WebNavigationInfo> info) { // A valid RequestorOrigin is always expected to be present. DCHECK(!info->url_request.RequestorOrigin().IsNull()); @@ -6803,9 +6818,6 @@ WebUserGestureIndicator::ConsumeUserGesture(frame_); } - if (is_history_navigation_in_new_child) - params.is_history_navigation_in_new_child = true; - params.href_translate = info->href_translate.Latin1(); bool current_frame_has_download_sandbox_flag = @@ -7024,9 +7036,11 @@ } // namespace void RenderFrameImpl::BeginNavigationInternal( - std::unique_ptr<blink::WebNavigationInfo> info) { + std::unique_ptr<blink::WebNavigationInfo> info, + bool is_history_navigation_in_new_child_frame) { std::unique_ptr<DocumentState> document_state = BuildDocumentState(); - if (!frame_->WillStartNavigation(*info)) + if (!frame_->WillStartNavigation(*info, + is_history_navigation_in_new_child_frame)) return; browser_side_navigation_pending_ = true; @@ -7137,8 +7151,8 @@ GetFrameHost()->BeginNavigation( MakeCommonNavigationParams(frame_->GetSecurityOrigin(), std::move(info), - load_flags, has_download_sandbox_flag, - from_ad), + load_flags, has_download_sandbox_flag, from_ad, + is_history_navigation_in_new_child_frame), std::move(begin_navigation_params), std::move(blob_url_token), std::move(navigation_client_info), std::move(initiator_ptr)); }
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index bafcf9a..e437972f 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -1174,12 +1174,8 @@ base::TimeDelta main_thread_use_time, mojom::MhtmlSaveStatus save_status); - // Requests that the browser process navigates to |url|. If - // |is_history_navigation_in_new_child| is true, the browser process should - // look for a matching FrameNavigationEntry in the last committed entry to use - // instead of |url|. - void OpenURL(std::unique_ptr<blink::WebNavigationInfo> info, - bool is_history_navigation_in_new_child); + // Requests that the browser process navigates to |url|. + void OpenURL(std::unique_ptr<blink::WebNavigationInfo> info); // Returns a ChildURLLoaderFactoryBundle which can be used to request // subresources for this frame. @@ -1235,7 +1231,8 @@ const CommitNavigationParams& commit_params); // Sends a FrameHostMsg_BeginNavigation to the browser - void BeginNavigationInternal(std::unique_ptr<blink::WebNavigationInfo> info); + void BeginNavigationInternal(std::unique_ptr<blink::WebNavigationInfo> info, + bool is_history_navigation_in_new_child_frame); // Commit a navigation that isn't handled by the browser (e.g., an empty // document, about:srcdoc or an MHTML archive). @@ -1366,6 +1363,9 @@ const blink::WebElement& plugin_element, v8::Isolate* isolate) override; + void UpdateSubresourceFactory( + std::unique_ptr<blink::URLLoaderFactoryBundleInfo> info) override; + // Updates the state of this frame when asked to commit a navigation. void PrepareFrameForCommit(const GURL& url, const CommitNavigationParams& commit_params); @@ -1395,7 +1395,7 @@ // When this happens, the navigation will be sent back to the browser process // so that it can be performed in cross-document fashion. blink::mojom::CommitResult PrepareForHistoryNavigationCommit( - FrameMsg_Navigate_Type::Value navigation_type, + const CommonNavigationParams& common_params, const CommitNavigationParams& commit_params, blink::WebHistoryItem* item_for_history_navigation, blink::WebFrameLoadType* load_type);
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 49e1e56..1aa52af 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -68,7 +68,6 @@ #include "content/public/renderer/render_view_observer.h" #include "content/public/renderer/render_view_visitor.h" #include "content/public/renderer/window_features_converter.h" -#include "content/renderer/appcache/web_application_cache_host_impl.h" #include "content/renderer/browser_plugin/browser_plugin.h" #include "content/renderer/browser_plugin/browser_plugin_manager.h" #include "content/renderer/compositor/layer_tree_view.h" @@ -88,7 +87,6 @@ #include "content/renderer/render_thread_impl.h" #include "content/renderer/render_widget_fullscreen_pepper.h" #include "content/renderer/renderer_blink_platform_impl.h" -#include "content/renderer/renderer_webapplicationcachehost_impl.h" #include "content/renderer/savable_resources.h" #include "content/renderer/v8_value_converter_impl.h" #include "content/renderer/web_ui_extension_data.h"
diff --git a/content/renderer/renderer_webapplicationcachehost_impl.cc b/content/renderer/renderer_webapplicationcachehost_impl.cc deleted file mode 100644 index 4fa7651..0000000 --- a/content/renderer/renderer_webapplicationcachehost_impl.cc +++ /dev/null
@@ -1,71 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/renderer/renderer_webapplicationcachehost_impl.h" - -#include <string> - -#include "content/renderer/render_frame_impl.h" -#include "content/renderer/render_thread_impl.h" -#include "content/renderer/render_view_impl.h" -#include "third_party/blink/public/mojom/appcache/appcache.mojom.h" -#include "third_party/blink/public/mojom/appcache/appcache_info.mojom.h" -#include "third_party/blink/public/web/web_frame.h" -#include "third_party/blink/public/web/web_local_frame.h" -#include "third_party/blink/public/web/web_view.h" - -using blink::WebApplicationCacheHostClient; -using blink::WebConsoleMessage; - -namespace content { - -RendererWebApplicationCacheHostImpl::RendererWebApplicationCacheHostImpl( - RenderFrameImpl* render_frame, - WebApplicationCacheHostClient* client, - const base::UnguessableToken& appcache_host_id, - scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : WebApplicationCacheHostImpl(render_frame->GetDocumentInterfaceBroker(), - client, - appcache_host_id, - std::move(task_runner)), - routing_id_(render_frame->render_view()->GetRoutingID()), - frame_routing_id_(render_frame->GetRoutingID()) {} - -void RendererWebApplicationCacheHostImpl::LogMessage( - blink::mojom::ConsoleMessageLevel log_level, - const std::string& message) { - if (RenderThreadImpl::current()->web_test_mode()) - return; - - RenderViewImpl* render_view = GetRenderView(); - if (!render_view || !render_view->webview() || - !render_view->webview()->MainFrame()) - return; - - blink::WebFrame* frame = render_view->webview()->MainFrame(); - if (!frame->IsWebLocalFrame()) - return; - // TODO(michaeln): Make app cache host per-frame and correctly report to the - // involved frame. - frame->ToWebLocalFrame()->AddMessageToConsole(WebConsoleMessage( - static_cast<blink::mojom::ConsoleMessageLevel>(log_level), - blink::WebString::FromUTF8(message.c_str()))); -} - -void RendererWebApplicationCacheHostImpl::SetSubresourceFactory( - network::mojom::URLLoaderFactoryPtr url_loader_factory) { - RenderFrameImpl* render_frame = - RenderFrameImpl::FromRoutingID(frame_routing_id_); - if (render_frame) { - auto info = std::make_unique<ChildURLLoaderFactoryBundleInfo>(); - info->appcache_factory_info() = url_loader_factory.PassInterface(); - render_frame->GetLoaderFactoryBundle()->Update(std::move(info)); - } -} - -RenderViewImpl* RendererWebApplicationCacheHostImpl::GetRenderView() { - return RenderViewImpl::FromRoutingID(routing_id_); -} - -} // namespace content
diff --git a/content/renderer/renderer_webapplicationcachehost_impl.h b/content/renderer/renderer_webapplicationcachehost_impl.h deleted file mode 100644 index 24c04b2..0000000 --- a/content/renderer/renderer_webapplicationcachehost_impl.h +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_RENDERER_RENDERER_WEBAPPLICATIONCACHEHOST_IMPL_H_ -#define CONTENT_RENDERER_RENDERER_WEBAPPLICATIONCACHEHOST_IMPL_H_ - -#include "content/renderer/appcache/web_application_cache_host_impl.h" - -#include "third_party/blink/public/mojom/appcache/appcache.mojom.h" -#include "third_party/blink/public/mojom/appcache/appcache_info.mojom.h" -#include "third_party/blink/public/mojom/devtools/console_message.mojom.h" - -namespace content { -class RenderFrameImpl; -class RenderViewImpl; - -class RendererWebApplicationCacheHostImpl : public WebApplicationCacheHostImpl { - public: - RendererWebApplicationCacheHostImpl( - RenderFrameImpl* render_frame, - blink::WebApplicationCacheHostClient* client, - const base::UnguessableToken& appcache_host_id, - scoped_refptr<base::SingleThreadTaskRunner> task_runner); - - // blink::mojom::AppCacheHostFrontend: - void LogMessage(blink::mojom::ConsoleMessageLevel log_level, - const std::string& message) override; - - void SetSubresourceFactory( - network::mojom::URLLoaderFactoryPtr url_loader_factory) override; - - private: - RenderViewImpl* GetRenderView(); - - int routing_id_; - int frame_routing_id_; -}; - -} // namespace content - -#endif // CONTENT_RENDERER_RENDERER_WEBAPPLICATIONCACHEHOST_IMPL_H_
diff --git a/content/renderer/worker/application_cache_host_for_shared_worker.cc b/content/renderer/worker/application_cache_host_for_shared_worker.cc deleted file mode 100644 index a4174b9..0000000 --- a/content/renderer/worker/application_cache_host_for_shared_worker.cc +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/renderer/worker/application_cache_host_for_shared_worker.h" - -namespace content { - -ApplicationCacheHostForSharedWorker::ApplicationCacheHostForSharedWorker( - blink::WebApplicationCacheHostClient* client, - const base::UnguessableToken& appcache_host_id, - scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : WebApplicationCacheHostImpl(nullptr /* interface_broker */, - client, - appcache_host_id, - std::move(task_runner)) {} - -ApplicationCacheHostForSharedWorker::~ApplicationCacheHostForSharedWorker() = - default; - -void ApplicationCacheHostForSharedWorker::WillStartMainResourceRequest( - const blink::WebURL& url, - const blink::WebString& method, - const WebApplicationCacheHost* spawning_host) {} - -void ApplicationCacheHostForSharedWorker::DidReceiveResponseForMainResource( - const blink::WebURLResponse&) {} - -void ApplicationCacheHostForSharedWorker::SelectCacheWithoutManifest() {} - -bool ApplicationCacheHostForSharedWorker::SelectCacheWithManifest( - const blink::WebURL& manifestURL) { - return true; -} - -void ApplicationCacheHostForSharedWorker::LogMessage( - blink::mojom::ConsoleMessageLevel log_level, - const std::string& message) {} - -void ApplicationCacheHostForSharedWorker::SetSubresourceFactory( - network::mojom::URLLoaderFactoryPtr url_loader_factory) {} - -} // namespace content
diff --git a/content/renderer/worker/application_cache_host_for_shared_worker.h b/content/renderer/worker/application_cache_host_for_shared_worker.h deleted file mode 100644 index fd04389..0000000 --- a/content/renderer/worker/application_cache_host_for_shared_worker.h +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_RENDERER_WORKER_APPLICATION_CACHE_HOST_FOR_SHARED_WORKER_H_ -#define CONTENT_RENDERER_WORKER_APPLICATION_CACHE_HOST_FOR_SHARED_WORKER_H_ - -#include "base/unguessable_token.h" -#include "content/renderer/appcache/web_application_cache_host_impl.h" - -namespace content { - -class ApplicationCacheHostForSharedWorker final - : public WebApplicationCacheHostImpl { - public: - ApplicationCacheHostForSharedWorker( - blink::WebApplicationCacheHostClient* client, - const base::UnguessableToken& appcache_host_id, - scoped_refptr<base::SingleThreadTaskRunner> task_runner); - ~ApplicationCacheHostForSharedWorker() override; - - // Main resource loading is different for workers. The main resource is - // loaded by the worker using WorkerClassicScriptLoader. - // These overrides are stubbed out. - void WillStartMainResourceRequest( - const blink::WebURL& url, - const blink::WebString& method, - const WebApplicationCacheHost* spawning_host) override; - void DidReceiveResponseForMainResource(const blink::WebURLResponse&) override; - - // Cache selection is also different for workers. We know at construction - // time what cache to select and do so then. - // These overrides are stubbed out. - void SelectCacheWithoutManifest() override; - bool SelectCacheWithManifest(const blink::WebURL& manifestURL) override; - - // blink::mojom::AppCacheFrontend: - void LogMessage(blink::mojom::ConsoleMessageLevel log_level, - const std::string& message) override; - void SetSubresourceFactory( - network::mojom::URLLoaderFactoryPtr url_loader_factory) override; -}; - -} // namespace content - -#endif // CONTENT_RENDERER_WORKER_APPLICATION_CACHE_HOST_FOR_SHARED_WORKER_H_
diff --git a/content/renderer/worker/embedded_shared_worker_stub.cc b/content/renderer/worker/embedded_shared_worker_stub.cc index f1c59f5..4a34198 100644 --- a/content/renderer/worker/embedded_shared_worker_stub.cc +++ b/content/renderer/worker/embedded_shared_worker_stub.cc
@@ -20,7 +20,6 @@ #include "content/renderer/loader/web_worker_fetch_context_impl.h" #include "content/renderer/renderer_blink_platform_impl.h" #include "content/renderer/service_worker/service_worker_provider_context.h" -#include "content/renderer/worker/application_cache_host_for_shared_worker.h" #include "content/renderer/worker/service_worker_network_provider_for_worker.h" #include "ipc/ipc_message_macros.h" #include "services/network/public/cpp/features.h" @@ -38,6 +37,7 @@ #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/public/platform/url_conversion.h" #include "third_party/blink/public/platform/web_security_origin.h" +#include "third_party/blink/public/web/web_application_cache_host.h" #include "third_party/blink/public/web/web_shared_worker.h" #include "third_party/blink/public/web/web_shared_worker_client.h" #include "url/origin.h" @@ -189,12 +189,12 @@ std::unique_ptr<blink::WebApplicationCacheHost> EmbeddedSharedWorkerStub::CreateApplicationCacheHost( blink::WebApplicationCacheHostClient* client) { - std::unique_ptr<WebApplicationCacheHostImpl> host = - std::make_unique<ApplicationCacheHostForSharedWorker>( + auto host = blink::WebApplicationCacheHost:: + CreateWebApplicationCacheHostForSharedWorker( client, appcache_host_id_, impl_->GetTaskRunner(blink::TaskType::kNetworking)); app_cache_host_ = host.get(); - return std::move(host); + return host; } std::unique_ptr<blink::WebServiceWorkerNetworkProvider>
diff --git a/content/renderer/worker/embedded_shared_worker_stub.h b/content/renderer/worker/embedded_shared_worker_stub.h index 04533ff9..13794cb 100644 --- a/content/renderer/worker/embedded_shared_worker_stub.h +++ b/content/renderer/worker/embedded_shared_worker_stub.h
@@ -32,7 +32,6 @@ namespace blink { class WebApplicationCacheHost; -class WebApplicationCacheHostClient; class WebSharedWorker; } // namespace blink @@ -44,7 +43,6 @@ namespace content { class ChildURLLoaderFactoryBundle; -class WebApplicationCacheHostImpl; struct NavigationResponseOverrideParameters; // A stub class to receive IPC from browser process and talk to @@ -124,7 +122,7 @@ std::vector<PendingChannel> pending_channels_; const base::UnguessableToken appcache_host_id_; - WebApplicationCacheHostImpl* app_cache_host_ = nullptr; // Not owned. + blink::WebApplicationCacheHost* app_cache_host_ = nullptr; // Not owned. // The info needed to connect to the ServiceWorkerProviderHost on the browser. blink::mojom::ServiceWorkerProviderInfoForWorkerPtr
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt index b570c924..803024c 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -553,6 +553,7 @@ crbug.com/891456 [ android nvidia ] conformance/textures/image_bitmap_from_video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ RetryOnFailure ] crbug.com/891456 [ android nvidia ] conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html [ RetryOnFailure ] crbug.com/891456 [ android nvidia ] conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_byte.html [ RetryOnFailure ] +crbug.com/891456 [ android nvidia ] conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ RetryOnFailure ] crbug.com/891456 [ android nvidia ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html [ RetryOnFailure ] # Flaky timeout on android_n5x_swarming_rel and
diff --git a/docs/sheriff.md b/docs/sheriff.md new file mode 100644 index 0000000..22469987 --- /dev/null +++ b/docs/sheriff.md
@@ -0,0 +1,399 @@ +# Chromium Sheriffing + +Author: ellyjones@ + +Audience: Chromium build sheriff rotation members + +This document describes how to be a Chromium sheriff: what your responsibilities +are and how to go about them. It outlines a specific, opinionated view of how to +be an effective sheriff which is not universally practiced but may be useful for +you. + +[TOC] + +## Sheriffing Philosophy + +Sheriffs have one overarching role: to ensure that the Chromium build +infrastructure is doing its job of helping developers deliver good software. +Every other sheriff responsibility flows from that one. In priority order, +sheriffs need to ensure that: + +1. **The tree is open**, because when the tree is closed nobody can make + progress; +2. **New test failures are not introduced**, because they weaken our assurance + that we're shipping good code; +3. **Existing test failures are repaired**, for the same reason + +As the sheriff, you not only have those responsibilities, but you have any +necessary authority to fulfill them. In particular, you have the authority to: + +* Revert changes that you know or suspect are causing breakages +* Disable or otherwise mark misbehaving tests +* Use [TBRs] freely as part of your sheriffing duties +* Pull in any other engineer or team you need to help you do these duties + +Do not be shy about asking for debugging help from subject-matter experts, and +do not hesitate to ask for guidance on Slack (see below) when you need it. In +particular, there are many experienced sheriffs, ops folks, and other helpful +pseudo-humans in [slack #sheriffing]. + +## Tools Of The Trade + +### A Developer Checkout + +Effective sheriffing requires an [up-to-date checkout][get-the-code], primarily +so that you can create CLs to mark tests, but also so you can attempt local +reproduction or debugging of failures if necessary. If you are a googler, you +will want to have [goma] working as well, since fast builds provide faster +turnaround times. + +### Slack + +Sheriffing is coordinated in the [slack #sheriffing] channel. If you don't yet +have [Slack] set up, it is worth setting it up to sheriff. If you don't want to +use Slack, you will at a minimum need a way to coordinate with your fellow +sheriffs and probably with the ops team. + +These are important Slack channels for sheriffs: + +* [#sheriffing][slack #sheriffing]: for sheriffing + tasks and work tracking +* [#ops][slack #ops]: for [infra + issues][contacting-troopers] with gerrit, git, the bots, monorail, + sheriff-o-matic, findit, ... +* [#halp][slack #halp]: for general chromium + build & development issues - "no question too newbie!" + +A good way to use Slack for sheriffing is as follows: for each new task you do +(investigating a build failure, marking a specific test flaky/slow/etc, working +with a trooper, ...), post a new message in the #sheriffing channel, then +immediately start a thread based on that message. Post all your status updates +on that specific task in that thread, being verbose and using lots of +detail/links; be especially diligent about referencing bug numbers, CL numbers, +usernames, and so on, because these will be searchable later. For example, let's +suppose you see the mac-rel bot has gone red in browser tests: + + you: looking at mac-rel browser_tests failure + [in thread] + you: a handful of related-looking tests failed + you: ah, looks like this was caused by CL 12345, reverting + you: revert is CL 23456, TBR @othersheriff + you: revert is in now, snoozing failure + +Only use "also send to channel" when either the thread is old enough to have +scrolled off people's screens, or the message you are posting is important +enough to appear in the channel at the top level as well - this helps keep the +main channel clear of smaller status updates and makes it more like an index of +the threads. + +### The Waterfall + +The [CI console page], commonly referred to as "the waterfall" because of how it +looks, displays the current state of many of the Chromium bots. In the old days +before Sheriff-o-matic (see below) this was the main tool sheriffs used, and it +is still extremely useful. Especially note the "links" panel, which can take you +not just to other waterfalls but to other sheriffing tools. + +### Sheriff-o-Matic + +[Sheriff-o-matic] attempts to +aggregate build or test failures together into groups. How to use +sheriff-o-matic effectively is described below, but the key parts of the UI are: + +* The bug queue: this is a dashboard of bugs that might be relevant to the + on-duty sheriffs, such as known infra issues, failures that are under active + investigation by engineering teams, and so on. +* The "consistent failures" list: these are failures that have happened more + than once. These are **sometimes** actual consistent failures, and sometimes + the same suite or bot failing twice in two different ways, so it is not always + to be trusted but can be useful. +* The "new failures" list: these are singleton failures that have not yet become + "consistent". These tend to disappear if a bot or suite goes green on a + subsequent pass, so this section can be fairly noisy. + +Sheriff-o-matic can automatically generate CLs to do some sheriffing tasks, like +disabling specific tests. You can access this feature via the "Layout Test +Expectations" link in the sidebar; it is called "TA/DA". + +### Builder (or "Bot") Pages + +Each builder page displays a view of the history of that builder's most recent builds - +here is an example: [Win10 Tests +x64](https://ci.chromium.org/p/chromium/builders/ci/Win10%20Tests%20x64). You +can get more history on this page using the links to the bottom-left of the +build list, or appending a `?limit=n` to the builder page's URL. + +If you click through to an individual build ([Win10 Tests x64 Build +36397](https://ci.chromium.org/p/chromium/builders/ci/Win10%20Tests%20x64/36397) +for example), the important features of the build page are: + +1. The build revision, which is listed at the top - this is key for knowing if a + given build had a specific CL or not. +2. The blamelist (one of the tabs at the top) - this lists all CLs that were in + this build, but not in the previous build for this builder. Note that this + only shows **Chromium** changes; any changes that were incorporated via a + DEPS roll of another repo won't be listed here, and you will instead have to + look at the changelog for that DEP manually. There are usually links to views + of those changes in the commit messages of DEPS roll CLs. +3. The list of steps, each of which has a link to its output and metadata. + Especially important is the "lookup builder gn args" step, which tells you + how to replicate the builder's build config (although probably you will want + to use your own value of `goma_dir`). +4. Within individual steps, the "stdout" link and sometimes also the "shard" + links, which let you read the builder's actual console logs during that step. + Note that the sharded tasks are actually executing on different machines and + are aggregated back into the builder's results. + +### The Flake Portal (The "New Flakiness Dashboard") + +The [new flakiness dashboard] is much faster than the old one but has a +different set of features. **Note that to effectively use this tool you must log +in** via the link in the top right. + +To look at the history of a suite on a specific builder here: + +1. In the "Flakes" view (the default), use Search By Tags +2. Add a filter for `builder` == (eg) `Win10 Tests x64` +3. Add a filter for `test_type` == (eg) `browser_tests` + +To look at how flaky a specific test is across all builders: + +1. In the "Flakes" view, use Search By Test +2. Fill in the test name into the default filter + +This gives you a UI listing the failures for the named test broken down by +builder. At this point you should check to see where the flakes start +revision-wise. If that helps you identify a culprit CL revert it and move on; +otherwise, [disable the test][gtest-disable]. + +For more advice on dealing with flaky tests, look at the "Test Failed" section +below under "Diagnosing Build Failures". + +### The Old Flakiness Dashboard + +The [old flakiness dashboard] is often **extremely slow** and has a tendency not +to provide full results, but it sometimes can diagnose kinds of flakiness that +are not as easy to see in the new dashboard. It is not generally used these +days, but if you need it, you use it like this: + +1. Pick a builder - ideally one matching the test failure you're investigating, + or as similar to it as possible. After this, the dashboard will likely hang + for some seconds, or possibly crash, but reloading the page will load the + dashboard with the right builder set. +2. Pick the relevant test type. Do not pick a 'with patch' suite - these are + from people doing CQ runs with their changes. +3. Find-in-page to locate the test you have in mind. + +If you instead want to see how flaky a given test is across *all* builders, like +if you're trying to diagnose whether a specific test flakes on macOS generally: + +1. Type a glob pattern or substring of the test name in the "Show tests on all + platforms" field - this will clear out the "builder" dropdown. +2. Scroll down **past** the default results - the query results you asked for + are below them. + +In either view, you are looking for grey or black cells, which indicate +flakiness. Clicking one of these cells will let you see the actual log of these +failures; you should eyeball a couple of these to make sure that it's the same +kind of flake. It's also a good idea to look through history (scroll right) to +see if the flakes started at a specific point, in which case you can look for +culprit CLs around there. In general, for a flaky test, you should either: + +* Revert a culprit CL, if you can find it, or +* [Disable the test][gtest-disable] it as narrowly as possible to fix the flake + (eg, if the test is broken on Windows, only disable it on Windows) + +For more advice on dealing with flaky tests, look at the "Test Failed" section +below under "Diagnosing Build Failures". + +### Tree Status Page + +The [tree status page] tracks and lets you +set the state of the Chromium tree. You'll need this page to reopen the tree, +and sometimes to find out who previously closed it if it was manually closed. +The tree states are: + +* "Open": green banner. The CQ runs and commits land as normal +* "Closed": red banner. The CQ will not run; commits can still land via direct + submit (which is how you'll land fix commits) or CQ bypass +* "Throttled": yellow banner. semi-synonymous with "closed". In theory this + means "ask the sheriff before landing a change", but in practice this state + is not used now and few people know what it means. + +Note that various pieces of automation parse the tree state directly from the +textual message, and some pieces update it automatically as well - e.g., if the +tree is automatically closed by a builder, it will automatically reopen if that +builder goes green. To satisfy that automation, the message should always be +formatted as "Tree is $state ($details)", like: + +* "Tree is open ('s all good!)" +* "Tree is closed (sheriff investigating win bot infra failure)" + +Another key phrase is "channel is sheriff", which roughly means "nobody is +on-duty as sheriff right now"; you can use this if (eg) you are the only sheriff +on duty and you need to be away for more than 15min or so: + +* "Tree is open (channel is sheriff, back at 1330 UTC)" + +## The Sheriffing Loop + +You are on duty during your normal work hours; don't worry about adjusting your +work hours for maximum coverage or anything like that. + +Note that you are expected **not** to do any of your normal project work while +you are on sheriff duty - you are expected to be spending 100% of your work time +on the sheriffing work listed here. + +While you are on duty and at your desk, you should be in the "sheriffing loop", +which goes like this: + +### 1. Is The Tree Closed? + +If yes: + +* Start a new thread immediately in Slack - don't wait until you have started + investigating or "have something to say" to do this! +* Start figuring out what went wrong and working on fixing it +* Once it's fixed, or you're pretty confident it's fixed, reopen the tree + +Do not wait for a slow builder to cycle green before reopening if you are +reasonably confident you have landed a fix - "90% confidence" is an okay +threshold for a reopen. + +### 2. Are there consistent failures in sheriff-o-matic? + +If yes: + +* Start a new thread in Slack for one of the failures +* Investigate the failure and figure out why it happened - see the "diagnosing + build failures" section below +* Fix what went wrong +* Snooze the failure, with a link to the bug if your investigation resulted in a + bug + +### 3. Are there other red bots on the waterfall? + +If yes: + +* Start a new thread in Slack for one of the bots +* Investigate the bot - has it been red for a long time, or newly so? Is it an + important bot to someone? +* Fix, notify, or bother people as appropriate + +### 4. Does anything in the sheriff-o-matic bug queue need action? + +If yes: + +* Find the relevant Slack thread or start a new one +* Investigate the bug and see what needs to happen - ping the owner, see if the + priority & assignment are right, or try fixing it yourself. Check if it still + needs to be in the queue! + +### 5. All's well? + +If none of the above conditions obtain, it's time to do some longer-term project +health work! + +* Look for disabled/flaky tests and try to figure out how to re-enable them +* Look through test expectation files and see if expectations are obsolete or + can be removed +* Re-triage old or forgotten bugs +* Manually hunt through the flakiness dashboards for flaky tests and mark them + as such or file bugs for them +* Honestly, maybe just take a break, then restart the loop :) + +**Don't go back to doing your regular project work** - sheriffing is a full-time +job while your shift is happening. + +## Diagnosing Build Failures + +This section discusses how to figure out what's wrong with a failed build. +Generally a build fails for one of four reasons, each of which has its own +section below. + +### Compile Failed + +You can spot this kind of failure because the "Compile" step is marked red on +the bot's page. For this kind of failure the cause is virtually always a CL in +the bot's blamelist; find that CL and revert it. If you can't find the CL, try +reproducing the build config for the bot locally and seeing if you can reproduce +the compile failure. If you don't have that build setup (eg, the broken bot is +an iOS bot and you are a Linux developer and thus unable to build for iOS), get +in touch with members of that team for help reproing / fixing the failure. +Remember that you are empowered to pull in other engineers to help you fix the +tree! + +### Test Failed + +You can spot this kind of failure by a test step being marked red on the bot's +page. Note that test steps with "(experimental)" at the end don't count - these +can fail without turning the entire bot red, and can usually be safely ignored. +Also, if a suite fails, it is usually best to focus on the first failed test +within the suite, since a failing test will sometimes disturb the state of the +test runner for the rest of the tests. + +Take a look at the first red step. The buildbot page will probably say something +like "Deterministic failures: Foo.Bar", and then "Flaky failures: Baz.Quxx +(ignored)". You too can ignore the flaky failures for the moment - the +deterministic failures are the ones that actually made the step go red. Note +that here "deterministic" means "failed twice in a row" and "flaky" means +"failed once", so a deterministic failure can still be caused by a flake. + +From here there are a couple of places to go: + +* If a set of related-looking tests have all failed, probably something in the + blamelist caused it; the other option is that some framework or service that + all of them depend upon flaked at the same time. One example of this kind of + framework flake is the infamous [bug 869227](https://crbug.com/869227). +* If a single test failed, check the blamelist for any obvious culprits; + otherwise, check the flakiness dashboard for that test and see if the test + should be marked as flaky. +* If a LOT of tests failed, look for common symptoms in the output of a handful + of them at random; this will probably point you at either a CL in the + blamelist or some framework/service flake culprit. Also check the sheriff bug + queue to see if there are possible causes listed there. + +When debugging a `layout_tests` failure: use the `layout_test_results` step link +from the bot page; this will give you a useful UI that lets you see image diffs +and similar. This will be under "archive results" usually. + +One thing to specifically look out for: if a test is often slow, it will +sometimes flakily time out on bots that are extra-slow, especially bots that run +sanitizers (MSAN/TSAN/ASAN) or debug bots. If you see flaky timeouts for a test, +but only on these bots, that test might just be slow. For Blink tests there is a +file called [SlowTests] that lists these tests and gives them more time to run; +for Chromium tests you can just mark these as `DISABLED_` in those configurations +if you want. + +### Infra Breakage + +If a bot turns purple rather than red, that indicates an infra failure of some +type. These can have unpredictable effects, and in particular, if a bot goes red +after a purple run, that can often be caused by corrupt disk state on the bot. +Ask a trooper for help with this via [go/bugatrooper][bug-a-trooper]. Do not +immediately ping in [#ops][slack-ops] unless you have just filed (or are about +to file) a Pri-0 infra bug, or you have a Pri-1 bug that has been ignored for >2 +hours. + +### Other Causes + +There are many other things that can go wrong, which are too individually rare +and numerous to be listed here. Ask for help with diagnosis in Slack #sheriffing +and hopefully someone else will be able to help you figure it out. + +[CI console page]: https://ci.chromium.org/p/chromium/g/chromium/console +[SlowTests]: https://cs.chromium.org/chromium/src/third_party/blink/web_tests/SlowTests +[TBRs]: https://chromium.googlesource.com/chromium/src/+/master/docs/code_reviews.md#TBR-To-Be-Reviewed +[bug-a-trooper](https://goto.google.com/bugatrooper) +[contacting-troopers]: https://chromium.googlesource.com/infra/infra/+/master/doc/users/contacting_troopers.md +[get-the-code]: https://www.chromium.org/developers/how-tos/get-the-code +[goma]: http://shortn/_Iox00npQJW +[gtest-disable]: https://github.com/google/googletest/blob/master/googletest/docs/faq.md#how-do-i-temporarily-disable-a-test +[new flakiness dashboard]: https://analysis.chromium.org/p/chromium/flake-portal +[old flakiness dashboard]: https://test-results.appspot.com/dashboards/flakiness_dashboard.html +[sheriff-o-matic]: https://sheriff-o-matic.appspot.com/chromium +[slack #halp]: https://chromium.slack.com/messages/CGGPN5GDT/ +[slack #ops]: https://chromium.slack.com/messages/CGM8DQ3ST/ +[slack #sheriffing]: https://chromium.slack.com/messages/CGJ5WKRUH/ +[slack]: https://chromium.slack.com +[tree status page]: https://chromium-status.appspot.com/
diff --git a/docs/vscode.md b/docs/vscode.md index d598b97d5..0dff926 100644 --- a/docs/vscode.md +++ b/docs/vscode.md
@@ -313,7 +313,6 @@ ``` "git.autorefresh": false, "C_Cpp.autocomplete": "Disabled", -"C_Cpp.addWorkspaceRootToIncludePath": false ``` ### Unable to open $File resource is not available when debugging Chromium on Linux
diff --git a/extensions/browser/api/declarative_net_request/ruleset_source.cc b/extensions/browser/api/declarative_net_request/ruleset_source.cc index 7a3c34f..0330777 100644 --- a/extensions/browser/api/declarative_net_request/ruleset_source.cc +++ b/extensions/browser/api/declarative_net_request/ruleset_source.cc
@@ -347,19 +347,20 @@ // the callee interface. auto repeating_callback = base::AdaptCallbackForRepeating(std::move(callback)); - auto error_callback = base::BindRepeating(&OnSafeJSONParserError, - repeating_callback, json_path_); + auto error_callback = + base::BindOnce(&OnSafeJSONParserError, repeating_callback, json_path_); - auto success_callback = base::BindRepeating(&OnSafeJSONParserSuccess, Clone(), - repeating_callback); + auto success_callback = + base::BindOnce(&OnSafeJSONParserSuccess, Clone(), repeating_callback); if (decoder_batch_id) { - data_decoder::SafeJsonParser::ParseBatch(connector, json_contents, - success_callback, error_callback, - *decoder_batch_id); + data_decoder::SafeJsonParser::ParseBatch( + connector, json_contents, std::move(success_callback), + std::move(error_callback), *decoder_batch_id); } else { data_decoder::SafeJsonParser::Parse(connector, json_contents, - success_callback, error_callback); + std::move(success_callback), + std::move(error_callback)); } }
diff --git a/extensions/browser/extension_event_histogram_value.h b/extensions/browser/extension_event_histogram_value.h index b5898a5..2b551d51 100644 --- a/extensions/browser/extension_event_histogram_value.h +++ b/extensions/browser/extension_event_histogram_value.h
@@ -46,8 +46,8 @@ AUDIO_ON_DEVICES_CHANGED = 25, AUDIO_ON_LEVEL_CHANGED = 26, AUDIO_ON_MUTE_CHANGED = 27, - AUTOFILL_PRIVATE_ON_ADDRESS_LIST_CHANGED = 28, - AUTOFILL_PRIVATE_ON_CREDIT_CARD_LIST_CHANGED = 29, + AUTOFILL_PRIVATE_ON_ADDRESS_LIST_CHANGED_DEPRECATED = 28, + AUTOFILL_PRIVATE_ON_CREDIT_CARD_LIST_CHANGED_DEPRECATED = 29, AUTOMATION_INTERNAL_ON_ACCESSIBILITY_EVENT = 30, AUTOMATION_INTERNAL_ON_ACCESSIBILITY_TREE_DESTROYED = 31, BLUETOOTH_LOW_ENERGY_ON_CHARACTERISTIC_VALUE_CHANGED = 32, @@ -457,6 +457,7 @@ MIME_HANDLER_PRIVATE_SAVE = 436, RUNTIME_ON_CONNECT_NATIVE = 437, ACTION_ON_CLICKED = 438, + AUTOFILL_PRIVATE_ON_PERSONAL_DATA_CHANGED = 439, // Last entry: Add new entries above, then run: // python tools/metrics/histograms/update_extension_histograms.py ENUM_BOUNDARY
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_embedder.cc b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_embedder.cc index 22ef239c..c000d00 100644 --- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_embedder.cc +++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_embedder.cc
@@ -186,7 +186,8 @@ // Full page plugin refers to <iframe> or main frame navigations to a // MimeHandlerView resource. In such cases MHVG does not have a frame // container. - bool is_full_page = !guest_view->maybe_has_frame_container(); + bool is_full_page = !guest_view->maybe_has_frame_container() && + !guest_view->GetEmbedderFrame()->GetParent(); MimeHandlerViewAttachHelper::Get(embedder_frame_process_id) ->AttachToOuterWebContents(guest_view, embedder_frame_process_id, outer_contents_rfh, element_instance_id_,
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc index ffee5a4..cf367d3 100644 --- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc +++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc
@@ -169,6 +169,9 @@ owner_type == blink::FrameOwnerElementType::kEmbed || owner_type == blink::FrameOwnerElementType::kObject; DCHECK_NE(MSG_ROUTING_NONE, embedder_widget_routing_id_); + if (content::MimeHandlerViewMode::UsesCrossProcessFrame()) + delegate_->RecordLoadMetric( + /* in_main_frame */ !GetEmbedderFrame()->GetParent(), mime_type_); } void MimeHandlerViewGuest::SetBeforeUnloadController( @@ -199,6 +202,7 @@ std::move(callback).Run(nullptr); return; } + mime_type_ = stream_->mime_type(); const Extension* mime_handler_extension = // TODO(lazyboy): Do we need handle the case where the extension is // terminated (ExtensionRegistry::TERMINATED)?
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h index 9bdd744..7cdbfafb 100644 --- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h +++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h
@@ -109,6 +109,8 @@ // parent frame of the embedder frame (for post message). bool maybe_has_frame_container() const { return maybe_has_frame_container_; } + const std::string& mime_type() const { return mime_type_; } + base::WeakPtr<MimeHandlerViewGuest> GetWeakPtr(); protected: @@ -194,6 +196,8 @@ bool is_embedder_fullscreen_ = false; bool plugin_can_save_ = false; GURL original_resource_url_; + std::string mime_type_; + // True when the MimeHandlerViewGeust might have a frame container in its // embedder's parent frame to facilitate postMessage. bool maybe_has_frame_container_ = false;
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.cc b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.cc index 63b81b8a7..7f1e5a0 100644 --- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.cc +++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.cc
@@ -12,4 +12,8 @@ return false; } +void MimeHandlerViewGuestDelegate::RecordLoadMetric( + bool in_main_frame, + const std::string& mime_type) {} + } // namespace extensions
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h index 0928bf2f..98689e26 100644 --- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h +++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h
@@ -5,6 +5,8 @@ #ifndef EXTENSIONS_BROWSER_GUEST_VIEW_MIME_HANDLER_VIEW_MIME_HANDLER_VIEW_GUEST_DELEGATE_H_ #define EXTENSIONS_BROWSER_GUEST_VIEW_MIME_HANDLER_VIEW_MIME_HANDLER_VIEW_GUEST_DELEGATE_H_ +#include <string> + #include "base/macros.h" namespace content { @@ -23,6 +25,9 @@ // Handles context menu, or returns false if unhandled. virtual bool HandleContextMenu(content::WebContents* web_contents, const content::ContextMenuParams& params); + // Called when MimeHandlerViewGuest has an associated embedder frame. + virtual void RecordLoadMetric(bool in_main_frame, + const std::string& mime_type); private: DISALLOW_COPY_AND_ASSIGN(MimeHandlerViewGuestDelegate);
diff --git a/extensions/browser/zipfile_installer.cc b/extensions/browser/zipfile_installer.cc index 5efc4e4..3fc0f68 100644 --- a/extensions/browser/zipfile_installer.cc +++ b/extensions/browser/zipfile_installer.cc
@@ -140,8 +140,8 @@ data_decoder::SafeJsonParser::Parse( connector_, *manifest_content, - base::Bind(&ZipFileInstaller::ManifestParsed, this, unzip_dir), - base::Bind(&ZipFileInstaller::ManifestParsingFailed, this)); + base::BindOnce(&ZipFileInstaller::ManifestParsed, this, unzip_dir), + base::BindOnce(&ZipFileInstaller::ManifestParsingFailed, this)); } void ZipFileInstaller::ManifestParsingFailed(const std::string& error) {
diff --git a/extensions/common/api/_manifest_features.json b/extensions/common/api/_manifest_features.json index 95aad7e..bd848bcd 100644 --- a/extensions/common/api/_manifest_features.json +++ b/extensions/common/api/_manifest_features.json
@@ -51,7 +51,7 @@ "background.persistent": { "channel": "stable", "extension_types": [ - "extension", "legacy_packaged_app" + "extension", "legacy_packaged_app", "login_screen_extension" ], "min_manifest_version": 2 },
diff --git a/ios/chrome/app/BUILD.gn b/ios/chrome/app/BUILD.gn index d011609..1d2dc2e6 100644 --- a/ios/chrome/app/BUILD.gn +++ b/ios/chrome/app/BUILD.gn
@@ -247,6 +247,7 @@ "//ios/public/provider/chrome/browser/user_feedback", "//ios/testing/perf:startup", "//ios/third_party/material_roboto_font_loader_ios", + "//ios/web/public/webui", "//mojo/core/embedder", "//net", "//services/identity/public/cpp:cpp",
diff --git a/ios/chrome/app/startup/BUILD.gn b/ios/chrome/app/startup/BUILD.gn index 2add34f..84b0503 100644 --- a/ios/chrome/app/startup/BUILD.gn +++ b/ios/chrome/app/startup/BUILD.gn
@@ -25,7 +25,7 @@ "//base", "//components/crash/core/common", "//ios/chrome/browser:chrome_paths", - "//ios/web/public/app", + "//ios/web/public/init", "//skia", ] @@ -62,7 +62,7 @@ "//ios/net", "//ios/public/provider/chrome/browser", "//ios/web", - "//ios/web/public/app", + "//ios/web/public/init", ios_provider_target, ] }
diff --git a/ios/chrome/app/startup/ios_chrome_main.mm b/ios/chrome/app/startup/ios_chrome_main.mm index 382c2ee..c6a52e3d 100644 --- a/ios/chrome/app/startup/ios_chrome_main.mm +++ b/ios/chrome/app/startup/ios_chrome_main.mm
@@ -12,7 +12,7 @@ #include "base/strings/string_piece.h" #include "base/strings/sys_string_conversions.h" #include "base/time/time.h" -#include "ios/web/public/app/web_main_runner.h" +#include "ios/web/public/init/web_main_runner.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support."
diff --git a/ios/chrome/app/startup/ios_chrome_main_delegate.h b/ios/chrome/app/startup/ios_chrome_main_delegate.h index 6455c3c8..4f25bb5 100644 --- a/ios/chrome/app/startup/ios_chrome_main_delegate.h +++ b/ios/chrome/app/startup/ios_chrome_main_delegate.h
@@ -6,7 +6,7 @@ #define IOS_CHROME_APP_STARTUP_IOS_CHROME_MAIN_DELEGATE_H_ #include "base/macros.h" -#include "ios/web/public/app/web_main_delegate.h" +#include "ios/web/public/init/web_main_delegate.h" // Implementation of WebMainDelegate for Chrome on iOS. class IOSChromeMainDelegate : public web::WebMainDelegate {
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 81a9125f..1367fce 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -504,23 +504,23 @@ <message name="IDS_IOS_CLEAR_BROWSING_DATA_HISTORY_NOTICE_OPEN_HISTORY_BUTTON" desc="Title of a button that allows the user to open history.google.com. [Length: 15em]"> Open history.google.com </message> - <message name="IDS_IOS_CLEAR_BROWSING_DATA_TIME_RANGE_OPTION_BEGINNING_OF_TIME" desc="Label of a time range option. This is used to specify that the user wishes to clear their browsing data since the beginning of time. In titlecase. [Length: 22em] [iOS only]"> - Beginning of Time + <message name="IDS_IOS_CLEAR_BROWSING_DATA_TIME_RANGE_OPTION_BEGINNING_OF_TIME" desc="Label of a time range option. This is used to specify that the user wishes to clear their browsing data since the beginning of time. In titlecase."> + All Time </message> - <message name="IDS_IOS_CLEAR_BROWSING_DATA_TIME_RANGE_OPTION_LAST_FOUR_WEEKS" desc="Label of a time range option. This is used to specify that the user wishes to clear their browsing data for the last 4 weeks. In titlecase. [Length: 22em] [iOS only]"> + <message name="IDS_IOS_CLEAR_BROWSING_DATA_TIME_RANGE_OPTION_LAST_FOUR_WEEKS" desc="Label of a time range option. This is used to specify that the user wishes to clear their browsing data for the last 4 weeks. In titlecase."> Last 4 Weeks </message> - <message name="IDS_IOS_CLEAR_BROWSING_DATA_TIME_RANGE_OPTION_OLDER_THAN_30_DAYS" desc="Label of a time range option. This is used to specify that the user wishes to clear their browsing data that is older than 30 days. In titlecase. [Length: 22em] [iOS only]"> + <message name="IDS_IOS_CLEAR_BROWSING_DATA_TIME_RANGE_OPTION_OLDER_THAN_30_DAYS" desc="Label of a time range option. This is used to specify that the user wishes to clear their browsing data that is older than 30 days. In titlecase."> Older than 30 days </message> - <message name="IDS_IOS_CLEAR_BROWSING_DATA_TIME_RANGE_OPTION_PAST_DAY" desc="Label of a time range option. This is used to specify that the user wishes to clear their browsing data for the past day. In titlecase. [Length: 22em] [iOS only]"> - Past Day + <message name="IDS_IOS_CLEAR_BROWSING_DATA_TIME_RANGE_OPTION_PAST_DAY" desc="Label of a time range option. This is used to specify that the user wishes to clear their browsing data for the past day. In titlecase."> + Last 24 Hours </message> - <message name="IDS_IOS_CLEAR_BROWSING_DATA_TIME_RANGE_OPTION_PAST_HOUR" desc="Label of a time range option. This is used to specify that the user wishes to clear their browsing data for the past hour. In titlecase. [Length: 22em] [iOS only]"> - Past Hour + <message name="IDS_IOS_CLEAR_BROWSING_DATA_TIME_RANGE_OPTION_PAST_HOUR" desc="Label of a time range option. This is used to specify that the user wishes to clear their browsing data for the past hour. In titlecase."> + Last Hour </message> - <message name="IDS_IOS_CLEAR_BROWSING_DATA_TIME_RANGE_OPTION_PAST_WEEK" desc="Label of a time range option. This is used to specify that the user wishes to clear their browsing data for the past week. In titlecase. [Length: 22em] [iOS only]"> - Past Week + <message name="IDS_IOS_CLEAR_BROWSING_DATA_TIME_RANGE_OPTION_PAST_WEEK" desc="Label of a time range option. This is used to specify that the user wishes to clear their browsing data for the past week. In titlecase."> + Last 7 Days </message> <message name="IDS_IOS_CLEAR_BROWSING_DATA_TIME_RANGE_SELECTOR_TITLE" desc="Title for the view that allows the user to pick a time range. The selector is used to pick the time period for which to clear the browsing data. In titlecase. [Length: 13em] [iOS only]"> Time Range
diff --git a/ios/chrome/browser/BUILD.gn b/ios/chrome/browser/BUILD.gn index c0dc842..d606b43 100644 --- a/ios/chrome/browser/BUILD.gn +++ b/ios/chrome/browser/BUILD.gn
@@ -221,7 +221,7 @@ "//ios/chrome/common/app_group", "//ios/public/provider/chrome/browser", "//ios/web", - "//ios/web/public/app", + "//ios/web/public/init", "//net", "//rlz/buildflags", "//services/network:network_service",
diff --git a/ios/chrome/browser/browser_state/BUILD.gn b/ios/chrome/browser/browser_state/BUILD.gn index 9d8b2190..39a6910 100644 --- a/ios/chrome/browser/browser_state/BUILD.gn +++ b/ios/chrome/browser/browser_state/BUILD.gn
@@ -22,6 +22,7 @@ "//components/sync_preferences", "//components/variations/net", "//ios/chrome/browser/net:net_types", + "//ios/web/public/webui", ] configs += [ "//build/config/compiler:enable_arc" ] @@ -119,7 +120,6 @@ "//ios/net", "//ios/public/provider/chrome/browser", "//ios/public/provider/chrome/browser/signin", - "//ios/web", "//ios/web/net/cookies", "//net", "//net:extras",
diff --git a/ios/chrome/browser/ios_chrome_io_thread.mm b/ios/chrome/browser/ios_chrome_io_thread.mm index 23b26f0..f3b195a 100644 --- a/ios/chrome/browser/ios_chrome_io_thread.mm +++ b/ios/chrome/browser/ios_chrome_io_thread.mm
@@ -7,7 +7,7 @@ #include "components/variations/net/variations_http_headers.h" #include "ios/chrome/browser/net/ios_chrome_network_delegate.h" #include "ios/chrome/common/channel_info.h" -#include "ios/web/public/network_context_owner.h" +#include "ios/web/public/init/network_context_owner.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/chrome/browser/ios_chrome_main_parts.h b/ios/chrome/browser/ios_chrome_main_parts.h index d3bb1eef..d8e39651 100644 --- a/ios/chrome/browser/ios_chrome_main_parts.h +++ b/ios/chrome/browser/ios_chrome_main_parts.h
@@ -11,7 +11,7 @@ #include "base/macros.h" #include "base/metrics/field_trial.h" #include "ios/chrome/browser/ios_chrome_field_trials.h" -#include "ios/web/public/app/web_main_parts.h" +#include "ios/web/public/init/web_main_parts.h" class ApplicationContextImpl; class PrefService;
diff --git a/ios/chrome/browser/ios_first_run_field_trials.cc b/ios/chrome/browser/ios_first_run_field_trials.cc index 97fc02a..6c24be8 100644 --- a/ios/chrome/browser/ios_first_run_field_trials.cc +++ b/ios/chrome/browser/ios_first_run_field_trials.cc
@@ -16,20 +16,7 @@ // FirstRunFieldTrialConfig FirstRunFieldTrialConfig::FirstRunFieldTrialConfig( const std::string& trial_name) - : FirstRunFieldTrialConfig(trial_name, - base::FieldTrialList::kNoExpirationYear, - 1, - 1) {} - -FirstRunFieldTrialConfig::FirstRunFieldTrialConfig( - const std::string& trial_name, - int year, - int month, - int day_of_month) - : trial_name_(trial_name), - expire_year_(year), - expire_month_(month), - expire_day_of_month_(day_of_month) {} + : trial_name_(trial_name) {} FirstRunFieldTrialConfig::~FirstRunFieldTrialConfig() {}
diff --git a/ios/chrome/browser/ios_first_run_field_trials.h b/ios/chrome/browser/ios_first_run_field_trials.h index 59162ea..149e19e 100644 --- a/ios/chrome/browser/ios_first_run_field_trials.h +++ b/ios/chrome/browser/ios_first_run_field_trials.h
@@ -37,15 +37,8 @@ // at first run must be pre-defined in client code. class FirstRunFieldTrialConfig { public: - // Initializes with |trial_name| as the name of the FieldTrial with default - // duration. + // Initializes with |trial_name| as the name of the FieldTrial. FirstRunFieldTrialConfig(const std::string& trial_name); - // Initializes with |trial_name| as the name of the FieldTrial and one that - // ends on (year, month, day_of_month). - FirstRunFieldTrialConfig(const std::string& trial_name, - int year, - int month, - int day_of_month); ~FirstRunFieldTrialConfig(); // Adds a new FieldTrial group of |name| with a probability of |percentage|. @@ -58,16 +51,10 @@ const std::vector<FirstRunFieldTrialGroup>& groups() const { return groups_; } // Accessors for this FieldTrial. const std::string& trial_name() { return trial_name_; } - int expire_year() { return expire_year_; } - int expire_month() { return expire_month_; } - int expire_day_of_month() { return expire_day_of_month_; } private: std::string trial_name_; std::vector<FirstRunFieldTrialGroup> groups_; - int expire_year_; - int expire_month_; - int expire_day_of_month_; DISALLOW_COPY_AND_ASSIGN(FirstRunFieldTrialConfig); };
diff --git a/ios/chrome/browser/json_parser/in_process_json_parser.cc b/ios/chrome/browser/json_parser/in_process_json_parser.cc index 581c41a..72e6be7 100644 --- a/ios/chrome/browser/json_parser/in_process_json_parser.cc +++ b/ios/chrome/browser/json_parser/in_process_json_parser.cc
@@ -15,21 +15,21 @@ void ParseJsonOnBackgroundThread( scoped_refptr<base::TaskRunner> task_runner, const std::string& unsafe_json, - const InProcessJsonParser::SuccessCallback& success_callback, - const InProcessJsonParser::ErrorCallback& error_callback) { + InProcessJsonParser::SuccessCallback success_callback, + InProcessJsonParser::ErrorCallback error_callback) { DCHECK(task_runner); base::JSONReader::ValueWithError value_with_error = base::JSONReader::ReadAndReturnValueWithError(unsafe_json, base::JSON_PARSE_RFC); if (value_with_error.value) { - task_runner->PostTask( - FROM_HERE, - base::BindOnce(success_callback, std::move(*value_with_error.value))); + task_runner->PostTask(FROM_HERE, + base::BindOnce(std::move(success_callback), + std::move(*value_with_error.value))); } else { task_runner->PostTask( FROM_HERE, base::BindOnce( - error_callback, + std::move(error_callback), base::StringPrintf( "%s (%d:%d)", value_with_error.error_message.c_str(), value_with_error.error_line, value_with_error.error_column))); @@ -39,11 +39,11 @@ // static void InProcessJsonParser::Parse(const std::string& unsafe_json, - const SuccessCallback& success_callback, - const ErrorCallback& error_callback) { + SuccessCallback success_callback, + ErrorCallback error_callback) { base::PostTaskWithTraits( FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, base::BindOnce(&ParseJsonOnBackgroundThread, base::ThreadTaskRunnerHandle::Get(), unsafe_json, - success_callback, error_callback)); + std::move(success_callback), std::move(error_callback))); }
diff --git a/ios/chrome/browser/json_parser/in_process_json_parser.h b/ios/chrome/browser/json_parser/in_process_json_parser.h index b79b9bd8..ad6b10c 100644 --- a/ios/chrome/browser/json_parser/in_process_json_parser.h +++ b/ios/chrome/browser/json_parser/in_process_json_parser.h
@@ -24,15 +24,14 @@ // have to be added to SafeJsonParser and this class removed. class InProcessJsonParser { public: - // TODO(crbug.com/964232): Convert to base::OnceCallback with SafeJsonParser. - using SuccessCallback = base::Callback<void(base::Value)>; - using ErrorCallback = base::Callback<void(const std::string&)>; + using SuccessCallback = base::OnceCallback<void(base::Value)>; + using ErrorCallback = base::OnceCallback<void(const std::string&)>; // As with SafeJsonParser, runs either |success_callback| or |error_callback| // on the calling thread, but not before the call returns. static void Parse(const std::string& unsafe_json, - const SuccessCallback& success_callback, - const ErrorCallback& error_callback); + SuccessCallback success_callback, + ErrorCallback error_callback); InProcessJsonParser() = delete; };
diff --git a/ios/chrome/browser/json_parser/in_process_json_parser_unittest.cc b/ios/chrome/browser/json_parser/in_process_json_parser_unittest.cc index c940a99e..5331f846 100644 --- a/ios/chrome/browser/json_parser/in_process_json_parser_unittest.cc +++ b/ios/chrome/browser/json_parser/in_process_json_parser_unittest.cc
@@ -16,20 +16,20 @@ base::RunLoop run_loop; InProcessJsonParser::Parse( R"json({"key": 1})json", - base::AdaptCallbackForRepeating(base::BindOnce( + base::BindOnce( [](base::Closure quit_closure, base::Value value) { ASSERT_TRUE(value.is_dict()); ASSERT_TRUE(value.FindIntKey("key")); EXPECT_EQ(1, *value.FindIntKey("key")); std::move(quit_closure).Run(); }, - run_loop.QuitClosure())), - base::AdaptCallbackForRepeating(base::BindOnce( + run_loop.QuitClosure()), + base::BindOnce( [](base::Closure quit_closure, const std::string& error) { EXPECT_FALSE(true) << "unexpected json parse error: " << error; std::move(quit_closure).Run(); }, - run_loop.QuitClosure()))); + run_loop.QuitClosure())); run_loop.Run(); } @@ -39,17 +39,17 @@ base::RunLoop run_loop; InProcessJsonParser::Parse( R"json(invalid)json", - base::AdaptCallbackForRepeating(base::BindOnce( + base::BindOnce( [](base::Closure quit_closure, base::Value value) { EXPECT_FALSE(true) << "unexpected json parse success: " << value; std::move(quit_closure).Run(); }, - run_loop.QuitClosure())), - base::AdaptCallbackForRepeating(base::BindOnce( + run_loop.QuitClosure()), + base::BindOnce( [](base::Closure quit_closure, const std::string& error) { EXPECT_TRUE(!error.empty()); std::move(quit_closure).Run(); }, - run_loop.QuitClosure()))); + run_loop.QuitClosure())); run_loop.Run(); }
diff --git a/ios/chrome/browser/tabs/tab_unittest.mm b/ios/chrome/browser/tabs/tab_unittest.mm index 7e127d37..b3dc40e9 100644 --- a/ios/chrome/browser/tabs/tab_unittest.mm +++ b/ios/chrome/browser/tabs/tab_unittest.mm
@@ -14,6 +14,7 @@ #include "base/run_loop.h" #include "base/strings/stringprintf.h" #include "base/strings/sys_string_conversions.h" +#include "base/test/bind_test_util.h" #include "base/test/scoped_feature_list.h" #include "components/bookmarks/test/bookmark_test_helpers.h" #include "components/history/core/browser/history_service.h" @@ -120,30 +121,6 @@ namespace { -// Observer of a QueryHistory request. -class HistoryQueryResultsObserver - : public base::RefCountedThreadSafe<HistoryQueryResultsObserver> { - public: - HistoryQueryResultsObserver(base::RunLoop* run_loop) : run_loop_(run_loop) {} - - // Stores |results| and stops the current message loop. - void ProcessResults(history::QueryResults* results) { - results_.Swap(results); - run_loop_->QuitWhenIdle(); - } - history::QueryResults* results() { return &results_; } - - protected: - friend base::RefCountedThreadSafe<HistoryQueryResultsObserver>; - virtual ~HistoryQueryResultsObserver(); - - private: - history::QueryResults results_; - base::RunLoop* run_loop_; -}; - -HistoryQueryResultsObserver::~HistoryQueryResultsObserver() {} - // TabTest is parameterized on this enum to test both LegacyNavigationManager // and WKBasedNavigationManager. enum class NavigationManagerChoice { @@ -296,19 +273,17 @@ } void QueryAllHistory(history::QueryResults* results) { - base::CancelableTaskTracker tracker; base::RunLoop run_loop; - scoped_refptr<HistoryQueryResultsObserver> observer( - new HistoryQueryResultsObserver(&run_loop)); - history::HistoryService* history_service = - ios::HistoryServiceFactory::GetForBrowserState( - chrome_browser_state_.get(), ServiceAccessType::EXPLICIT_ACCESS); - history_service->QueryHistory( - base::string16(), history::QueryOptions(), - base::Bind(&HistoryQueryResultsObserver::ProcessResults, observer), - &tracker); + base::CancelableTaskTracker tracker; + ios::HistoryServiceFactory::GetForBrowserState( + chrome_browser_state_.get(), ServiceAccessType::EXPLICIT_ACCESS) + ->QueryHistory(base::string16(), history::QueryOptions(), + base::BindLambdaForTesting([&](history::QueryResults r) { + *results = std::move(r); + run_loop.Quit(); + }), + &tracker); run_loop.Run(); - results->Swap(observer->results()); } void CheckHistoryResult(const history::URLResult& historyResult,
diff --git a/ios/chrome/browser/ui/main/browser_view_wrangler.mm b/ios/chrome/browser/ui/main/browser_view_wrangler.mm index d9c521c..622fc6f 100644 --- a/ios/chrome/browser/ui/main/browser_view_wrangler.mm +++ b/ios/chrome/browser/ui/main/browser_view_wrangler.mm
@@ -14,17 +14,17 @@ #import "ios/chrome/browser/sessions/session_ios.h" #import "ios/chrome/browser/sessions/session_service_ios.h" #import "ios/chrome/browser/sessions/session_window_ios.h" -#import "ios/chrome/browser/tabs/tab.h" #import "ios/chrome/browser/tabs/tab_model.h" -#import "ios/chrome/browser/tabs/tab_model_observer.h" #import "ios/chrome/browser/ui/browser_view/browser_coordinator.h" #import "ios/chrome/browser/ui/browser_view/browser_view_controller.h" #import "ios/chrome/browser/ui/browser_view/browser_view_controller_dependency_factory.h" #import "ios/chrome/browser/url_loading/app_url_loading_service.h" +#import "ios/chrome/browser/web_state_list/active_web_state_observation_forwarder.h" #import "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/chrome/browser/web_state_list/web_state_list_observer_bridge.h" #include "ios/public/provider/chrome/browser/chrome_browser_provider.h" #import "ios/web/public/web_state/web_state.h" +#import "ios/web/public/web_state/web_state_observer_bridge.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -85,7 +85,7 @@ @end -@interface BrowserViewWrangler () <WebStateListObserving, TabModelObserver> { +@interface BrowserViewWrangler () <WebStateListObserving, CRWWebStateObserver> { ios::ChromeBrowserState* _browserState; __weak id<ApplicationCommands> _applicationCommandEndpoint; __weak id<BrowserStateStorageSwitching> _storageSwitcher; @@ -96,6 +96,13 @@ std::unique_ptr<Browser> _otrBrowser; std::unique_ptr<WebStateListObserverBridge> _webStateListObserver; std::unique_ptr<WebStateListObserverBridge> _webStateListForwardingObserver; + // Bridge to observe WebState from Objective-C. This observer will be used to + // only monitor active webStates. + std::unique_ptr<web::WebStateObserverBridge> _activeWebStateObserver; + // Forwards observer methods for The active WebState in each WebStateList + // monitored by the BrowserViewWrangler. + std::map<WebStateList*, std::unique_ptr<ActiveWebStateObservationForwarder>> + _activeWebStateObservationForwarders; } @property(nonatomic, strong, readwrite) WrangledBrowser* mainInterface; @@ -153,6 +160,8 @@ _webStateListObserver = std::make_unique<WebStateListObserverBridge>(self); _webStateListForwardingObserver = std::make_unique<WebStateListObserverBridge>(observer); + _activeWebStateObserver = + std::make_unique<web::WebStateObserverBridge>(self); } return self; } @@ -246,7 +255,7 @@ breakpad::StopMonitoringTabStateForWebStateList(tabModel.webStateList); breakpad::StopMonitoringURLsForWebStateList(tabModel.webStateList); [tabModel browserStateDestroyed]; - [tabModel removeObserver:self]; + _activeWebStateObservationForwarders[tabModel.webStateList] = nullptr; tabModel.webStateList->RemoveObserver(_webStateListObserver.get()); tabModel.webStateList->RemoveObserver( _webStateListForwardingObserver.get()); @@ -260,7 +269,7 @@ TabModel* tabModel = self.otrBrowser->GetTabModel(); breakpad::StopMonitoringTabStateForWebStateList(tabModel.webStateList); [tabModel browserStateDestroyed]; - [tabModel removeObserver:self]; + _activeWebStateObservationForwarders[tabModel.webStateList] = nullptr; tabModel.webStateList->RemoveObserver(_webStateListObserver.get()); tabModel.webStateList->RemoveObserver( _webStateListForwardingObserver.get()); @@ -290,9 +299,12 @@ [self updateDeviceSharingManager]; } -#pragma mark - TabModelObserver +#pragma mark - CRWWebStateObserver -- (void)tabModel:(TabModel*)model didChangeTab:(Tab*)tab { +- (void)webState:(web::WebState*)webState + didFinishNavigation:(web::NavigationContext*)navigation { + // Active WebState has update the active URL. Update the DeviceSharingManager + // state. [self updateDeviceSharingManager]; } @@ -305,10 +317,12 @@ [self.deviceSharingManager updateBrowserState:_browserState]; GURL activeURL; - Tab* currentTab = self.currentInterface.tabModel.currentTab; - // Set the active URL if there's a current tab and the current BVC is not OTR. - if (currentTab.webState && !self.currentInterface.incognito) { - activeURL = currentTab.webState->GetVisibleURL(); + web::WebState* activeWebState = + self.currentInterface.tabModel.webStateList->GetActiveWebState(); + // Set the active URL if there's an active webstate and the current BVC is not + // OTR. + if (activeWebState && !self.currentInterface.incognito) { + activeURL = activeWebState->GetVisibleURL(); } [self.deviceSharingManager updateActiveURL:activeURL]; } @@ -415,9 +429,12 @@ } // Add observers. - [tabModel addObserver:self]; + _activeWebStateObservationForwarders[tabModel.webStateList] = + std::make_unique<ActiveWebStateObservationForwarder>( + tabModel.webStateList, _activeWebStateObserver.get()); tabModel.webStateList->AddObserver(_webStateListObserver.get()); tabModel.webStateList->AddObserver(_webStateListForwardingObserver.get()); + breakpad::MonitorTabStateForWebStateList(tabModel.webStateList); }
diff --git a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_manager_unittest.mm b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_manager_unittest.mm index 15f45df..19c20fa 100644 --- a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_manager_unittest.mm +++ b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_manager_unittest.mm
@@ -22,11 +22,13 @@ #import "ios/chrome/browser/ui/settings/clear_browsing_data/fake_browsing_data_counter_wrapper_producer.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_detail_icon_item.h" #import "ios/chrome/browser/ui/table_view/table_view_model.h" +#include "ios/chrome/grit/ios_strings.h" #include "ios/web/public/test/test_web_thread_bundle.h" #include "services/identity/public/cpp/identity_test_environment.h" #include "testing/gtest/include/gtest/gtest.h" #import "testing/gtest_mac.h" #include "testing/platform_test.h" +#include "ui/base/l10n/l10n_util_mac.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -207,7 +209,6 @@ if (!IsNewClearBrowsingDataUIEnabled()) { return; } - ASSERT_EQ("en", GetApplicationContext()->GetApplicationLocale()); [manager_ loadModel:model_]; NSArray* timeRangeItems = [model_ itemsInSectionWithIdentifier:SectionIdentifierTimeRange]; @@ -218,9 +219,14 @@ // Changes of Time Range should trigger updates on Time Range item's // detailText. time_range_pref_.SetValue(2); - EXPECT_NSEQ(@"Past Week", timeRangeItem.detailText); + EXPECT_NSEQ(l10n_util::GetNSString( + IDS_IOS_CLEAR_BROWSING_DATA_TIME_RANGE_OPTION_PAST_WEEK), + timeRangeItem.detailText); time_range_pref_.SetValue(3); - EXPECT_NSEQ(@"Last 4 Weeks", timeRangeItem.detailText); + EXPECT_NSEQ( + l10n_util::GetNSString( + IDS_IOS_CLEAR_BROWSING_DATA_TIME_RANGE_OPTION_LAST_FOUR_WEEKS), + timeRangeItem.detailText); } } // namespace
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm index 13021849..7063bb3 100644 --- a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm +++ b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
@@ -24,7 +24,6 @@ #import "ios/chrome/browser/tabs/legacy_tab_helper.h" #import "ios/chrome/browser/tabs/tab.h" #import "ios/chrome/browser/tabs/tab_model.h" -#import "ios/chrome/browser/tabs/tab_model_observer.h" #import "ios/chrome/browser/tabs/tab_title_util.h" #import "ios/chrome/browser/ui/bubble/bubble_util.h" #import "ios/chrome/browser/ui/bubble/bubble_view.h" @@ -44,11 +43,13 @@ #include "ios/chrome/browser/ui/util/rtl_geometry.h" #include "ios/chrome/browser/ui/util/ui_util.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" +#include "ios/chrome/browser/web_state_list/all_web_state_observation_forwarder.h" #import "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/chrome/browser/web_state_list/web_state_list_favicon_driver_observer.h" #import "ios/chrome/browser/web_state_list/web_state_list_observer_bridge.h" #include "ios/chrome/grit/ios_strings.h" #import "ios/web/public/web_state/web_state.h" +#import "ios/web/public/web_state/web_state_observer_bridge.h" #include "third_party/google_toolbox_for_mac/src/iPhone/GTMFadeTruncatingLabel.h" #include "ui/gfx/image/image.h" @@ -157,7 +158,7 @@ @end @interface TabStripController () <DropAndNavigateDelegate, - TabModelObserver, + CRWWebStateObserver, TabStripViewLayoutDelegate, TabViewDelegate, WebStateListObserving, @@ -244,6 +245,14 @@ std::unique_ptr<WebStateListFaviconDriverObserver> _webStateListFaviconObserver; + // Bridges C++ WebStateObserver methods to this TabStripController. + std::unique_ptr<web::WebStateObserverBridge> _webStateObserver; + + // Forwards observer methods for all WebStates in the WebStateList monitored + // by the TabStripController. + std::unique_ptr<AllWebStateObservationForwarder> + _allWebStateObservationForwarder; + API_AVAILABLE(ios(11.0)) DropAndNavigateInteraction* _buttonNewTabInteraction; } @@ -266,8 +275,8 @@ // |isSelected| is passed in here as an optimization, so that the TabView is // drawn correctly the first time, without requiring the model to send a // -setSelected message to the TabView. -- (TabView*)tabViewForWebState:(web::WebState*)webState - isSelected:(BOOL)isSelected; +- (TabView*)createTabViewForWebState:(web::WebState*)webState + isSelected:(BOOL)isSelected; // Creates and installs the view used to dim unselected tabs. Does nothing if // the view already exists. @@ -378,8 +387,9 @@ // Updates the tab switcher button with the current tab count. - (void)updateTabCount; -// Updates the tab view fav icon & progress spinner based on the |webState|. -- (void)updateTabViewForWebState:(web::WebState*)webState; +// Returns the existing tab view for |webState| or nil if there is no TabView +// for it. +- (TabView*)tabViewForWebState:(web::WebState*)webState; @end @@ -403,12 +413,16 @@ _closingTabs = [[NSMutableSet alloc] initWithCapacity:5]; _tabModel = tabModel; - [_tabModel addObserver:self]; _webStateListObserver = std::make_unique<WebStateListObserverBridge>(self); _tabModel.webStateList->AddObserver(_webStateListObserver.get()); _webStateListFaviconObserver = std::make_unique<WebStateListFaviconDriverObserver>( _tabModel.webStateList, self); + _webStateObserver = std::make_unique<web::WebStateObserverBridge>(self); + // Observe all webStates of this |_tabModel.webStateList|. + _allWebStateObservationForwarder = + std::make_unique<AllWebStateObservationForwarder>( + _tabModel.webStateList, _webStateObserver.get()); _style = style; _dispatcher = dispatcher; @@ -506,7 +520,7 @@ - (void)dealloc { [_tabStripView setDelegate:nil]; [_tabStripView setLayoutDelegate:nil]; - [_tabModel removeObserver:self]; + _allWebStateObservationForwarder.reset(); _tabModel.webStateList->RemoveObserver(_webStateListObserver.get()); } @@ -523,7 +537,8 @@ for (int index = 0; index < webStateList->count(); ++index) { web::WebState* webState = webStateList->GetWebStateAt(index); BOOL isSelected = index == webStateList->active_index(); - TabView* view = [self tabViewForWebState:webState isSelected:isSelected]; + TabView* view = [self createTabViewForWebState:webState + isSelected:isSelected]; [_tabArray addObject:view]; [_tabStripView addSubview:view]; } @@ -550,8 +565,8 @@ return view; } -- (TabView*)tabViewForWebState:(web::WebState*)webState - isSelected:(BOOL)isSelected { +- (TabView*)createTabViewForWebState:(web::WebState*)webState + isSelected:(BOOL)isSelected { TabView* view = [[TabView alloc] initWithEmptyView:NO selected:isSelected]; if (UseRTLLayout()) [view setTransform:CGAffineTransformMakeScale(-1, 1)]; @@ -964,7 +979,55 @@ } #pragma mark - -#pragma mark WebStateObserving methods +#pragma mark - CRWWebStateObserver methods + +- (void)webStateDidStartLoading:(web::WebState*)webState { + // webState can start loading before didInsertWebState is called, in that + // case early return as there is no view to update yet. + if (_tabModel.count > _tabArray.count - _closingTabs.count) + return; + + if (IsVisibleURLNewTabPage(webState)) + return; + + TabView* view = [self tabViewForWebState:webState]; + if (!view) { + DCHECK(false) << "Received start loading notification for a Webstate " + << "that is not contained in the WebStateList"; + return; + } + [view startProgressSpinner]; + [view setNeedsDisplay]; +} + +- (void)webStateDidStopLoading:(web::WebState*)webState { + TabView* view = [self tabViewForWebState:webState]; + if (!view) { + DCHECK(false) << "Received stop loading notification for a Webstate " + << "that is not contained in the WebStateList"; + return; + } + // In new Tab case WebState's DidChangeTitle is not called. Make sure to + // updated the title here to account for that. + [view setTitle:tab_util::GetTabTitle(webState)]; + + [view stopProgressSpinner]; + [view setNeedsDisplay]; +} + +- (void)webStateDidChangeTitle:(web::WebState*)webState { + TabView* view = [self tabViewForWebState:webState]; + if (!view) { + DCHECK(false) << "Received title change notification for a Webstate " + << "that is not contained in the WebStateList"; + return; + } + [view setTitle:tab_util::GetTabTitle(webState)]; + [view setNeedsDisplay]; +} + +#pragma mark - +#pragma mark WebStateListObserving methods // Observer method, active WebState changed. - (void)webStateList:(WebStateList*)webStateList @@ -1048,7 +1111,8 @@ didInsertWebState:(web::WebState*)webState atIndex:(int)index activating:(BOOL)activating { - TabView* view = [self tabViewForWebState:webState isSelected:activating]; + TabView* view = [self createTabViewForWebState:webState + isSelected:activating]; [_tabArray insertObject:view atIndex:[self indexForModelIndex:index]]; [[self tabStripView] addSubview:view]; @@ -1087,37 +1151,14 @@ } #pragma mark - -#pragma mark TabModelObserver methods - -// Observer method. -- (void)tabModel:(TabModel*)model didChangeTab:(Tab*)tab { - // didChangeTab is called with each single webState. Some of these changes - // may happen before didInsertWebState is called, in that case early return as - // there is no view to update yet. - if (_tabModel.count > _tabArray.count - _closingTabs.count) - return; - [self updateTabViewForWebState:tab.webState]; -} - -#pragma mark - #pragma mark Views and Layout -- (void)updateTabViewForWebState:(web::WebState*)webState { +- (TabView*)tabViewForWebState:(web::WebState*)webState { int modelIndex = _tabModel.webStateList->GetIndexOfWebState(webState); - if (modelIndex == WebStateList::kInvalidIndex) { - DCHECK(false) << "Received notification for a Webstate that is not " - << "contained in the WebStateList"; - return; - } + if (modelIndex == WebStateList::kInvalidIndex) + return nil; NSUInteger index = [self indexForModelIndex:modelIndex]; - TabView* view = [_tabArray objectAtIndex:index]; - [view setTitle:tab_util::GetTabTitle(webState)]; - - if (webState->IsLoading() && !IsVisibleURLNewTabPage(webState)) - [view startProgressSpinner]; - else - [view stopProgressSpinner]; - [view setNeedsDisplay]; + return [_tabArray objectAtIndex:index]; } - (CGFloat)tabStripVisibleSpace {
diff --git a/ios/chrome/browser/ui/webui/BUILD.gn b/ios/chrome/browser/ui/webui/BUILD.gn index e2d27aa6..634b672c 100644 --- a/ios/chrome/browser/ui/webui/BUILD.gn +++ b/ios/chrome/browser/ui/webui/BUILD.gn
@@ -68,8 +68,8 @@ "//ios/chrome/browser/web:java_script_console", "//ios/chrome/browser/web_state_list", "//ios/chrome/common", - "//ios/web", "//ios/web/public/js_messaging", + "//ios/web/public/webui", "//net", "//services/service_manager/public/cpp", "//third_party/brotli:dec", @@ -102,7 +102,7 @@ "//ios/chrome/browser/ui/webui/net_export", "//ios/chrome/browser/ui/webui/sync_internals", "//ios/chrome/browser/ui/webui/translate_internals", - "//ios/web", + "//ios/web/public/webui", "//services/identity/public/cpp", "//url", ]
diff --git a/ios/chrome/browser/ui/webui/about_ui.cc b/ios/chrome/browser/ui/webui/about_ui.cc index b070b3f..635083d 100644 --- a/ios/chrome/browser/ui/webui/about_ui.cc +++ b/ios/chrome/browser/ui/webui/about_ui.cc
@@ -18,7 +18,7 @@ #include "google_apis/gaia/google_service_auth_error.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/chrome_url_constants.h" -#include "ios/web/public/url_data_source_ios.h" +#include "ios/web/public/webui/url_data_source_ios.h" #include "net/base/escape.h" #include "third_party/brotli/include/brotli/decode.h" #include "ui/base/device_form_factor.h"
diff --git a/ios/chrome/browser/ui/webui/crashes_ui.cc b/ios/chrome/browser/ui/webui/crashes_ui.cc index 9af79cb..fc654ba 100644 --- a/ios/chrome/browser/ui/webui/crashes_ui.cc +++ b/ios/chrome/browser/ui/webui/crashes_ui.cc
@@ -24,8 +24,8 @@ #include "ios/chrome/browser/crash_report/crash_upload_list.h" #include "ios/chrome/browser/metrics/ios_chrome_metrics_service_accessor.h" #include "ios/chrome/grit/ios_chromium_strings.h" -#include "ios/web/public/web_ui_ios_data_source.h" #include "ios/web/public/webui/web_ui_ios.h" +#include "ios/web/public/webui/web_ui_ios_data_source.h" #include "ios/web/public/webui/web_ui_ios_message_handler.h" namespace {
diff --git a/ios/chrome/browser/ui/webui/flags_ui.cc b/ios/chrome/browser/ui/webui/flags_ui.cc index 7636b29..a03ee05 100644 --- a/ios/chrome/browser/ui/webui/flags_ui.cc +++ b/ios/chrome/browser/ui/webui/flags_ui.cc
@@ -27,8 +27,8 @@ #include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/chrome_url_constants.h" -#include "ios/web/public/web_ui_ios_data_source.h" #include "ios/web/public/webui/web_ui_ios.h" +#include "ios/web/public/webui/web_ui_ios_data_source.h" #include "ios/web/public/webui/web_ui_ios_message_handler.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h"
diff --git a/ios/chrome/browser/ui/webui/gcm/BUILD.gn b/ios/chrome/browser/ui/webui/gcm/BUILD.gn index 12db264..c988404 100644 --- a/ios/chrome/browser/ui/webui/gcm/BUILD.gn +++ b/ios/chrome/browser/ui/webui/gcm/BUILD.gn
@@ -14,6 +14,6 @@ "//ios/chrome/browser", "//ios/chrome/browser/browser_state", "//ios/chrome/browser/gcm", - "//ios/web", + "//ios/web/public/webui", ] }
diff --git a/ios/chrome/browser/ui/webui/gcm/gcm_internals_ui.cc b/ios/chrome/browser/ui/webui/gcm/gcm_internals_ui.cc index 776370a9..fe92f0b 100644 --- a/ios/chrome/browser/ui/webui/gcm/gcm_internals_ui.cc +++ b/ios/chrome/browser/ui/webui/gcm/gcm_internals_ui.cc
@@ -21,8 +21,8 @@ #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/chrome_url_constants.h" #include "ios/chrome/browser/gcm/ios_chrome_gcm_profile_service_factory.h" -#include "ios/web/public/web_ui_ios_data_source.h" #include "ios/web/public/webui/web_ui_ios.h" +#include "ios/web/public/webui/web_ui_ios_data_source.h" #include "ios/web/public/webui/web_ui_ios_message_handler.h" namespace {
diff --git a/ios/chrome/browser/ui/webui/inspect/inspect_ui.mm b/ios/chrome/browser/ui/webui/inspect/inspect_ui.mm index adf6260..02088f7 100644 --- a/ios/chrome/browser/ui/webui/inspect/inspect_ui.mm +++ b/ios/chrome/browser/ui/webui/inspect/inspect_ui.mm
@@ -24,8 +24,8 @@ #include "ios/web/public/js_messaging/web_frame_util.h" #import "ios/web/public/js_messaging/web_frames_manager.h" #import "ios/web/public/web_state/web_state.h" -#include "ios/web/public/web_ui_ios_data_source.h" #include "ios/web/public/webui/web_ui_ios.h" +#include "ios/web/public/webui/web_ui_ios_data_source.h" #include "ios/web/public/webui/web_ui_ios_message_handler.h" #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/chrome/browser/ui/webui/net_export/BUILD.gn b/ios/chrome/browser/ui/webui/net_export/BUILD.gn index 25d8f49a..44de1997 100644 --- a/ios/chrome/browser/ui/webui/net_export/BUILD.gn +++ b/ios/chrome/browser/ui/webui/net_export/BUILD.gn
@@ -17,7 +17,7 @@ "//ios/chrome/browser/browser_state", "//ios/chrome/browser/webui", "//ios/chrome/common:common", - "//ios/web", - "//net:net", + "//ios/web/public/webui", + "//net", ] }
diff --git a/ios/chrome/browser/ui/webui/net_export/net_export_ui.mm b/ios/chrome/browser/ui/webui/net_export/net_export_ui.mm index a868d1a..9534592 100644 --- a/ios/chrome/browser/ui/webui/net_export/net_export_ui.mm +++ b/ios/chrome/browser/ui/webui/net_export/net_export_ui.mm
@@ -25,8 +25,8 @@ #include "ios/chrome/grit/ios_strings.h" #import "ios/web/public/web_state/web_state.h" #include "ios/web/public/web_thread.h" -#include "ios/web/public/web_ui_ios_data_source.h" #include "ios/web/public/webui/web_ui_ios.h" +#include "ios/web/public/webui/web_ui_ios_data_source.h" #include "ios/web/public/webui/web_ui_ios_message_handler.h" #include "net/log/net_log_capture_mode.h" #include "net/url_request/url_request_context_getter.h"
diff --git a/ios/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc b/ios/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc index 6b6c4a76..9d4e075 100644 --- a/ios/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc +++ b/ios/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc
@@ -17,8 +17,8 @@ #include "ios/chrome/browser/ntp_tiles/ios_most_visited_sites_factory.h" #include "ios/chrome/browser/ntp_tiles/ios_popular_sites_factory.h" #include "ios/web/public/web_thread.h" -#include "ios/web/public/web_ui_ios_data_source.h" #include "ios/web/public/webui/web_ui_ios.h" +#include "ios/web/public/webui/web_ui_ios_data_source.h" #include "ios/web/public/webui/web_ui_ios_message_handler.h" namespace {
diff --git a/ios/chrome/browser/ui/webui/omaha_ui.cc b/ios/chrome/browser/ui/webui/omaha_ui.cc index dd5537ee6..e86b636 100644 --- a/ios/chrome/browser/ui/webui/omaha_ui.cc +++ b/ios/chrome/browser/ui/webui/omaha_ui.cc
@@ -13,8 +13,8 @@ #include "ios/chrome/browser/chrome_url_constants.h" #include "ios/chrome/browser/omaha/omaha_service.h" #include "ios/chrome/grit/ios_resources.h" -#include "ios/web/public/web_ui_ios_data_source.h" #include "ios/web/public/webui/web_ui_ios.h" +#include "ios/web/public/webui/web_ui_ios_data_source.h" #include "ios/web/public/webui/web_ui_ios_message_handler.h" using web::WebUIIOSMessageHandler;
diff --git a/ios/chrome/browser/ui/webui/password_manager_internals_ui_ios.mm b/ios/chrome/browser/ui/webui/password_manager_internals_ui_ios.mm index b78f9800..3d2eebc 100644 --- a/ios/chrome/browser/ui/webui/password_manager_internals_ui_ios.mm +++ b/ios/chrome/browser/ui/webui/password_manager_internals_ui_ios.mm
@@ -11,8 +11,8 @@ #include "ios/chrome/browser/chrome_url_constants.h" #include "ios/chrome/browser/passwords/password_manager_internals_service_factory.h" #import "ios/web/public/web_state/web_state.h" -#include "ios/web/public/web_ui_ios_data_source.h" #include "ios/web/public/webui/web_ui_ios.h" +#include "ios/web/public/webui/web_ui_ios_data_source.h" #include "net/base/escape.h" using password_manager::PasswordManagerInternalsService;
diff --git a/ios/chrome/browser/ui/webui/signin_internals_ui_ios.cc b/ios/chrome/browser/ui/webui/signin_internals_ui_ios.cc index c89a1f2..a555b347 100644 --- a/ios/chrome/browser/ui/webui/signin_internals_ui_ios.cc +++ b/ios/chrome/browser/ui/webui/signin_internals_ui_ios.cc
@@ -11,8 +11,8 @@ #include "ios/chrome/browser/chrome_url_constants.h" #include "ios/chrome/browser/signin/about_signin_internals_factory.h" #include "ios/chrome/browser/signin/identity_manager_factory.h" -#include "ios/web/public/web_ui_ios_data_source.h" #include "ios/web/public/webui/web_ui_ios.h" +#include "ios/web/public/webui/web_ui_ios_data_source.h" #include "services/identity/public/cpp/accounts_in_cookie_jar_info.h" #include "services/identity/public/cpp/identity_manager.h"
diff --git a/ios/chrome/browser/ui/webui/suggestions_ui.cc b/ios/chrome/browser/ui/webui/suggestions_ui.cc index 8e3c0d70..16beb1bb 100644 --- a/ios/chrome/browser/ui/webui/suggestions_ui.cc +++ b/ios/chrome/browser/ui/webui/suggestions_ui.cc
@@ -11,7 +11,7 @@ #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/chrome_url_constants.h" #include "ios/chrome/browser/suggestions/suggestions_service_factory.h" -#include "ios/web/public/url_data_source_ios.h" +#include "ios/web/public/webui/url_data_source_ios.h" namespace suggestions {
diff --git a/ios/chrome/browser/ui/webui/sync_internals/BUILD.gn b/ios/chrome/browser/ui/webui/sync_internals/BUILD.gn index bbfb58e..e9028ad 100644 --- a/ios/chrome/browser/ui/webui/sync_internals/BUILD.gn +++ b/ios/chrome/browser/ui/webui/sync_internals/BUILD.gn
@@ -20,6 +20,6 @@ "//ios/chrome/browser/signin", "//ios/chrome/browser/sync", "//ios/chrome/common", - "//ios/web", + "//ios/web/public/webui", ] }
diff --git a/ios/chrome/browser/ui/webui/sync_internals/sync_internals_ui.cc b/ios/chrome/browser/ui/webui/sync_internals/sync_internals_ui.cc index 4d7a35f..e8fb990 100644 --- a/ios/chrome/browser/ui/webui/sync_internals/sync_internals_ui.cc +++ b/ios/chrome/browser/ui/webui/sync_internals/sync_internals_ui.cc
@@ -11,8 +11,8 @@ #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/chrome_url_constants.h" #include "ios/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.h" -#include "ios/web/public/web_ui_ios_data_source.h" #include "ios/web/public/webui/web_ui_ios.h" +#include "ios/web/public/webui/web_ui_ios_data_source.h" namespace {
diff --git a/ios/chrome/browser/ui/webui/terms_ui.mm b/ios/chrome/browser/ui/webui/terms_ui.mm index b19c0aa..8ff629b 100644 --- a/ios/chrome/browser/ui/webui/terms_ui.mm +++ b/ios/chrome/browser/ui/webui/terms_ui.mm
@@ -11,7 +11,7 @@ #import "base/strings/sys_string_conversions.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/ui/util/terms_util.h" -#include "ios/web/public/url_data_source_ios.h" +#include "ios/web/public/webui/url_data_source_ios.h" #include "ios/web/public/webui/web_ui_ios.h" #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/chrome/browser/ui/webui/translate_internals/BUILD.gn b/ios/chrome/browser/ui/webui/translate_internals/BUILD.gn index 0771ed4..dd5c8df 100644 --- a/ios/chrome/browser/ui/webui/translate_internals/BUILD.gn +++ b/ios/chrome/browser/ui/webui/translate_internals/BUILD.gn
@@ -20,6 +20,6 @@ "//ios/chrome/browser/tabs", "//ios/chrome/browser/translate", "//ios/chrome/browser/web_state_list", - "//ios/web/public", + "//ios/web/public/webui", ] }
diff --git a/ios/chrome/browser/ui/webui/translate_internals/translate_internals_ui.mm b/ios/chrome/browser/ui/webui/translate_internals/translate_internals_ui.mm index 79abaa91..8a69c93 100644 --- a/ios/chrome/browser/ui/webui/translate_internals/translate_internals_ui.mm +++ b/ios/chrome/browser/ui/webui/translate_internals/translate_internals_ui.mm
@@ -11,8 +11,8 @@ #include "ios/chrome/browser/chrome_url_constants.h" #import "ios/chrome/browser/ui/webui/translate_internals/ios_translate_internals_handler.h" #include "ios/chrome/grit/ios_resources.h" -#include "ios/web/public/web_ui_ios_data_source.h" #include "ios/web/public/webui/web_ui_ios.h" +#include "ios/web/public/webui/web_ui_ios_data_source.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support."
diff --git a/ios/chrome/browser/ui/webui/ukm_internals_ui.cc b/ios/chrome/browser/ui/webui/ukm_internals_ui.cc index 44194f5..7bbbc41 100644 --- a/ios/chrome/browser/ui/webui/ukm_internals_ui.cc +++ b/ios/chrome/browser/ui/webui/ukm_internals_ui.cc
@@ -15,9 +15,9 @@ #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/chrome_url_constants.h" #include "ios/chrome/grit/ios_resources.h" -#include "ios/web/public/url_data_source_ios.h" -#include "ios/web/public/web_ui_ios_data_source.h" +#include "ios/web/public/webui/url_data_source_ios.h" #include "ios/web/public/webui/web_ui_ios.h" +#include "ios/web/public/webui/web_ui_ios_data_source.h" #include "ios/web/public/webui/web_ui_ios_message_handler.h" namespace {
diff --git a/ios/chrome/browser/ui/webui/user_actions_ui.mm b/ios/chrome/browser/ui/webui/user_actions_ui.mm index b4ae9d9..c19ca45 100644 --- a/ios/chrome/browser/ui/webui/user_actions_ui.mm +++ b/ios/chrome/browser/ui/webui/user_actions_ui.mm
@@ -8,8 +8,8 @@ #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/chrome_url_constants.h" #include "ios/chrome/browser/ui/webui/user_actions_handler.h" -#include "ios/web/public/web_ui_ios_data_source.h" #include "ios/web/public/webui/web_ui_ios.h" +#include "ios/web/public/webui/web_ui_ios_data_source.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support."
diff --git a/ios/chrome/browser/ui/webui/version_ui.mm b/ios/chrome/browser/ui/webui/version_ui.mm index ba7cc26..6fa79132 100644 --- a/ios/chrome/browser/ui/webui/version_ui.mm +++ b/ios/chrome/browser/ui/webui/version_ui.mm
@@ -23,8 +23,8 @@ #include "ios/chrome/common/channel_info.h" #include "ios/chrome/grit/ios_chromium_strings.h" #include "ios/web/public/web_client.h" -#include "ios/web/public/web_ui_ios_data_source.h" #include "ios/web/public/webui/web_ui_ios.h" +#include "ios/web/public/webui/web_ui_ios_data_source.h" #include "ui/base/l10n/l10n_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn index cae9b29..a18d25ab 100644 --- a/ios/web/BUILD.gn +++ b/ios/web/BUILD.gn
@@ -21,10 +21,13 @@ ":service_names", # TODO(crbug.com/616244): Remove private files from public dependencies. + ":services", + ":threads", "//ios/web/navigation:core", "//ios/web/net", "//ios/web/public", "//ios/web/public/download", + "//ios/web/public/init", "//ios/web/web_state:web_state_impl_header", "//ios/web/web_state/ui", "//ios/web/web_state/ui:wk_web_view_configuration_provider", @@ -37,10 +40,12 @@ ":js_resources", ":navigation_resources", ":resources", - ":service_names", + ":services", + ":threads", "//base", "//ios/web/common", "//ios/web/download", + "//ios/web/init", "//ios/web/navigation", "//ios/web/net", "//ios/web/public", @@ -63,18 +68,8 @@ "browser_url_rewriter_impl.mm", "crw_navigation_item_storage.mm", "network_context_owner.cc", - "service_manager_connection_impl.cc", - "service_manager_connection_impl.h", - "service_manager_context.h", - "service_manager_context.mm", "url_scheme_util.mm", - "web_browser_manifest.h", - "web_browser_manifest.mm", "web_client.mm", - "web_sub_thread.cc", - "web_sub_thread.h", - "web_thread_impl.cc", - "web_thread_impl.h", "web_view_creation_util.mm", ] @@ -83,6 +78,44 @@ configs += [ "//build/config/compiler:enable_arc" ] } +source_set("threads") { + deps = [ + "//base", + "//ios/web/public", + ] + + sources = [ + "web_sub_thread.cc", + "web_sub_thread.h", + "web_thread_impl.cc", + "web_thread_impl.h", + ] + + configs += [ "//build/config/compiler:enable_arc" ] +} + +source_set("services") { + deps = [ + ":service_names", + "//ios/web/public", + "//services/network:network_service", + "//services/network/public/mojom", + "//services/service_manager", + "//services/service_manager/public/cpp", + "//services/service_manager/public/mojom", + ] + sources = [ + "service_manager_connection_impl.cc", + "service_manager_connection_impl.h", + "service_manager_context.h", + "service_manager_context.mm", + "web_browser_manifest.h", + "web_browser_manifest.mm", + ] + + configs += [ "//build/config/compiler:enable_arc" ] +} + mojom("service_names") { sources = [ "public/service_names.mojom", @@ -221,6 +254,7 @@ testonly = true deps = [ ":core", + ":threads", ":web", "//base", "//base/test:test_support", @@ -558,9 +592,9 @@ "//components/url_formatter", "//ios/net", "//ios/testing:ocmock_support", - "//ios/web/public", "//ios/web/public/test", "//ios/web/public/test/fakes", + "//ios/web/public/webui", "//ios/web/test:mojo_bindings", "//ios/web/test:test_constants", "//ios/web/test:test_support", @@ -603,6 +637,7 @@ "//ios/web/public/test", "//ios/web/public/test:element_selector", "//ios/web/public/test/http_server", + "//ios/web/public/webui", "//ios/web/test:mojo_bindings", "//ios/web/test:packed_resources", "//ios/web/test:resources",
diff --git a/ios/web/app/BUILD.gn b/ios/web/app/BUILD.gn deleted file mode 100644 index 93e0dd9..0000000 --- a/ios/web/app/BUILD.gn +++ /dev/null
@@ -1,34 +0,0 @@ -# Copyright 2015 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -source_set("app") { - visibility = [ "//ios/web/public/app" ] - - sources = [ - "web_main.mm", - "web_main_loop.h", - "web_main_loop.mm", - "web_main_runner.mm", - ] - - configs += [ "//build/config/compiler:enable_arc" ] - - deps = [ - "//base", - "//base:i18n", - "//crypto", - "//ios/web", - "//ios/web/public/global_state", - "//mojo/core/embedder", - "//net", - "//ui/base", - "//ui/gfx", - "//ui/gfx/geometry", - ] - - libs = [ - "Foundation.framework", - "UIKit.framework", - ] -}
diff --git a/ios/web/browser_state.mm b/ios/web/browser_state.mm index f388810..4479371 100644 --- a/ios/web/browser_state.mm +++ b/ios/web/browser_state.mm
@@ -15,7 +15,7 @@ #include "base/process/process_handle.h" #include "base/task/post_task.h" #include "base/token.h" -#include "ios/web/public/network_context_owner.h" +#include "ios/web/public/init/network_context_owner.h" #include "ios/web/public/security/certificate_policy_cache.h" #include "ios/web/public/service_manager_connection.h" #include "ios/web/public/service_names.mojom.h"
diff --git a/ios/web/init/BUILD.gn b/ios/web/init/BUILD.gn new file mode 100644 index 0000000..ec5bee26 --- /dev/null +++ b/ios/web/init/BUILD.gn
@@ -0,0 +1,51 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("init") { + sources = [ + "web_main.mm", + "web_main_loop.h", + "web_main_loop.mm", + "web_main_runner.mm", + ] + + configs += [ "//build/config/compiler:enable_arc" ] + + deps = [ + ":global_state", + "//base", + "//base:i18n", + "//crypto", + "//ios/web:services", + "//ios/web:threads", + "//ios/web/net", + "//ios/web/public", + "//ios/web/public/init", + "//ios/web/webui", + "//mojo/core/embedder", + "//net", + "//ui/base", + "//ui/gfx", + "//ui/gfx/geometry", + ] + + libs = [ + "Foundation.framework", + "UIKit.framework", + ] +} + +source_set("global_state") { + sources = [ + "ios_global_state.mm", + ] + + configs += [ "//build/config/compiler:enable_arc" ] + + deps = [ + "//base", + "//ios/web/public/init:global_state", + "//net", + ] +}
diff --git a/ios/web/init/README.md b/ios/web/init/README.md new file mode 100644 index 0000000..1faa9f10 --- /dev/null +++ b/ios/web/init/README.md
@@ -0,0 +1,2 @@ +This directory contains the implementation of the classes responsible for +//ios//web layer initialization.
diff --git a/ios/web/public/global_state/ios_global_state.mm b/ios/web/init/ios_global_state.mm similarity index 97% rename from ios/web/public/global_state/ios_global_state.mm rename to ios/web/init/ios_global_state.mm index 4ef1de6..fb1cc74 100644 --- a/ios/web/public/global_state/ios_global_state.mm +++ b/ios/web/init/ios_global_state.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ios/web/public/global_state/ios_global_state.h" +#include "ios/web/public/init/ios_global_state.h" #include "base/at_exit.h" #include "base/command_line.h"
diff --git a/ios/web/app/web_main.mm b/ios/web/init/web_main.mm similarity index 81% rename from ios/web/app/web_main.mm rename to ios/web/init/web_main.mm index 202b267..8f2a54d 100644 --- a/ios/web/app/web_main.mm +++ b/ios/web/init/web_main.mm
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ios/web/public/app/web_main.h" -#include "ios/web/public/app/web_main_runner.h" +#include "ios/web/public/init/web_main.h" +#include "ios/web/public/init/web_main_runner.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -14,10 +14,7 @@ WebMainParams::WebMainParams() : WebMainParams(nullptr) {} WebMainParams::WebMainParams(WebMainDelegate* delegate) - : delegate(delegate), - register_exit_manager(true), - argc(0), - argv(nullptr) {} + : delegate(delegate), register_exit_manager(true), argc(0), argv(nullptr) {} WebMainParams::~WebMainParams() = default;
diff --git a/ios/web/app/web_main_loop.h b/ios/web/init/web_main_loop.h similarity index 95% rename from ios/web/app/web_main_loop.h rename to ios/web/init/web_main_loop.h index 0a8efa1d..6e46617 100644 --- a/ios/web/app/web_main_loop.h +++ b/ios/web/init/web_main_loop.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_WEB_APP_WEB_MAIN_LOOP_H_ -#define IOS_WEB_APP_WEB_MAIN_LOOP_H_ +#ifndef IOS_WEB_INIT_WEB_MAIN_LOOP_H_ +#define IOS_WEB_INIT_WEB_MAIN_LOOP_H_ #include <memory> @@ -90,4 +90,4 @@ } // namespace web -#endif // IOS_WEB_APP_WEB_MAIN_LOOP_H_ +#endif // IOS_WEB_INIT_WEB_MAIN_LOOP_H_
diff --git a/ios/web/app/web_main_loop.mm b/ios/web/init/web_main_loop.mm similarity index 96% rename from ios/web/app/web_main_loop.mm rename to ios/web/init/web_main_loop.mm index 7853dae..047adb3 100644 --- a/ios/web/app/web_main_loop.mm +++ b/ios/web/init/web_main_loop.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ios/web/app/web_main_loop.h" +#include "ios/web/init/web_main_loop.h" #include <stddef.h> @@ -21,8 +21,8 @@ #include "base/task/thread_pool/thread_pool.h" #include "base/threading/thread_restrictions.h" #import "ios/web/net/cookie_notification_bridge.h" -#include "ios/web/public/app/web_main_parts.h" -#include "ios/web/public/global_state/ios_global_state.h" +#include "ios/web/public/init/ios_global_state.h" +#include "ios/web/public/init/web_main_parts.h" #import "ios/web/public/web_client.h" #include "ios/web/public/web_task_traits.h" #include "ios/web/service_manager_context.h" @@ -37,7 +37,7 @@ namespace web { // The currently-running WebMainLoop. There can be one or zero. -// TODO(rohitrao): Desktop uses this to implement +// TODO(crbug.com/965889): Desktop uses this to implement // ImmediateShutdownAndExitProcess. If we don't need that functionality, we can // remove this. WebMainLoop* g_current_web_main_loop = nullptr;
diff --git a/ios/web/app/web_main_runner.mm b/ios/web/init/web_main_runner.mm similarity index 93% rename from ios/web/app/web_main_runner.mm rename to ios/web/init/web_main_runner.mm index 9810315..b8eed971 100644 --- a/ios/web/app/web_main_runner.mm +++ b/ios/web/init/web_main_runner.mm
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ios/web/public/app/web_main_runner.h" +#include "ios/web/public/init/web_main_runner.h" #include "base/i18n/icu_util.h" #include "base/logging.h" #include "base/macros.h" -#include "ios/web/app/web_main_loop.h" -#include "ios/web/public/global_state/ios_global_state.h" +#include "ios/web/init/web_main_loop.h" +#include "ios/web/public/init/ios_global_state.h" #include "ios/web/public/url_schemes.h" #import "ios/web/public/web_client.h" #include "ios/web/web_thread_impl.h" @@ -56,7 +56,7 @@ mojo::core::Init(); - // TODO(rohitrao): Should we instead require that all embedders call + // TODO(crbug.com/965894): Should we instead require that all embedders call // SetWebClient()? if (!GetWebClient()) SetWebClient(&empty_web_client_);
diff --git a/ios/web/network_context_owner.cc b/ios/web/network_context_owner.cc index 6066487..a89c9e0f 100644 --- a/ios/web/network_context_owner.cc +++ b/ios/web/network_context_owner.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ios/web/public/network_context_owner.h" +#include "ios/web/public/init/network_context_owner.h" #include <memory> #include <string>
diff --git a/ios/web/network_context_owner_unittest.cc b/ios/web/network_context_owner_unittest.cc index 77525be..40e6804 100644 --- a/ios/web/network_context_owner_unittest.cc +++ b/ios/web/network_context_owner_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ios/web/public/network_context_owner.h" +#include "ios/web/public/init/network_context_owner.h" #include <string> #include <vector>
diff --git a/ios/web/public/BUILD.gn b/ios/web/public/BUILD.gn index 0816512c..e6586a6 100644 --- a/ios/web/public/BUILD.gn +++ b/ios/web/public/BUILD.gn
@@ -34,10 +34,7 @@ "navigation_item.h", "navigation_manager.h", "reload_type.h", - "security/cert_policy.h", - "security/certificate_policy_cache.h", "service_manager_connection.h", - "url_data_source_ios.h", "url_scheme_util.h", "url_schemes.h", "url_schemes.mm", @@ -60,14 +57,7 @@ "web_task_traits.h", "web_thread.h", "web_thread_delegate.h", - "web_ui_ios_data_source.h", "web_view_creation_util.h", - "webui/web_ui_ios.h", - "webui/web_ui_ios_controller.cc", - "webui/web_ui_ios_controller.h", - "webui/web_ui_ios_controller_factory.h", - "webui/web_ui_ios_message_handler.cc", - "webui/web_ui_ios_message_handler.h", ] libs = [ "WebKit.framework" ]
diff --git a/ios/web/public/app/BUILD.gn b/ios/web/public/app/BUILD.gn deleted file mode 100644 index 136588c..0000000 --- a/ios/web/public/app/BUILD.gn +++ /dev/null
@@ -1,30 +0,0 @@ -# Copyright 2015 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -source_set("app") { - sources = [ - "web_main.h", - "web_main_delegate.h", - "web_main_parts.h", - "web_main_runner.h", - ] - - deps = [ - "//base", - "//ios/web/app", - - # TODO(crbug.com/728161): remove this dependency as it is not needed but - # is there just to allow adding the target to allow_circular_includes_from - # in order to fix a circular include issue. - "//ios/web:web", - ] - allow_circular_includes_from = [ - "//ios/web/app", - - # TODO(crbug.com/728161): remove this exception. - "//ios/web:web", - ] - - configs += [ "//build/config/compiler:enable_arc" ] -}
diff --git a/ios/web/public/global_state/BUILD.gn b/ios/web/public/global_state/BUILD.gn deleted file mode 100644 index 070a762a..0000000 --- a/ios/web/public/global_state/BUILD.gn +++ /dev/null
@@ -1,18 +0,0 @@ -# Copyright 2017 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -source_set("global_state") { - configs += [ "//build/config/compiler:enable_arc" ] - - deps = [ - "//base", - "//net", - ] - - sources = [ - "ios_global_state.h", - "ios_global_state.mm", - "ios_global_state_configuration.h", - ] -}
diff --git a/ios/web/public/init/BUILD.gn b/ios/web/public/init/BUILD.gn new file mode 100644 index 0000000..5c2f0a5 --- /dev/null +++ b/ios/web/public/init/BUILD.gn
@@ -0,0 +1,40 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("init") { + configs += [ "//build/config/compiler:enable_arc" ] + + sources = [ + "network_context_owner.h", + "web_main.h", + "web_main_delegate.h", + "web_main_parts.h", + "web_main_runner.h", + ] + + public_deps = [ + ":global_state", + ] + + deps = [ + ":global_state", + "//base", + "//ios/web/public", + "//net", + "//services/network:network_service", + ] +} + +source_set("global_state") { + configs += [ "//build/config/compiler:enable_arc" ] + + sources = [ + "ios_global_state.h", + "ios_global_state_configuration.h", + ] + + deps = [ + "//base", + ] +}
diff --git a/ios/web/public/init/README.md b/ios/web/public/init/README.md new file mode 100644 index 0000000..59227548 --- /dev/null +++ b/ios/web/public/init/README.md
@@ -0,0 +1 @@ +This directory contains API responsible for //ios//web layer initialization.
diff --git a/ios/web/public/global_state/ios_global_state.h b/ios/web/public/init/ios_global_state.h similarity index 93% rename from ios/web/public/global_state/ios_global_state.h rename to ios/web/public/init/ios_global_state.h index 1dd07c2..a85b847 100644 --- a/ios/web/public/global_state/ios_global_state.h +++ b/ios/web/public/init/ios_global_state.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_WEB_PUBLIC_GLOBAL_STATE_IOS_GLOBAL_STATE_H_ -#define IOS_WEB_PUBLIC_GLOBAL_STATE_IOS_GLOBAL_STATE_H_ +#ifndef IOS_WEB_PUBLIC_INIT_IOS_GLOBAL_STATE_H_ +#define IOS_WEB_PUBLIC_INIT_IOS_GLOBAL_STATE_H_ #include "base/task/thread_pool/thread_pool.h" @@ -70,4 +70,4 @@ } // namespace ios_global_state -#endif // IOS_WEB_PUBLIC_GLOBAL_STATE_IOS_GLOBAL_STATE_H_ +#endif // IOS_WEB_PUBLIC_INIT_IOS_GLOBAL_STATE_H_
diff --git a/ios/web/public/global_state/ios_global_state_configuration.h b/ios/web/public/init/ios_global_state_configuration.h similarity index 66% rename from ios/web/public/global_state/ios_global_state_configuration.h rename to ios/web/public/init/ios_global_state_configuration.h index 418f33bb..8ec42050 100644 --- a/ios/web/public/global_state/ios_global_state_configuration.h +++ b/ios/web/public/init/ios_global_state_configuration.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_WEB_PUBLIC_GLOBAL_STATE_IOS_GLOBAL_STATE_CONFIGURATION_H_ -#define IOS_WEB_PUBLIC_GLOBAL_STATE_IOS_GLOBAL_STATE_CONFIGURATION_H_ +#ifndef IOS_WEB_PUBLIC_INIT_IOS_GLOBAL_STATE_CONFIGURATION_H_ +#define IOS_WEB_PUBLIC_INIT_IOS_GLOBAL_STATE_CONFIGURATION_H_ #include "base/single_thread_task_runner.h" @@ -15,4 +15,4 @@ } // namespace ios_global_state -#endif // IOS_WEB_PUBLIC_GLOBAL_STATE_IOS_GLOBAL_STATE_CONFIGURATION_H_ +#endif // IOS_WEB_PUBLIC_INIT_IOS_GLOBAL_STATE_CONFIGURATION_H_
diff --git a/ios/web/public/network_context_owner.h b/ios/web/public/init/network_context_owner.h similarity index 92% rename from ios/web/public/network_context_owner.h rename to ios/web/public/init/network_context_owner.h index 50835dc..5e74fa9 100644 --- a/ios/web/public/network_context_owner.h +++ b/ios/web/public/init/network_context_owner.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_WEB_PUBLIC_NETWORK_CONTEXT_OWNER_H_ -#define IOS_WEB_PUBLIC_NETWORK_CONTEXT_OWNER_H_ +#ifndef IOS_WEB_PUBLIC_INIT_NETWORK_CONTEXT_OWNER_H_ +#define IOS_WEB_PUBLIC_INIT_NETWORK_CONTEXT_OWNER_H_ #include <memory> #include <string> @@ -53,4 +53,4 @@ } // namespace web -#endif // IOS_WEB_PUBLIC_NETWORK_CONTEXT_OWNER_H_ +#endif // IOS_WEB_PUBLIC_INIT_NETWORK_CONTEXT_OWNER_H_
diff --git a/ios/web/public/app/web_main.h b/ios/web/public/init/web_main.h similarity index 87% rename from ios/web/public/app/web_main.h rename to ios/web/public/init/web_main.h index 1df146b..07bc8ac 100644 --- a/ios/web/public/app/web_main.h +++ b/ios/web/public/init/web_main.h
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_WEB_PUBLIC_APP_WEB_MAIN_H_ -#define IOS_WEB_PUBLIC_APP_WEB_MAIN_H_ +#ifndef IOS_WEB_PUBLIC_INIT_WEB_MAIN_H_ +#define IOS_WEB_PUBLIC_INIT_WEB_MAIN_H_ #include <memory> #include "base/macros.h" -#include "ios/web/public/app/web_main_delegate.h" +#include "ios/web/public/init/web_main_delegate.h" namespace web { class WebMainRunner; @@ -51,4 +51,4 @@ } // namespace web -#endif // IOS_WEB_PUBLIC_APP_WEB_MAIN_H_ +#endif // IOS_WEB_PUBLIC_INIT_WEB_MAIN_H_
diff --git a/ios/web/public/app/web_main_delegate.h b/ios/web/public/init/web_main_delegate.h similarity index 78% rename from ios/web/public/app/web_main_delegate.h rename to ios/web/public/init/web_main_delegate.h index f462384c..c3b0454e 100644 --- a/ios/web/public/app/web_main_delegate.h +++ b/ios/web/public/init/web_main_delegate.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_WEB_PUBLIC_APP_WEB_MAIN_DELEGATE_H_ -#define IOS_WEB_PUBLIC_APP_WEB_MAIN_DELEGATE_H_ +#ifndef IOS_WEB_PUBLIC_INIT_WEB_MAIN_DELEGATE_H_ +#define IOS_WEB_PUBLIC_INIT_WEB_MAIN_DELEGATE_H_ namespace web { @@ -21,10 +21,11 @@ virtual void BasicStartupComplete() {} // Called right before the process exits. - // TODO(rohitrao): This may not be used for anything. Remove if useless. + // TODO(crbug.com/965895): This may not be used for anything. Remove if + // useless. virtual void ProcessExiting() {} }; } // namespace web -#endif // IOS_WEB_PUBLIC_APP_WEB_MAIN_DELEGATE_H_ +#endif // IOS_WEB_PUBLIC_INIT_WEB_MAIN_DELEGATE_H_
diff --git a/ios/web/public/app/web_main_parts.h b/ios/web/public/init/web_main_parts.h similarity index 95% rename from ios/web/public/app/web_main_parts.h rename to ios/web/public/init/web_main_parts.h index b85dca5..8f6c0df 100644 --- a/ios/web/public/app/web_main_parts.h +++ b/ios/web/public/init/web_main_parts.h
@@ -2,9 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_WEB_PUBLIC_APP_WEB_MAIN_PARTS_H_ -#define IOS_WEB_PUBLIC_APP_WEB_MAIN_PARTS_H_ - +#ifndef IOS_WEB_PUBLIC_INIT_WEB_MAIN_PARTS_H_ +#define IOS_WEB_PUBLIC_INIT_WEB_MAIN_PARTS_H_ namespace web { @@ -73,4 +72,4 @@ } // namespace web -#endif // IOS_WEB_PUBLIC_APP_WEB_MAIN_PARTS_H_ +#endif // IOS_WEB_PUBLIC_INIT_WEB_MAIN_PARTS_H_
diff --git a/ios/web/public/app/web_main_runner.h b/ios/web/public/init/web_main_runner.h similarity index 75% rename from ios/web/public/app/web_main_runner.h rename to ios/web/public/init/web_main_runner.h index 9cb5a9a..190f7cf 100644 --- a/ios/web/public/app/web_main_runner.h +++ b/ios/web/public/init/web_main_runner.h
@@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_WEB_PUBLIC_APP_WEB_MAIN_RUNNER_H_ -#define IOS_WEB_PUBLIC_APP_WEB_MAIN_RUNNER_H_ +#ifndef IOS_WEB_PUBLIC_INIT_WEB_MAIN_RUNNER_H_ +#define IOS_WEB_PUBLIC_INIT_WEB_MAIN_RUNNER_H_ -#include "ios/web/public/app/web_main.h" +#include "ios/web/public/init/web_main.h" namespace web { @@ -26,4 +26,4 @@ } // namespace web -#endif // IOS_WEB_PUBLIC_APP_WEB_MAIN_RUNNER_H_ +#endif // IOS_WEB_PUBLIC_INIT_WEB_MAIN_RUNNER_H_
diff --git a/ios/web/public/webui/BUILD.gn b/ios/web/public/webui/BUILD.gn new file mode 100644 index 0000000..4f59e437 --- /dev/null +++ b/ios/web/public/webui/BUILD.gn
@@ -0,0 +1,25 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//ios/build/config.gni") + +source_set("webui") { + deps = [ + "//base", + "//net", + ] + + sources = [ + "url_data_source_ios.h", + "web_ui_ios.h", + "web_ui_ios_controller.h", + "web_ui_ios_controller_factory.h", + "web_ui_ios_data_source.h", + "web_ui_ios_message_handler.h", + ] + + libs = [ "WebKit.framework" ] + + configs += [ "//build/config/compiler:enable_arc" ] +}
diff --git a/ios/web/public/webui/README.md b/ios/web/public/webui/README.md new file mode 100644 index 0000000..e89cee7 --- /dev/null +++ b/ios/web/public/webui/README.md
@@ -0,0 +1 @@ +This directory contains API to work with browser specific URLs (e.g. chromium://version), which can load browser UI implemented as locally-stored web pages.
diff --git a/ios/web/public/url_data_source_ios.h b/ios/web/public/webui/url_data_source_ios.h similarity index 95% rename from ios/web/public/url_data_source_ios.h rename to ios/web/public/webui/url_data_source_ios.h index 90a8684b..2c0ccde 100644 --- a/ios/web/public/url_data_source_ios.h +++ b/ios/web/public/webui/url_data_source_ios.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_WEB_PUBLIC_URL_DATA_SOURCE_IOS_H_ -#define IOS_WEB_PUBLIC_URL_DATA_SOURCE_IOS_H_ +#ifndef IOS_WEB_PUBLIC_WEBUI_URL_DATA_SOURCE_IOS_H_ +#define IOS_WEB_PUBLIC_WEBUI_URL_DATA_SOURCE_IOS_H_ #include <string> @@ -90,4 +90,4 @@ } // namespace web -#endif // IOS_WEB_PUBLIC_URL_DATA_SOURCE_IOS_H_ +#endif // IOS_WEB_PUBLIC_WEBUI_URL_DATA_SOURCE_IOS_H_
diff --git a/ios/web/public/web_ui_ios_data_source.h b/ios/web/public/webui/web_ui_ios_data_source.h similarity index 91% rename from ios/web/public/web_ui_ios_data_source.h rename to ios/web/public/webui/web_ui_ios_data_source.h index edfcd8ab5..8902760 100644 --- a/ios/web/public/web_ui_ios_data_source.h +++ b/ios/web/public/webui/web_ui_ios_data_source.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_WEB_PUBLIC_WEB_UI_IOS_DATA_SOURCE_H_ -#define IOS_WEB_PUBLIC_WEB_UI_IOS_DATA_SOURCE_H_ +#ifndef IOS_WEB_PUBLIC_WEBUI_WEB_UI_IOS_DATA_SOURCE_H_ +#define IOS_WEB_PUBLIC_WEBUI_WEB_UI_IOS_DATA_SOURCE_H_ #include "base/callback.h" #include "base/strings/string16.h" @@ -59,4 +59,4 @@ } // namespace web -#endif // IOS_WEB_PUBLIC_WEB_UI_IOS_DATA_SOURCE_H_ +#endif // IOS_WEB_PUBLIC_WEBUI_WEB_UI_IOS_DATA_SOURCE_H_
diff --git a/ios/web/session/BUILD.gn b/ios/web/session/BUILD.gn index fed1aa8..3cdd37c 100644 --- a/ios/web/session/BUILD.gn +++ b/ios/web/session/BUILD.gn
@@ -7,6 +7,7 @@ deps = [ "//base", "//ios/web/public", + "//ios/web/public/security", "//ios/web/public/session", "//net", ] @@ -25,6 +26,7 @@ testonly = true deps = [ "//ios/web/public", + "//ios/web/public/security", "//ios/web/public/session", "//ios/web/public/test", "//ios/web/public/test/fakes",
diff --git a/ios/web/shell/BUILD.gn b/ios/web/shell/BUILD.gn index 2f6c757..ec7fd87a 100644 --- a/ios/web/shell/BUILD.gn +++ b/ios/web/shell/BUILD.gn
@@ -67,7 +67,7 @@ "//ios/net", "//ios/web", "//ios/web/public", - "//ios/web/public/app", + "//ios/web/public/init", "//net", "//net:extras", "//services/service_manager/public/cpp",
diff --git a/ios/web/shell/app_delegate.mm b/ios/web/shell/app_delegate.mm index adc543f5..baebe3d 100644 --- a/ios/web/shell/app_delegate.mm +++ b/ios/web/shell/app_delegate.mm
@@ -6,7 +6,7 @@ #include <memory> -#include "ios/web/public/app/web_main.h" +#include "ios/web/public/init/web_main.h" #import "ios/web/public/web_client.h" #import "ios/web/public/web_state/web_state.h" #include "ios/web/shell/shell_browser_state.h"
diff --git a/ios/web/shell/shell_main_delegate.h b/ios/web/shell/shell_main_delegate.h index afd2ccb..6228cf61e 100644 --- a/ios/web/shell/shell_main_delegate.h +++ b/ios/web/shell/shell_main_delegate.h
@@ -8,7 +8,7 @@ #include <memory> #include "base/compiler_specific.h" -#include "ios/web/public/app/web_main_delegate.h" +#include "ios/web/public/init/web_main_delegate.h" namespace web { class ShellWebClient;
diff --git a/ios/web/shell/shell_web_main_parts.h b/ios/web/shell/shell_web_main_parts.h index 963cf263..9f5adce 100644 --- a/ios/web/shell/shell_web_main_parts.h +++ b/ios/web/shell/shell_web_main_parts.h
@@ -7,8 +7,7 @@ #include <memory> -#include "ios/web/public/app/web_main_parts.h" - +#include "ios/web/public/init/web_main_parts.h" namespace web { class ShellBrowserState;
diff --git a/ios/web/web_client.mm b/ios/web/web_client.mm index 6e5001a..7f03982 100644 --- a/ios/web/web_client.mm +++ b/ios/web/web_client.mm
@@ -7,7 +7,7 @@ #import <Foundation/Foundation.h> #include "ios/web/common/features.h" -#include "ios/web/public/app/web_main_parts.h" +#include "ios/web/public/init/web_main_parts.h" #include "services/service_manager/public/cpp/service.h" #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/web/web_state/BUILD.gn b/ios/web/web_state/BUILD.gn index e08e345..f447090 100644 --- a/ios/web/web_state/BUILD.gn +++ b/ios/web/web_state/BUILD.gn
@@ -16,12 +16,14 @@ "//ios/web/public", "//ios/web/public/deprecated", "//ios/web/public/session", + "//ios/web/public/webui", "//ios/web/security", "//ios/web/security", "//ios/web/session", "//ios/web/web_state/ui", "//ios/web/web_state/ui:crw_web_view_navigation_proxy", "//ios/web/webui", + "//net", "//ui/gfx", ]
diff --git a/ios/web/web_state/ui/BUILD.gn b/ios/web/web_state/ui/BUILD.gn index 2c2da60..bb46f6b5 100644 --- a/ios/web/web_state/ui/BUILD.gn +++ b/ios/web/web_state/ui/BUILD.gn
@@ -28,6 +28,7 @@ "//ios/web/public/download", "//ios/web/public/js_messaging", "//ios/web/public/security", + "//ios/web/public/webui", "//ios/web/security", "//ios/web/session", "//ios/web/web_state:context_menu", @@ -40,6 +41,7 @@ "//ios/web/web_state/ui/controller", "//ios/web/web_view:util", "//ios/web/webui:webui", + "//net", "//services/metrics/public/cpp:ukm_builders", "//ui/base", "//url",
diff --git a/ios/web/webui/BUILD.gn b/ios/web/webui/BUILD.gn index f44247a..b86c57f9 100644 --- a/ios/web/webui/BUILD.gn +++ b/ios/web/webui/BUILD.gn
@@ -10,8 +10,10 @@ "//ios/web:resources", "//ios/web:resources_grit", "//ios/web/public", + "//ios/web/public/webui", "//ios/web/web_state:web_state_impl_header", "//mojo/public/cpp/system", + "//net", "//services/service_manager/public/mojom", "//ui/base", "//ui/resources", @@ -34,12 +36,14 @@ "url_data_source_ios_impl.h", "url_fetcher_block_adapter.h", "url_fetcher_block_adapter.mm", + "web_ui_ios_controller.cc", "web_ui_ios_controller_factory_registry.h", "web_ui_ios_controller_factory_registry.mm", "web_ui_ios_data_source_impl.h", "web_ui_ios_data_source_impl.mm", "web_ui_ios_impl.h", "web_ui_ios_impl.mm", + "web_ui_ios_message_handler.cc", ] configs += [ "//build/config/compiler:enable_arc" ]
diff --git a/ios/web/webui/shared_resources_data_source_ios.h b/ios/web/webui/shared_resources_data_source_ios.h index faed43c..4751719 100644 --- a/ios/web/webui/shared_resources_data_source_ios.h +++ b/ios/web/webui/shared_resources_data_source_ios.h
@@ -7,7 +7,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" -#include "ios/web/public/url_data_source_ios.h" +#include "ios/web/public/webui/url_data_source_ios.h" namespace web {
diff --git a/ios/web/webui/url_data_manager_ios.cc b/ios/web/webui/url_data_manager_ios.cc index d619537..483c9f5 100644 --- a/ios/web/webui/url_data_manager_ios.cc +++ b/ios/web/webui/url_data_manager_ios.cc
@@ -17,9 +17,9 @@ #include "base/synchronization/lock.h" #include "base/task/post_task.h" #include "ios/web/public/browser_state.h" -#include "ios/web/public/url_data_source_ios.h" #include "ios/web/public/web_task_traits.h" #include "ios/web/public/web_thread.h" +#include "ios/web/public/webui/url_data_source_ios.h" #include "ios/web/webui/url_data_manager_ios_backend.h" #include "ios/web/webui/url_data_source_ios_impl.h" #include "ios/web/webui/web_ui_ios_data_source_impl.h"
diff --git a/ios/web/webui/url_data_manager_ios_backend.h b/ios/web/webui/url_data_manager_ios_backend.h index 48878d6..ff719af 100644 --- a/ios/web/webui/url_data_manager_ios_backend.h +++ b/ios/web/webui/url_data_manager_ios_backend.h
@@ -13,7 +13,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "base/supports_user_data.h" -#include "ios/web/public/url_data_source_ios.h" +#include "ios/web/public/webui/url_data_source_ios.h" #include "ios/web/webui/url_data_manager_ios.h" #include "net/url_request/url_request_job_factory.h"
diff --git a/ios/web/webui/url_data_source_ios.mm b/ios/web/webui/url_data_source_ios.mm index 1b3993c..804951b 100644 --- a/ios/web/webui/url_data_source_ios.mm +++ b/ios/web/webui/url_data_source_ios.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ios/web/public/url_data_source_ios.h" +#include "ios/web/public/webui/url_data_source_ios.h" #import "ios/web/public/web_client.h" #include "ios/web/webui/url_data_manager_ios.h"
diff --git a/ios/web/webui/url_data_source_ios_impl.cc b/ios/web/webui/url_data_source_ios_impl.cc index 33907b9..6488ade 100644 --- a/ios/web/webui/url_data_source_ios_impl.cc +++ b/ios/web/webui/url_data_source_ios_impl.cc
@@ -9,9 +9,9 @@ #include "base/memory/ref_counted_memory.h" #include "base/strings/string_util.h" #include "base/task/post_task.h" -#include "ios/web/public/url_data_source_ios.h" #include "ios/web/public/web_task_traits.h" #include "ios/web/public/web_thread.h" +#include "ios/web/public/webui/url_data_source_ios.h" #include "ios/web/webui/url_data_manager_ios_backend.h" namespace web {
diff --git a/ios/web/public/webui/web_ui_ios_controller.cc b/ios/web/webui/web_ui_ios_controller.cc similarity index 100% rename from ios/web/public/webui/web_ui_ios_controller.cc rename to ios/web/webui/web_ui_ios_controller.cc
diff --git a/ios/web/webui/web_ui_ios_data_source_impl.h b/ios/web/webui/web_ui_ios_data_source_impl.h index cbb2b74..cf71f40 100644 --- a/ios/web/webui/web_ui_ios_data_source_impl.h +++ b/ios/web/webui/web_ui_ios_data_source_impl.h
@@ -12,8 +12,8 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "base/values.h" -#include "ios/web/public/url_data_source_ios.h" -#include "ios/web/public/web_ui_ios_data_source.h" +#include "ios/web/public/webui/url_data_source_ios.h" +#include "ios/web/public/webui/web_ui_ios_data_source.h" #include "ios/web/webui/url_data_manager_ios.h" #include "ios/web/webui/url_data_source_ios_impl.h" #include "ui/base/template_expressions.h"
diff --git a/ios/web/public/webui/web_ui_ios_message_handler.cc b/ios/web/webui/web_ui_ios_message_handler.cc similarity index 100% rename from ios/web/public/webui/web_ui_ios_message_handler.cc rename to ios/web/webui/web_ui_ios_message_handler.cc
diff --git a/ios/web/webui/web_ui_mojo_inttest.mm b/ios/web/webui/web_ui_mojo_inttest.mm index 90b1fe3..f2c9f15 100644 --- a/ios/web/webui/web_ui_mojo_inttest.mm +++ b/ios/web/webui/web_ui_mojo_inttest.mm
@@ -13,9 +13,9 @@ #import "ios/web/public/test/navigation_test_util.h" #import "ios/web/public/web_state/web_state.h" #include "ios/web/public/web_state/web_state_interface_provider.h" -#include "ios/web/public/web_ui_ios_data_source.h" #include "ios/web/public/webui/web_ui_ios_controller.h" #include "ios/web/public/webui/web_ui_ios_controller_factory.h" +#include "ios/web/public/webui/web_ui_ios_data_source.h" #include "ios/web/test/grit/test_resources.h" #include "ios/web/test/mojo_test.mojom.h" #include "ios/web/test/test_url_constants.h"
diff --git a/ios/web_view/BUILD.gn b/ios/web_view/BUILD.gn index edd7dcf4..8798a828 100644 --- a/ios/web_view/BUILD.gn +++ b/ios/web_view/BUILD.gn
@@ -308,11 +308,10 @@ "//ios/web", "//ios/web/common", "//ios/web/public", - "//ios/web/public/app", + "//ios/web/public/init", "//ios/web/public/deprecated", "//ios/web/public/security", "//ios/web/public/js_messaging", - "//ios/web/public/global_state", "//net", "//net:extras", "//services/identity/public/cpp",
diff --git a/ios/web_view/internal/app/application_context.h b/ios/web_view/internal/app/application_context.h index 8a773605..26e66c6 100644 --- a/ios/web_view/internal/app/application_context.h +++ b/ios/web_view/internal/app/application_context.h
@@ -11,7 +11,7 @@ #include "base/macros.h" #include "base/no_destructor.h" #include "base/sequence_checker.h" -#include "ios/web/public/network_context_owner.h" +#include "ios/web/public/init/network_context_owner.h" #include "services/network/public/mojom/network_service.mojom.h" namespace net {
diff --git a/ios/web_view/internal/ios_global_state_web_view_configuration.mm b/ios/web_view/internal/ios_global_state_web_view_configuration.mm index d7345f02..0af3596 100644 --- a/ios/web_view/internal/ios_global_state_web_view_configuration.mm +++ b/ios/web_view/internal/ios_global_state_web_view_configuration.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ios/web/public/global_state/ios_global_state_configuration.h" +#include "ios/web/public/init/ios_global_state_configuration.h" #include "base/single_thread_task_runner.h" #include "base/task/post_task.h"
diff --git a/ios/web_view/internal/web_view_global_state_util.mm b/ios/web_view/internal/web_view_global_state_util.mm index a352552..a330706 100644 --- a/ios/web_view/internal/web_view_global_state_util.mm +++ b/ios/web_view/internal/web_view_global_state_util.mm
@@ -7,7 +7,7 @@ #import <UIKit/UIKit.h> #include <memory> -#include "ios/web/public/app/web_main.h" +#include "ios/web/public/init/web_main.h" #import "ios/web_view/internal/web_view_web_client.h" #import "ios/web_view/internal/web_view_web_main_delegate.h"
diff --git a/ios/web_view/internal/web_view_web_main_delegate.h b/ios/web_view/internal/web_view_web_main_delegate.h index 78deeca..b1b39d2 100644 --- a/ios/web_view/internal/web_view_web_main_delegate.h +++ b/ios/web_view/internal/web_view_web_main_delegate.h
@@ -9,7 +9,7 @@ #include <string> #include "base/macros.h" -#include "ios/web/public/app/web_main_delegate.h" +#include "ios/web/public/init/web_main_delegate.h" namespace ios_web_view {
diff --git a/ios/web_view/internal/web_view_web_main_parts.h b/ios/web_view/internal/web_view_web_main_parts.h index 658f428e..fad1d1e 100644 --- a/ios/web_view/internal/web_view_web_main_parts.h +++ b/ios/web_view/internal/web_view_web_main_parts.h
@@ -8,7 +8,7 @@ #include <memory> #include "base/macros.h" -#include "ios/web/public/app/web_main_parts.h" +#include "ios/web/public/init/web_main_parts.h" namespace ios_web_view {
diff --git a/sandbox/linux/services/libc_interceptor.cc b/sandbox/linux/services/libc_interceptor.cc index 50c8f96c..d25b509 100644 --- a/sandbox/linux/services/libc_interceptor.cc +++ b/sandbox/linux/services/libc_interceptor.cc
@@ -188,7 +188,7 @@ static PROTECTED_MEMORY_SECTION base::ProtectedMemory<LibcFunctions> g_libc_funcs; -static void InitLibcLocaltimeFunctions() { +static void InitLibcLocaltimeFunctionsImpl() { auto writer = base::AutoWritableMemory::Create(g_libc_funcs); g_libc_funcs->localtime = reinterpret_cast<LocaltimeFunction>(dlsym(RTLD_NEXT, "localtime")); @@ -238,7 +238,7 @@ return &time_struct; } - CHECK_EQ(0, pthread_once(&g_libc_funcs_guard, InitLibcLocaltimeFunctions)); + InitLibcLocaltimeFunctions(); struct tm* res = base::UnsanitizedCfiCall(g_libc_funcs, &LibcFunctions::localtime)(timep); #if defined(MEMORY_SANITIZER) @@ -264,7 +264,7 @@ return &time_struct; } - CHECK_EQ(0, pthread_once(&g_libc_funcs_guard, InitLibcLocaltimeFunctions)); + InitLibcLocaltimeFunctions(); struct tm* res = base::UnsanitizedCfiCall(g_libc_funcs, &LibcFunctions::localtime64)(timep); #if defined(MEMORY_SANITIZER) @@ -288,7 +288,7 @@ return result; } - CHECK_EQ(0, pthread_once(&g_libc_funcs_guard, InitLibcLocaltimeFunctions)); + InitLibcLocaltimeFunctions(); struct tm* res = base::UnsanitizedCfiCall( g_libc_funcs, &LibcFunctions::localtime_r)(timep, result); #if defined(MEMORY_SANITIZER) @@ -312,7 +312,7 @@ return result; } - CHECK_EQ(0, pthread_once(&g_libc_funcs_guard, InitLibcLocaltimeFunctions)); + InitLibcLocaltimeFunctions(); struct tm* res = base::UnsanitizedCfiCall( g_libc_funcs, &LibcFunctions::localtime64_r)(timep, result); #if defined(MEMORY_SANITIZER) @@ -343,4 +343,9 @@ return HandleLocalTime(fd, iter, fds); } +void InitLibcLocaltimeFunctions() { + CHECK_EQ(0, + pthread_once(&g_libc_funcs_guard, InitLibcLocaltimeFunctionsImpl)); +} + } // namespace sandbox
diff --git a/sandbox/linux/services/libc_interceptor.h b/sandbox/linux/services/libc_interceptor.h index c58c9f34..be020c20 100644 --- a/sandbox/linux/services/libc_interceptor.h +++ b/sandbox/linux/services/libc_interceptor.h
@@ -70,6 +70,9 @@ // children. |backchannel_fd| must be the fd to use for proxying calls. SANDBOX_EXPORT void SetAmZygoteOrRenderer(bool enable, int backchannel_fd); +// Initializes libc interception. Must be called before sandbox lock down. +SANDBOX_EXPORT void InitLibcLocaltimeFunctions(); + } // namespace sandbox #endif // SANDBOX_LINUX_SERVICES_LIBC_INTERCEPTOR_H_
diff --git a/services/data_decoder/public/cpp/json_sanitizer.cc b/services/data_decoder/public/cpp/json_sanitizer.cc index 7b3ec4a..8169612f 100644 --- a/services/data_decoder/public/cpp/json_sanitizer.cc +++ b/services/data_decoder/public/cpp/json_sanitizer.cc
@@ -28,8 +28,8 @@ public: OopJsonSanitizer(service_manager::Connector* connector, const std::string& unsafe_json, - const StringCallback& success_callback, - const StringCallback& error_callback); + StringCallback success_callback, + StringCallback error_callback); private: friend std::default_delete<OopJsonSanitizer>; @@ -46,13 +46,14 @@ OopJsonSanitizer::OopJsonSanitizer(service_manager::Connector* connector, const std::string& unsafe_json, - const StringCallback& success_callback, - const StringCallback& error_callback) - : success_callback_(success_callback), error_callback_(error_callback) { + StringCallback success_callback, + StringCallback error_callback) + : success_callback_(std::move(success_callback)), + error_callback_(std::move(error_callback)) { SafeJsonParser::Parse( connector, unsafe_json, - base::Bind(&OopJsonSanitizer::OnParseSuccess, base::Unretained(this)), - base::Bind(&OopJsonSanitizer::OnParseError, base::Unretained(this))); + base::BindOnce(&OopJsonSanitizer::OnParseSuccess, base::Unretained(this)), + base::BindOnce(&OopJsonSanitizer::OnParseError, base::Unretained(this))); } void OopJsonSanitizer::OnParseSuccess(base::Value value) { @@ -64,21 +65,21 @@ base::Value::Type type = value.type(); if (type != base::Value::Type::DICTIONARY && type != base::Value::Type::LIST) { - error_callback_.Run("Invalid top-level type"); + std::move(error_callback_).Run("Invalid top-level type"); return; } std::string json; if (!base::JSONWriter::Write(value, &json)) { - error_callback_.Run("Encoding error"); + std::move(error_callback_).Run("Encoding error"); return; } - success_callback_.Run(json); + std::move(success_callback_).Run(json); } void OopJsonSanitizer::OnParseError(const std::string& error) { - error_callback_.Run("Parse error: " + error); + std::move(error_callback_).Run("Parse error: " + error); delete this; } @@ -87,11 +88,11 @@ // static void JsonSanitizer::Sanitize(service_manager::Connector* connector, const std::string& unsafe_json, - const StringCallback& success_callback, - const StringCallback& error_callback) { + StringCallback success_callback, + StringCallback error_callback) { // OopJsonSanitizer destroys itself when it is finished. - new OopJsonSanitizer(connector, unsafe_json, success_callback, - error_callback); + new OopJsonSanitizer(connector, unsafe_json, std::move(success_callback), + std::move(error_callback)); } } // namespace data_decoder
diff --git a/services/data_decoder/public/cpp/json_sanitizer.h b/services/data_decoder/public/cpp/json_sanitizer.h index df467978..a8088eb1 100644 --- a/services/data_decoder/public/cpp/json_sanitizer.h +++ b/services/data_decoder/public/cpp/json_sanitizer.h
@@ -30,7 +30,7 @@ // the resulting JSON, which might save some space. class JsonSanitizer { public: - using StringCallback = base::Callback<void(const std::string&)>; + using StringCallback = base::OnceCallback<void(const std::string&)>; // Starts sanitizing the passed in unsafe JSON string. Either the passed // |success_callback| or the |error_callback| will be called with the result @@ -41,8 +41,8 @@ // service manager connection context object that the embedder provides. static void Sanitize(service_manager::Connector* connector, const std::string& unsafe_json, - const StringCallback& success_callback, - const StringCallback& error_callback); + StringCallback success_callback, + StringCallback error_callback); protected: JsonSanitizer() {}
diff --git a/services/data_decoder/public/cpp/json_sanitizer_android.cc b/services/data_decoder/public/cpp/json_sanitizer_android.cc index 5189efba1..e871839 100644 --- a/services/data_decoder/public/cpp/json_sanitizer_android.cc +++ b/services/data_decoder/public/cpp/json_sanitizer_android.cc
@@ -38,8 +38,8 @@ // rejected. class JsonSanitizerAndroid : public JsonSanitizer { public: - JsonSanitizerAndroid(const StringCallback& success_callback, - const StringCallback& error_callback); + JsonSanitizerAndroid(StringCallback success_callback, + StringCallback error_callback); ~JsonSanitizerAndroid() {} void Sanitize(const std::string& unsafe_json); @@ -54,10 +54,10 @@ DISALLOW_COPY_AND_ASSIGN(JsonSanitizerAndroid); }; -JsonSanitizerAndroid::JsonSanitizerAndroid( - const StringCallback& success_callback, - const StringCallback& error_callback) - : success_callback_(success_callback), error_callback_(error_callback) {} +JsonSanitizerAndroid::JsonSanitizerAndroid(StringCallback success_callback, + StringCallback error_callback) + : success_callback_(std::move(success_callback)), + error_callback_(std::move(error_callback)) {} void JsonSanitizerAndroid::Sanitize(const std::string& unsafe_json) { // The JSON parser only accepts wellformed UTF-8. @@ -77,12 +77,12 @@ void JsonSanitizerAndroid::OnSuccess(const std::string& json) { base::SequencedTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(success_callback_, json)); + FROM_HERE, base::BindOnce(std::move(success_callback_), json)); } void JsonSanitizerAndroid::OnError(const std::string& error) { base::SequencedTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(error_callback_, error)); + FROM_HERE, base::BindOnce(std::move(error_callback_), error)); } } // namespace @@ -106,12 +106,13 @@ // static void JsonSanitizer::Sanitize(service_manager::Connector* connector, const std::string& unsafe_json, - const StringCallback& success_callback, - const StringCallback& error_callback) { + StringCallback success_callback, + StringCallback error_callback) { // JsonSanitizerAndroid does all its work synchronously, but posts any // callbacks to the current sequence. This means it can be destroyed at // the end of this method. - JsonSanitizerAndroid sanitizer(success_callback, error_callback); + JsonSanitizerAndroid sanitizer(std::move(success_callback), + std::move(error_callback)); sanitizer.Sanitize(unsafe_json); }
diff --git a/services/data_decoder/public/cpp/json_sanitizer_unittest.cc b/services/data_decoder/public/cpp/json_sanitizer_unittest.cc index a4f59d1b..e8842a9 100644 --- a/services/data_decoder/public/cpp/json_sanitizer_unittest.cc +++ b/services/data_decoder/public/cpp/json_sanitizer_unittest.cc
@@ -91,8 +91,8 @@ run_loop_.reset(new base::RunLoop); JsonSanitizer::Sanitize( nullptr, json, - base::Bind(&JsonSanitizerTest::OnSuccess, base::Unretained(this)), - base::Bind(&JsonSanitizerTest::OnError, base::Unretained(this))); + base::BindOnce(&JsonSanitizerTest::OnSuccess, base::Unretained(this)), + base::BindOnce(&JsonSanitizerTest::OnError, base::Unretained(this))); // We should never get a result immediately. EXPECT_EQ(State::STATE_IDLE, state_);
diff --git a/services/data_decoder/public/cpp/safe_json_parser.cc b/services/data_decoder/public/cpp/safe_json_parser.cc index 6c348ac..3e0d070 100644 --- a/services/data_decoder/public/cpp/safe_json_parser.cc +++ b/services/data_decoder/public/cpp/safe_json_parser.cc
@@ -22,21 +22,23 @@ SafeJsonParser* Create(service_manager::Connector* connector, const std::string& unsafe_json, - const SafeJsonParser::SuccessCallback& success_callback, - const SafeJsonParser::ErrorCallback& error_callback, + SafeJsonParser::SuccessCallback success_callback, + SafeJsonParser::ErrorCallback error_callback, const base::Optional<base::Token>& batch_id) { if (g_factory) - return g_factory(unsafe_json, success_callback, error_callback); + return g_factory(unsafe_json, std::move(success_callback), + std::move(error_callback)); #if defined(OS_IOS) NOTREACHED() << "SafeJsonParser is not supported on iOS (except in tests)"; return nullptr; #elif defined(OS_ANDROID) - return new SafeJsonParserAndroid(unsafe_json, success_callback, - error_callback); + return new SafeJsonParserAndroid(unsafe_json, std::move(success_callback), + std::move(error_callback)); #else - return new SafeJsonParserImpl(connector, unsafe_json, success_callback, - error_callback, batch_id); + return new SafeJsonParserImpl(connector, unsafe_json, + std::move(success_callback), + std::move(error_callback), batch_id); #endif } @@ -50,21 +52,23 @@ // static void SafeJsonParser::Parse(service_manager::Connector* connector, const std::string& unsafe_json, - const SuccessCallback& success_callback, - const ErrorCallback& error_callback) { - SafeJsonParser* parser = Create(connector, unsafe_json, success_callback, - error_callback, base::nullopt); + SuccessCallback success_callback, + ErrorCallback error_callback) { + SafeJsonParser* parser = + Create(connector, unsafe_json, std::move(success_callback), + std::move(error_callback), base::nullopt); parser->Start(); } // static void SafeJsonParser::ParseBatch(service_manager::Connector* connector, const std::string& unsafe_json, - const SuccessCallback& success_callback, - const ErrorCallback& error_callback, + SuccessCallback success_callback, + ErrorCallback error_callback, const base::Token& batch_id) { - SafeJsonParser* parser = Create(connector, unsafe_json, success_callback, - error_callback, batch_id); + SafeJsonParser* parser = + Create(connector, unsafe_json, std::move(success_callback), + std::move(error_callback), batch_id); parser->Start(); }
diff --git a/services/data_decoder/public/cpp/safe_json_parser.h b/services/data_decoder/public/cpp/safe_json_parser.h index 568d85c..e47959b 100644 --- a/services/data_decoder/public/cpp/safe_json_parser.h +++ b/services/data_decoder/public/cpp/safe_json_parser.h
@@ -28,12 +28,12 @@ // deletes itself. class SafeJsonParser { public: - using SuccessCallback = base::Callback<void(base::Value)>; - using ErrorCallback = base::Callback<void(const std::string&)>; + using SuccessCallback = base::OnceCallback<void(base::Value)>; + using ErrorCallback = base::OnceCallback<void(const std::string&)>; using Factory = SafeJsonParser* (*)(const std::string& unsafe_json, - const SuccessCallback& success_callback, - const ErrorCallback& error_callback); + SuccessCallback success_callback, + ErrorCallback error_callback); // Starts parsing the passed in |unsafe_json| and calls either // |success_callback| or |error_callback| when finished. @@ -45,8 +45,8 @@ // in an isolated sandboxed utility process. static void Parse(service_manager::Connector* connector, const std::string& unsafe_json, - const SuccessCallback& success_callback, - const ErrorCallback& error_callback); + SuccessCallback success_callback, + ErrorCallback error_callback); // Same as Parse, but allows clients to provide a |batch_id|, which the system // may use to batch this parse request with other parse requests using the @@ -55,8 +55,8 @@ // other, so this should be used with appropriate caution. static void ParseBatch(service_manager::Connector* connector, const std::string& unsafe_json, - const SuccessCallback& success_callback, - const ErrorCallback& error_callback, + SuccessCallback success_callback, + ErrorCallback error_callback, const base::Token& batch_id); static void SetFactoryForTesting(Factory factory);
diff --git a/services/data_decoder/public/cpp/safe_json_parser_android.cc b/services/data_decoder/public/cpp/safe_json_parser_android.cc index 80555ed9..0ef1fe4 100644 --- a/services/data_decoder/public/cpp/safe_json_parser_android.cc +++ b/services/data_decoder/public/cpp/safe_json_parser_android.cc
@@ -13,13 +13,12 @@ namespace data_decoder { -SafeJsonParserAndroid::SafeJsonParserAndroid( - const std::string& unsafe_json, - const SuccessCallback& success_callback, - const ErrorCallback& error_callback) +SafeJsonParserAndroid::SafeJsonParserAndroid(const std::string& unsafe_json, + SuccessCallback success_callback, + ErrorCallback error_callback) : unsafe_json_(unsafe_json), - success_callback_(success_callback), - error_callback_(error_callback) {} + success_callback_(std::move(success_callback)), + error_callback_(std::move(error_callback)) {} SafeJsonParserAndroid::~SafeJsonParserAndroid() {} @@ -27,10 +26,10 @@ JsonSanitizer::Sanitize( /*connector=*/nullptr, // connector is unused on Android. unsafe_json_, - base::Bind(&SafeJsonParserAndroid::OnSanitizationSuccess, - base::Unretained(this)), - base::Bind(&SafeJsonParserAndroid::OnSanitizationError, - base::Unretained(this))); + base::BindOnce(&SafeJsonParserAndroid::OnSanitizationSuccess, + base::Unretained(this)), + base::BindOnce(&SafeJsonParserAndroid::OnSanitizationError, + base::Unretained(this))); } void SafeJsonParserAndroid::OnSanitizationSuccess( @@ -43,15 +42,15 @@ base::JSON_PARSE_RFC); if (!value_with_error.value) { - error_callback_.Run(value_with_error.error_message); + std::move(error_callback_).Run(value_with_error.error_message); return; } - success_callback_.Run(std::move(*value_with_error.value)); + std::move(success_callback_).Run(std::move(*value_with_error.value)); } void SafeJsonParserAndroid::OnSanitizationError(const std::string& error) { - error_callback_.Run(error); + std::move(error_callback_).Run(error); delete this; }
diff --git a/services/data_decoder/public/cpp/safe_json_parser_android.h b/services/data_decoder/public/cpp/safe_json_parser_android.h index 8c94019..54880d1 100644 --- a/services/data_decoder/public/cpp/safe_json_parser_android.h +++ b/services/data_decoder/public/cpp/safe_json_parser_android.h
@@ -15,8 +15,8 @@ class SafeJsonParserAndroid : public SafeJsonParser { public: SafeJsonParserAndroid(const std::string& unsafe_json, - const SuccessCallback& success_callback, - const ErrorCallback& error_callback); + SuccessCallback success_callback, + ErrorCallback error_callback); private: friend std::default_delete<SafeJsonParserAndroid>;
diff --git a/services/data_decoder/public/cpp/safe_json_parser_impl.cc b/services/data_decoder/public/cpp/safe_json_parser_impl.cc index 8dc81d8..382ea647 100644 --- a/services/data_decoder/public/cpp/safe_json_parser_impl.cc +++ b/services/data_decoder/public/cpp/safe_json_parser_impl.cc
@@ -19,12 +19,12 @@ SafeJsonParserImpl::SafeJsonParserImpl( service_manager::Connector* connector, const std::string& unsafe_json, - const SuccessCallback& success_callback, - const ErrorCallback& error_callback, + SuccessCallback success_callback, + ErrorCallback error_callback, const base::Optional<base::Token>& batch_id) : unsafe_json_(unsafe_json), - success_callback_(success_callback), - error_callback_(error_callback) { + success_callback_(std::move(success_callback)), + error_callback_(std::move(error_callback)) { // If no batch ID has been provided, use a random instance ID to guarantee the // connection is to a new service running in its own process. connector->BindInterface( @@ -70,10 +70,10 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (error.empty() && parsed_json) { if (!success_callback_.is_null()) - success_callback_.Run(std::move(*parsed_json)); + std::move(success_callback_).Run(std::move(*parsed_json)); } else { if (!error_callback_.is_null()) - error_callback_.Run(error); + std::move(error_callback_).Run(error); } // The parsing is done whether an error occured or not, so this instance can
diff --git a/services/data_decoder/public/cpp/safe_json_parser_impl.h b/services/data_decoder/public/cpp/safe_json_parser_impl.h index 59d78df..eb04331 100644 --- a/services/data_decoder/public/cpp/safe_json_parser_impl.h +++ b/services/data_decoder/public/cpp/safe_json_parser_impl.h
@@ -28,8 +28,8 @@ public: SafeJsonParserImpl(service_manager::Connector* connector, const std::string& unsafe_json, - const SuccessCallback& success_callback, - const ErrorCallback& error_callback, + SuccessCallback success_callback, + ErrorCallback error_callback, const base::Optional<base::Token>& batch_id); private:
diff --git a/services/data_decoder/public/cpp/testing_json_parser.cc b/services/data_decoder/public/cpp/testing_json_parser.cc index 934397f..1165cf6 100644 --- a/services/data_decoder/public/cpp/testing_json_parser.cc +++ b/services/data_decoder/public/cpp/testing_json_parser.cc
@@ -20,9 +20,10 @@ SafeJsonParser* CreateTestingJsonParser( const std::string& unsafe_json, - const SafeJsonParser::SuccessCallback& success_callback, - const SafeJsonParser::ErrorCallback& error_callback) { - return new TestingJsonParser(unsafe_json, success_callback, error_callback); + SafeJsonParser::SuccessCallback success_callback, + SafeJsonParser::ErrorCallback error_callback) { + return new TestingJsonParser(unsafe_json, std::move(success_callback), + std::move(error_callback)); } } // namespace @@ -36,11 +37,11 @@ } TestingJsonParser::TestingJsonParser(const std::string& unsafe_json, - const SuccessCallback& success_callback, - const ErrorCallback& error_callback) + SuccessCallback success_callback, + ErrorCallback error_callback) : unsafe_json_(unsafe_json), - success_callback_(success_callback), - error_callback_(error_callback) {} + success_callback_(std::move(success_callback)), + error_callback_(std::move(error_callback)) {} TestingJsonParser::~TestingJsonParser() {} @@ -53,11 +54,11 @@ // completion callbacks may quit the run loop without leaking |this|. base::SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); base::SequencedTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - value_with_error.value - ? base::Bind(success_callback_, - base::Passed(std::move(*value_with_error.value))) - : base::Bind(error_callback_, value_with_error.error_message)); + FROM_HERE, value_with_error.value + ? base::BindOnce(std::move(success_callback_), + std::move(*value_with_error.value)) + : base::BindOnce(std::move(error_callback_), + value_with_error.error_message)); } } // namespace data_decoder
diff --git a/services/data_decoder/public/cpp/testing_json_parser.h b/services/data_decoder/public/cpp/testing_json_parser.h index f75b9f7..fbee2df 100644 --- a/services/data_decoder/public/cpp/testing_json_parser.h +++ b/services/data_decoder/public/cpp/testing_json_parser.h
@@ -30,8 +30,8 @@ // not on the stack). It will delete itself after calling one of the // callbacks. TestingJsonParser(const std::string& unsafe_json, - const SuccessCallback& success_callback, - const ErrorCallback& error_callback); + SuccessCallback success_callback, + ErrorCallback error_callback); ~TestingJsonParser() override; private:
diff --git a/services/data_decoder/public/cpp/testing_json_parser_unittest.cc b/services/data_decoder/public/cpp/testing_json_parser_unittest.cc index 097f4e3c..2af079b 100644 --- a/services/data_decoder/public/cpp/testing_json_parser_unittest.cc +++ b/services/data_decoder/public/cpp/testing_json_parser_unittest.cc
@@ -22,11 +22,12 @@ public: void Parse(const std::string& input) { base::RunLoop run_loop; - SafeJsonParser::Parse(/* connector=*/nullptr, input, - base::Bind(&SuccessCallback, base::Unretained(this), - run_loop.QuitClosure()), - base::Bind(&ErrorCallback, base::Unretained(this), - run_loop.QuitClosure())); + SafeJsonParser::Parse( + /* connector=*/nullptr, input, + base::BindOnce(&SuccessCallback, base::Unretained(this), + run_loop.QuitClosure()), + base::BindOnce(&ErrorCallback, base::Unretained(this), + run_loop.QuitClosure())); run_loop.Run(); }
diff --git a/services/service_manager/sandbox/linux/sandbox_linux.cc b/services/service_manager/sandbox/linux/sandbox_linux.cc index 623ef0e..ee83e14 100644 --- a/services/service_manager/sandbox/linux/sandbox_linux.cc +++ b/services/service_manager/sandbox/linux/sandbox_linux.cc
@@ -33,6 +33,7 @@ #include "build/build_config.h" #include "sandbox/constants.h" #include "sandbox/linux/services/credentials.h" +#include "sandbox/linux/services/libc_interceptor.h" #include "sandbox/linux/services/namespace_sandbox.h" #include "sandbox/linux/services/proc_util.h" #include "sandbox/linux/services/resource_limits.h" @@ -382,6 +383,8 @@ << "InitializeSandbox() called after unexpected directories have been " << "opened. This breaks the security of the setuid sandbox."; + sandbox::InitLibcLocaltimeFunctions(); + // Attempt to limit the future size of the address space of the process. int error = 0; const bool limited_as = LimitAddressSpace(&error);
diff --git a/services/tracing/public/cpp/perfetto/task_runner.h b/services/tracing/public/cpp/perfetto/task_runner.h index 020bfda52..1221bc6 100644 --- a/services/tracing/public/cpp/perfetto/task_runner.h +++ b/services/tracing/public/cpp/perfetto/task_runner.h
@@ -38,6 +38,7 @@ void SetTaskRunner(scoped_refptr<base::SequencedTaskRunner> task_runner); scoped_refptr<base::SequencedTaskRunner> GetOrCreateTaskRunner(); + bool HasTaskRunner() const { return !!task_runner_; } // Not used in Chrome. void AddFileDescriptorWatch(int fd, std::function<void()>) override;
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source.cc b/services/tracing/public/cpp/perfetto/trace_event_data_source.cc index 99b3cce..7ea0561 100644 --- a/services/tracing/public/cpp/perfetto/trace_event_data_source.cc +++ b/services/tracing/public/cpp/perfetto/trace_event_data_source.cc
@@ -248,7 +248,6 @@ target_buffer_ = data_source_config.target_buffer(); // Reduce lock contention by binding the registry without holding the lock. unbound_writer_registry = std::move(startup_writer_registry_); - trace_writers_from_registry_.clear(); } session_id_.fetch_add(1u, std::memory_order_relaxed); @@ -382,7 +381,6 @@ uint32_t session_id = session_id_.load(std::memory_order_relaxed); if (startup_writer_registry_) { trace_writer = startup_writer_registry_->CreateUnboundTraceWriter(); - trace_writers_from_registry_.insert(trace_writer.get()); } else if (producer_client_) { trace_writer = std::make_unique<perfetto::StartupTraceWriter>( producer_client_->CreateTraceWriter(target_buffer_)); @@ -494,28 +492,42 @@ void TraceEventDataSource::ReturnTraceWriter( std::unique_ptr<perfetto::StartupTraceWriter> trace_writer) { + // Prevent concurrent binding of the registry. base::AutoLock lock(lock_); - // It's possible that the returned trace writer was created by a former - // StartupTraceWriterRegistry. In this case, we should not attempt to return - // it to the current registry, so we need to verify first that it was indeed - // created by the current registry. - if (startup_writer_registry_ && - trace_writers_from_registry_.find(trace_writer.get()) != - trace_writers_from_registry_.end()) { - // If the writer is still unbound, the registry will keep it alive until it - // was bound and its buffered data was copied. This ensures that we don't - // lose data from threads that are shut down during startup. - trace_writers_from_registry_.erase(trace_writer.get()); - startup_writer_registry_->ReturnUnboundTraceWriter(std::move(trace_writer)); - } else { - // Delete the TraceWriter on the sequence that Perfetto runs on, needed - // as the ThreadLocalEventSink gets deleted on thread - // shutdown and we can't safely call TaskRunnerHandle::Get() at that point - // (which can happen as the TraceWriter destructor might make a Mojo call - // and trigger it). - PerfettoTracedProcess::GetTaskRunner()->GetOrCreateTaskRunner()->DeleteSoon( - FROM_HERE, std::move(trace_writer)); + + // If we don't have a task runner yet, we must be attempting to return a + // writer before the (very first) registry was bound. We cannot create the + // task runner safely in this case, because the thread pool may not have been + // brought up yet. + if (!PerfettoTracedProcess::GetTaskRunner()->HasTaskRunner()) { + DCHECK(startup_writer_registry_); + // It's safe to call ReturnToRegistry on the current sequence, as it won't + // destroy the writer since the registry was not bound yet. Will keep + // |trace_writer| alive until the registry is bound later. + perfetto::StartupTraceWriter::ReturnToRegistry(std::move(trace_writer)); + return; } + + // Return the TraceWriter on the sequence that Perfetto runs on. Needed as the + // ThreadLocalEventSink gets deleted on thread shutdown and we can't safely + // call TaskRunnerHandle::Get() at that point (which can happen as the + // TraceWriter destructor might make a Mojo call and trigger it). + PerfettoTracedProcess::GetTaskRunner()->GetOrCreateTaskRunner()->PostTask( + FROM_HERE, + base::BindOnce( + // Pass writer as raw pointer so that we leak it if task posting fails + // (during shutdown). + [](perfetto::StartupTraceWriter* raw_trace_writer) { + std::unique_ptr<perfetto::StartupTraceWriter> trace_writer( + raw_trace_writer); + // May destroy |trace_writer|. If the writer is still unbound, the + // registry will keep it alive until it was bound and its buffered + // data was copied. This ensures that we don't lose data from + // threads that are shut down during startup. + perfetto::StartupTraceWriter::ReturnToRegistry( + std::move(trace_writer)); + }, + trace_writer.release())); } } // namespace tracing
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source.h b/services/tracing/public/cpp/perfetto/trace_event_data_source.h index e19620d..308364f 100644 --- a/services/tracing/public/cpp/perfetto/trace_event_data_source.h +++ b/services/tracing/public/cpp/perfetto/trace_event_data_source.h
@@ -162,10 +162,6 @@ // SetupStartupTracing() is called. std::unique_ptr<perfetto::StartupTraceWriterRegistry> startup_writer_registry_; - // Unbound writers created by the current |startup_writer_registry_|. We track - // these writers to ensure that we only return the correct ones back to the - // registry. - std::set<perfetto::StartupTraceWriter*> trace_writers_from_registry_; std::vector<std::string> histograms_; bool privacy_filtering_enabled_ = false;
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc b/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc index 50523d7..a6e6847 100644 --- a/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc +++ b/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc
@@ -182,6 +182,7 @@ public: void SetUp() override { PerfettoTracedProcess::ResetTaskRunnerForTesting(); + PerfettoTracedProcess::GetTaskRunner()->GetOrCreateTaskRunner(); auto perfetto_wrapper = std::make_unique<PerfettoTaskRunner>( scoped_task_environment_.GetMainThreadTaskRunner()); producer_client_ =
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 8f8c400..90e08b5 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -2170,6 +2170,25 @@ ] } ], + "FastBorderRadius": [ + { + "platforms": [ + "android", + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FastBorderRadius" + ] + } + ] + } + ], "FilterAdsOnAbusiveSites": [ { "platforms": [ @@ -6153,7 +6172,7 @@ ] } ], - "WebRTC-Audio-SendSideBWE": [ + "WebRTC-Audio-SendSideBwe": [ { "platforms": [ "windows",
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index ba033271..5456f7b 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -36,6 +36,10 @@ const base::Feature kScriptStreaming{"ScriptStreaming", base::FEATURE_ENABLED_BY_DEFAULT}; +// Allow streaming small (<30kB) scripts. +const base::Feature kSmallScriptStreaming{"SmallScriptStreaming", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Enables user level memory pressure signal generation on Android. const base::Feature kUserLevelMemoryPressureSignal{ "UserLevelMemoryPressureSignal", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index 97d8605..6b77555 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -172,8 +172,6 @@ "platform/task_type.h", "platform/url_conversion.h", "platform/user_metrics_action.h", - "platform/web_application_cache_host.h", - "platform/web_application_cache_host_client.h", "platform/web_audio_bus.h", "platform/web_audio_destination_consumer.h", "platform/web_audio_device.h", @@ -375,6 +373,8 @@ "web/modules/service_worker/web_service_worker_context_client.h", "web/modules/service_worker/web_service_worker_context_proxy.h", "web/web_active_fling_parameters.h", + "web/web_application_cache_host.h", + "web/web_application_cache_host_client.h", "web/web_apply_constraints_request.h", "web/web_array_buffer.h", "web/web_array_buffer_converter.h",
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index 1fc85ce..13c0f68 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h
@@ -19,6 +19,7 @@ BLINK_COMMON_EXPORT extern const base::Feature kEnableGpuRasterizationViewportRestriction; BLINK_COMMON_EXPORT extern const base::Feature kScriptStreaming; +BLINK_COMMON_EXPORT extern const base::Feature kSmallScriptStreaming; BLINK_COMMON_EXPORT extern const base::Feature kUserLevelMemoryPressureSignal; BLINK_COMMON_EXPORT extern const base::Feature kFirstContentfulPaintPlusPlus; BLINK_COMMON_EXPORT extern const base::Feature kFreezePurgeMemoryAllPagesFrozen;
diff --git a/third_party/blink/public/mojom/dwrite_font_proxy/dwrite_font_proxy.mojom b/third_party/blink/public/mojom/dwrite_font_proxy/dwrite_font_proxy.mojom index 3d87a6b..9327563 100644 --- a/third_party/blink/public/mojom/dwrite_font_proxy/dwrite_font_proxy.mojom +++ b/third_party/blink/public/mojom/dwrite_font_proxy/dwrite_font_proxy.mojom
@@ -94,7 +94,7 @@ // to perform searches in it. Retrieval may take up to several seconds if the // table needs rebuilding on browser side. GetUniqueNameLookupTable() => - (mojo_base.mojom.ReadOnlySharedMemoryRegion font_lookup_table); + (mojo_base.mojom.ReadOnlySharedMemoryRegion? font_lookup_table); // Locates a font family that is able to render the specified text using the // specified style. If successful, the family_index and family_name will
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom index 74f4164..e96332e 100644 --- a/third_party/blink/public/mojom/web_feature/web_feature.mojom +++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -2303,6 +2303,7 @@ kV8XRInputSource_Gamepad_AttributeGetter = 2910, kV8XRSession_End_Method = 2911, kV8XRWebGLLayer_Constructor = 2912, + kFetchKeepalive = 2913, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h index 2697e8f..cd2e860 100644 --- a/third_party/blink/public/platform/platform.h +++ b/third_party/blink/public/platform/platform.h
@@ -187,6 +187,10 @@ return nullptr; } + // AppCache ---------------------------------------------------------- + + virtual bool IsURLSupportedForAppCache(const WebURL& url) { return false; } + // Audio -------------------------------------------------------------- virtual double AudioHardwareSampleRate() { return 0; }
diff --git a/third_party/blink/public/platform/web_worker_fetch_context.h b/third_party/blink/public/platform/web_worker_fetch_context.h index 2e138ba..3f7b1cb 100644 --- a/third_party/blink/public/platform/web_worker_fetch_context.h +++ b/third_party/blink/public/platform/web_worker_fetch_context.h
@@ -13,7 +13,6 @@ #include "base/unguessable_token.h" #include "third_party/blink/public/mojom/service_worker/controller_service_worker_mode.mojom-shared.h" #include "third_party/blink/public/platform/code_cache_loader.h" -#include "third_party/blink/public/platform/web_application_cache_host.h" #include "third_party/blink/public/platform/web_document_subresource_filter.h" #include "third_party/blink/public/platform/web_security_origin.h" #include "third_party/blink/public/platform/web_string.h"
diff --git a/third_party/blink/public/platform/web_application_cache_host.h b/third_party/blink/public/web/web_application_cache_host.h similarity index 77% rename from third_party/blink/public/platform/web_application_cache_host.h rename to third_party/blink/public/web/web_application_cache_host.h index 0ba0d07..8b1277c 100644 --- a/third_party/blink/public/platform/web_application_cache_host.h +++ b/third_party/blink/public/web/web_application_cache_host.h
@@ -28,8 +28,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_APPLICATION_CACHE_HOST_H_ -#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_APPLICATION_CACHE_HOST_H_ +#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_APPLICATION_CACHE_HOST_H_ +#define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_APPLICATION_CACHE_HOST_H_ #include "third_party/blink/public/mojom/appcache/appcache.mojom-shared.h" #include "third_party/blink/public/mojom/appcache/appcache_info.mojom-shared.h" @@ -37,9 +37,14 @@ #include "third_party/blink/public/platform/web_url.h" #include "third_party/blink/public/platform/web_vector.h" +namespace WTF { +class String; +} + namespace blink { -class WebString; +class WebApplicationCacheHostClient; +class WebLocalFrame; class WebURL; class WebURLResponse; @@ -50,10 +55,26 @@ public: virtual ~WebApplicationCacheHost() = default; + // TODO(crbug.com/950159): Remove + // CreateWebApplicationCacheHostFor{SharedWorker,Frame}. + // Instantiate a WebApplicationCacheHost that interacts with the frame or the + // shared worker. + BLINK_EXPORT static std::unique_ptr<WebApplicationCacheHost> + CreateWebApplicationCacheHostForFrame( + WebLocalFrame* frame, + WebApplicationCacheHostClient* client, + const base::UnguessableToken& appcache_host_id, + scoped_refptr<base::SingleThreadTaskRunner> task_runner); + BLINK_EXPORT static std::unique_ptr<WebApplicationCacheHost> + CreateWebApplicationCacheHostForSharedWorker( + WebApplicationCacheHostClient* client, + const base::UnguessableToken& appcache_host_id, + scoped_refptr<base::SingleThreadTaskRunner> task_runner); + // Called for every request made within the context. virtual void WillStartMainResourceRequest( const WebURL& url, - const WebString& method, + const WTF::String& method, const WebApplicationCacheHost* spawning_host) {} // One or the other selectCache methods is called after having parsed the @@ -119,8 +140,13 @@ virtual const base::UnguessableToken& GetHostID() const { return base::UnguessableToken::Null(); } + // TODO(crbug.com/950159): Remove this API once + // ApplicationCacheHostForSharedWorker is created in WebSharedWorkerImpl. + virtual void SelectCacheForSharedWorker( + int64_t app_cache_id, + base::OnceClosure completion_callback) {} }; } // namespace blink -#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_APPLICATION_CACHE_HOST_H_ +#endif // THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_APPLICATION_CACHE_HOST_H_
diff --git a/third_party/blink/public/platform/web_application_cache_host_client.h b/third_party/blink/public/web/web_application_cache_host_client.h similarity index 89% rename from third_party/blink/public/platform/web_application_cache_host_client.h rename to third_party/blink/public/web/web_application_cache_host_client.h index 321f550d..3e0243a 100644 --- a/third_party/blink/public/platform/web_application_cache_host_client.h +++ b/third_party/blink/public/web/web_application_cache_host_client.h
@@ -28,12 +28,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_APPLICATION_CACHE_HOST_CLIENT_H_ -#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_APPLICATION_CACHE_HOST_CLIENT_H_ +#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_APPLICATION_CACHE_HOST_CLIENT_H_ +#define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_APPLICATION_CACHE_HOST_CLIENT_H_ #include "third_party/blink/public/mojom/appcache/appcache.mojom-shared.h" -#include "third_party/blink/public/platform/web_application_cache_host.h" #include "third_party/blink/public/platform/web_common.h" +#include "third_party/blink/public/platform/web_url.h" namespace blink { @@ -61,4 +61,4 @@ } // namespace blink -#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_APPLICATION_CACHE_HOST_CLIENT_H_ +#endif // THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_APPLICATION_CACHE_HOST_CLIENT_H_
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 c607be4..48ee3f1 100644 --- a/third_party/blink/public/web/web_local_frame_client.h +++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -39,10 +39,10 @@ #include "third_party/blink/public/common/frame/frame_owner_element_type.h" #include "third_party/blink/public/common/frame/sandbox_flags.h" #include "third_party/blink/public/common/frame/user_activation_update_type.h" +#include "third_party/blink/public/common/loader/url_loader_factory_bundle.h" #include "third_party/blink/public/mojom/frame/lifecycle.mojom-shared.h" #include "third_party/blink/public/platform/blame_context.h" #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider.h" -#include "third_party/blink/public/platform/web_application_cache_host.h" #include "third_party/blink/public/platform/web_common.h" #include "third_party/blink/public/platform/web_content_security_policy.h" #include "third_party/blink/public/platform/web_content_security_policy_struct.h" @@ -59,6 +59,7 @@ #include "third_party/blink/public/platform/web_url_loader_factory.h" #include "third_party/blink/public/platform/web_url_request.h" #include "third_party/blink/public/platform/web_worker_fetch_context.h" +#include "third_party/blink/public/web/web_application_cache_host.h" #include "third_party/blink/public/web/web_ax_object.h" #include "third_party/blink/public/web/web_document_loader.h" #include "third_party/blink/public/web/web_dom_message_event.h" @@ -864,6 +865,10 @@ // Transfers user activation state from |source_frame| to the current frame. virtual void TransferUserActivationFrom(WebLocalFrame* source_frame) {} + + // AppCache ------------------------------------------------------------ + virtual void UpdateSubresourceFactory( + std::unique_ptr<blink::URLLoaderFactoryBundleInfo> info) {} }; } // namespace blink
diff --git a/third_party/blink/public/web/web_navigation_control.h b/third_party/blink/public/web/web_navigation_control.h index 388552c..f1114e652 100644 --- a/third_party/blink/public/web/web_navigation_control.h +++ b/third_party/blink/public/web/web_navigation_control.h
@@ -84,7 +84,9 @@ // This runs some JavaScript event listeners, which may cancel the navigation // or detach the frame. In this case the method returns false and client // should not proceed with the navigation. - virtual bool WillStartNavigation(const WebNavigationInfo&) = 0; + virtual bool WillStartNavigation( + const WebNavigationInfo&, + bool is_history_navigation_in_new_child_frame) = 0; // Informs the frame that the navigation it asked the client to do was // dropped. @@ -95,6 +97,10 @@ // in another process. virtual void MarkAsLoading() = 0; + // TODO(ahemery): Remove all IsClientNavigationInitialHistoryLoad functions + // when IsPerNavigationMojoInterface is enabled. + virtual bool IsClientNavigationInitialHistoryLoad() = 0; + protected: explicit WebNavigationControl(WebTreeScopeType scope) : WebLocalFrame(scope) {}
diff --git a/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.cc b/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.cc index 334ad31..f9e91089 100644 --- a/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.cc +++ b/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.cc
@@ -65,7 +65,7 @@ // https://html.spec.whatwg.org/C/#window-reflecting-body-element-event-handler-set document = &node->GetDocument(); } else { - element = ToElement(node); + element = To<Element>(node); document = &node->GetDocument(); } // EventTarget::GetExecutionContext() sometimes returns the document which
diff --git a/third_party/blink/renderer/bindings/core/v8/script_streamer.cc b/third_party/blink/renderer/bindings/core/v8/script_streamer.cc index 198126b..b436793f 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_streamer.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_streamer.cc
@@ -11,6 +11,7 @@ #include "base/threading/scoped_blocking_call.h" #include "base/threading/thread_restrictions.h" #include "mojo/public/cpp/system/wait.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/renderer/bindings/core/v8/v8_code_cache.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/element.h" @@ -24,7 +25,6 @@ #include "third_party/blink/renderer/platform/loader/fetch/cached_metadata.h" #include "third_party/blink/renderer/platform/loader/fetch/resource.h" #include "third_party/blink/renderer/platform/loader/fetch/response_body_loader.h" -#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/public/worker_pool.h" @@ -354,8 +354,12 @@ } // namespace bool ScriptStreamer::HasEnoughDataForStreaming(size_t resource_buffer_size) { - // Only stream larger scripts. - return resource_buffer_size >= small_script_threshold_; + if (base::FeatureList::IsEnabled(features::kSmallScriptStreaming)) { + return resource_buffer_size >= kMaximumLengthOfBOM; + } else { + // Only stream larger scripts. + return resource_buffer_size >= small_script_threshold_; + } } // Try to start streaming the script from the given datapipe, taking ownership
diff --git a/third_party/blink/renderer/core/accessibility/ax_object_cache.cc b/third_party/blink/renderer/core/accessibility/ax_object_cache.cc index 8d5ba4bc..26dce18 100644 --- a/third_party/blink/renderer/core/accessibility/ax_object_cache.cc +++ b/third_party/blink/renderer/core/accessibility/ax_object_cache.cc
@@ -127,8 +127,7 @@ bool AXObjectCache::IsInsideFocusableElementOrARIAWidget(const Node& node) { const Node* cur_node = &node; do { - if (cur_node->IsElementNode()) { - const Element* element = ToElement(cur_node); + if (const auto* element = DynamicTo<Element>(cur_node)) { if (element->IsFocusable()) return true; String role = element->getAttribute("role");
diff --git a/third_party/blink/renderer/core/animation/animation.cc b/third_party/blink/renderer/core/animation/animation.cc index e183005..b9a3387 100644 --- a/third_party/blink/renderer/core/animation/animation.cc +++ b/third_party/blink/renderer/core/animation/animation.cc
@@ -519,9 +519,11 @@ base::Optional<double> Animation::CalculateStartTime( double current_time) const { - base::Optional<double> start_time = - timeline_->EffectiveTime() - current_time / playback_rate_; - DCHECK(!IsNull(start_time.value())); + base::Optional<double> start_time; + if (timeline_) { + start_time = timeline_->EffectiveTime() - current_time / playback_rate_; + DCHECK(!IsNull(start_time.value())); + } return start_time; } @@ -981,7 +983,8 @@ } void Animation::ForceServiceOnNextFrame() { - timeline_->Wake(); + if (timeline_) + timeline_->Wake(); } CompositorAnimations::FailureReasons
diff --git a/third_party/blink/renderer/core/animation/animation_test.cc b/third_party/blink/renderer/core/animation/animation_test.cc index 577f8983..c9e49ed 100644 --- a/third_party/blink/renderer/core/animation/animation_test.cc +++ b/third_party/blink/renderer/core/animation/animation_test.cc
@@ -959,10 +959,11 @@ Timing timing; timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30); auto* keyframe_effect_composited = MakeGarbageCollected<KeyframeEffect>( - ToElement(object_composited->GetNode()), MakeSimpleEffectModel(), timing); + To<Element>(object_composited->GetNode()), MakeSimpleEffectModel(), + timing); Animation* animation_composited = timeline->Play(keyframe_effect_composited); auto* keyframe_effect_not_composited = MakeGarbageCollected<KeyframeEffect>( - ToElement(object_not_composited->GetNode()), MakeSimpleEffectModel(), + To<Element>(object_not_composited->GetNode()), MakeSimpleEffectModel(), timing); Animation* animation_not_composited = timeline->Play(keyframe_effect_not_composited);
diff --git a/third_party/blink/renderer/core/animation/scroll_timeline.cc b/third_party/blink/renderer/core/animation/scroll_timeline.cc index 1e7b10f4..47546bf 100644 --- a/third_party/blink/renderer/core/animation/scroll_timeline.cc +++ b/third_party/blink/renderer/core/animation/scroll_timeline.cc
@@ -314,8 +314,8 @@ return; GetActiveScrollTimelineSet().insert(resolved_scroll_source_); - if (resolved_scroll_source_->IsElementNode()) - ToElement(resolved_scroll_source_)->SetNeedsCompositingUpdate(); + if (auto* element = DynamicTo<Element>(resolved_scroll_source_.Get())) + element->SetNeedsCompositingUpdate(); resolved_scroll_source_->GetDocument() .GetLayoutView() ->Compositor() @@ -332,8 +332,8 @@ return; GetActiveScrollTimelineSet().erase(resolved_scroll_source_); - if (resolved_scroll_source_->IsElementNode()) - ToElement(resolved_scroll_source_)->SetNeedsCompositingUpdate(); + if (auto* element = DynamicTo<Element>(resolved_scroll_source_.Get())) + element->SetNeedsCompositingUpdate(); auto* layout_view = resolved_scroll_source_->GetDocument().GetLayoutView(); if (layout_view && layout_view->Compositor()) { layout_view->Compositor()->SetNeedsCompositingUpdate(
diff --git a/third_party/blink/renderer/core/css/css_computed_style_declaration.cc b/third_party/blink/renderer/core/css/css_computed_style_declaration.cc index 1e6009e..f8ebf9a 100644 --- a/third_party/blink/renderer/core/css/css_computed_style_declaration.cc +++ b/third_party/blink/renderer/core/css/css_computed_style_declaration.cc
@@ -313,9 +313,10 @@ Node* CSSComputedStyleDeclaration::StyledNode() const { if (!node_) return nullptr; - if (node_->IsElementNode()) { + + if (auto* node_element = DynamicTo<Element>(node_.Get())) { if (PseudoElement* element = - ToElement(node_)->GetPseudoElement(pseudo_element_specifier_)) + node_element->GetPseudoElement(pseudo_element_specifier_)) return element; } return node_.Get();
diff --git a/third_party/blink/renderer/core/css/css_style_sheet.cc b/third_party/blink/renderer/core/css/css_style_sheet.cc index 445d6079..03d68a2a1 100644 --- a/third_party/blink/renderer/core/css/css_style_sheet.cc +++ b/third_party/blink/renderer/core/css/css_style_sheet.cc
@@ -586,8 +586,9 @@ bool CSSStyleSheet::IsAlternate() const { if (owner_node_) { - return owner_node_->IsElementNode() && - ToElement(owner_node_)->getAttribute(kRelAttr).Contains("alternate"); + auto* owner_element = DynamicTo<Element>(owner_node_.Get()); + return owner_element && + owner_element->getAttribute(kRelAttr).Contains("alternate"); } return alternate_from_constructor_; }
diff --git a/third_party/blink/renderer/core/css/css_style_sheet.h b/third_party/blink/renderer/core/css/css_style_sheet.h index b6cc7a6..f773cdf 100644 --- a/third_party/blink/renderer/core/css/css_style_sheet.h +++ b/third_party/blink/renderer/core/css/css_style_sheet.h
@@ -194,7 +194,6 @@ void SetText(const String&, bool allow_import_rules, ExceptionState&); void SetMedia(MediaList*); void SetAlternateFromConstructor(bool); - bool IsAlternate() const; bool CanBeActivated(const String& current_preferrable_name) const; void SetIsConstructed(bool is_constructed) { @@ -206,6 +205,7 @@ void Trace(blink::Visitor*) override; private: + bool IsAlternate() const; bool IsCSSStyleSheet() const override { return true; } String type() const override { return "text/css"; }
diff --git a/third_party/blink/renderer/core/css/cssom/computed_style_property_map.cc b/third_party/blink/renderer/core/css/cssom/computed_style_property_map.cc index f48127de..5ab8054 100644 --- a/third_party/blink/renderer/core/css/cssom/computed_style_property_map.cc +++ b/third_party/blink/renderer/core/css/cssom/computed_style_property_map.cc
@@ -200,9 +200,8 @@ DCHECK(node_); if (!pseudo_id_) return node_; - if (node_->IsElementNode()) { - if (PseudoElement* element = - (ToElement(node_))->GetPseudoElement(pseudo_id_)) { + if (auto* element_node = DynamicTo<Element>(node_.Get())) { + if (PseudoElement* element = element_node->GetPseudoElement(pseudo_id_)) { return element; } }
diff --git a/third_party/blink/renderer/core/css/selector_query.cc b/third_party/blink/renderer/core/css/selector_query.cc index 5d41921..f497bc4 100644 --- a/third_party/blink/renderer/core/css/selector_query.cc +++ b/third_party/blink/renderer/core/css/selector_query.cc
@@ -197,10 +197,11 @@ inline bool AncestorHasClassName(ContainerNode& root_node, const AtomicString& class_name) { - if (!root_node.IsElementNode()) + auto* root_node_element = DynamicTo<Element>(root_node); + if (!root_node_element) return false; - for (Element* element = &ToElement(root_node); element; + for (auto* element = root_node_element; element; element = element->parentElement()) { if (element->HasClassName(class_name)) return true; @@ -345,10 +346,10 @@ typename SelectorQueryTrait::OutputType& output) const { for (ContainerNode* node = NextTraversingShadowTree(root_node, &root_node); node; node = NextTraversingShadowTree(*node, &root_node)) { - if (!node->IsElementNode()) + auto* element = DynamicTo<Element>(node); + if (!element) continue; QUERY_STATS_INCREMENT(slow_traversing_shadow_tree_scan); - Element* element = ToElement(node); if (!SelectorListMatches(root_node, *element)) continue; SelectorQueryTrait::AppendElement(output, *element);
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc index c21c328..f33e2f6 100644 --- a/third_party/blink/renderer/core/css/style_engine.cc +++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -1599,9 +1599,9 @@ } void StyleEngine::NodeWillBeRemoved(Node& node) { - if (node.IsElementNode()) { + if (auto* element = DynamicTo<Element>(node)) { pending_invalidations_.RescheduleSiblingInvalidationsAsDescendants( - ToElement(node)); + *element); } // Mark closest ancestor with with LayoutObject to have all whitespace @@ -1620,8 +1620,9 @@ layout_object = layout_object->Parent(); DCHECK(layout_object); DCHECK(layout_object->GetNode()); - if (layout_object->GetNode()->IsElementNode()) { - whitespace_reattach_set_.insert(ToElement(layout_object->GetNode())); + if (auto* layout_object_element = + DynamicTo<Element>(layout_object->GetNode())) { + whitespace_reattach_set_.insert(layout_object_element); GetDocument().ScheduleLayoutTreeUpdateIfNeeded(); } } @@ -1736,8 +1737,8 @@ } for (ContainerNode* ancestor = root_element.ParentOrShadowHostNode(); ancestor; ancestor = ancestor->ParentOrShadowHostNode()) { - if (ancestor->IsElementNode()) - ToElement(ancestor)->RecalcStyleForTraversalRootAncestor(); + if (auto* ancestor_element = DynamicTo<Element>(ancestor)) + ancestor_element->RecalcStyleForTraversalRootAncestor(); ancestor->ClearChildNeedsStyleRecalc(); } style_recalc_root_.Clear(); @@ -1757,8 +1758,8 @@ for (ContainerNode* ancestor = root_element.GetReattachParent(); ancestor; ancestor = ancestor->GetReattachParent()) { - if (ancestor->IsElementNode()) - ToElement(ancestor)->RebuildLayoutTreeForTraversalRootAncestor(); + if (auto* ancestor_element = DynamicTo<Element>(ancestor)) + ancestor_element->RebuildLayoutTreeForTraversalRootAncestor(); ancestor->ClearChildNeedsStyleRecalc(); ancestor->ClearChildNeedsReattachLayoutTree(); } @@ -1824,14 +1825,9 @@ // darkening is enabled. preferred_color_scheme_ = PreferredColorScheme::kNoPreference; } - - if (preferred_color_scheme_ != old_preferred_color_scheme) { + if (preferred_color_scheme_ != old_preferred_color_scheme) PlatformColorsChanged(); - if (LocalFrameView* view = GetDocument().View()) { - view->SetBaseBackgroundColor(use_dark_scheme ? Color::kBlack - : Color::kWhite); - } - } + UpdateColorSchemeBackground(); } void StyleEngine::ColorSchemeChanged() { @@ -1847,6 +1843,28 @@ UpdateColorScheme(); } +void StyleEngine::UpdateColorSchemeBackground() { + LocalFrameView* view = GetDocument().View(); + if (!view) + return; + + bool use_dark_background = false; + + if (preferred_color_scheme_ == PreferredColorScheme::kDark) { + const ComputedStyle* style = nullptr; + if (auto* root_element = GetDocument().documentElement()) + style = root_element->GetComputedStyle(); + if (style) { + if (style->UsedColorScheme() == ColorScheme::kDark) + use_dark_background = true; + } else if (SupportsDarkColorScheme()) { + use_dark_background = true; + } + } + + view->SetUseDarkSchemeBackground(use_dark_background); +} + void StyleEngine::Trace(blink::Visitor* visitor) { visitor->Trace(document_); visitor->Trace(injected_user_style_sheets_);
diff --git a/third_party/blink/renderer/core/css/style_engine.h b/third_party/blink/renderer/core/css/style_engine.h index ffa88d6..164c603e 100644 --- a/third_party/blink/renderer/core/css/style_engine.h +++ b/third_party/blink/renderer/core/css/style_engine.h
@@ -347,6 +347,7 @@ PreferredColorScheme GetPreferredColorScheme() const { return preferred_color_scheme_; } + void UpdateColorSchemeBackground(); void Trace(blink::Visitor*) override; const char* NameInHeapSnapshot() const override { return "StyleEngine"; }
diff --git a/third_party/blink/renderer/core/css/style_engine_test.cc b/third_party/blink/renderer/core/css/style_engine_test.cc index 122bca6..f09c6ceb 100644 --- a/third_party/blink/renderer/core/css/style_engine_test.cc +++ b/third_party/blink/renderer/core/css/style_engine_test.cc
@@ -1927,4 +1927,19 @@ form->removeChild(outer); } +TEST_F(StyleEngineTest, ColorSchemeBaseBackgroundChange) { + ScopedCSSColorSchemeForTest enable_color_scheme(true); + GetDocument().GetSettings()->SetPreferredColorScheme( + PreferredColorScheme::kDark); + UpdateAllLifecyclePhases(); + + EXPECT_EQ(Color::kWhite, GetDocument().View()->BaseBackgroundColor()); + + GetDocument().documentElement()->SetInlineStyleProperty( + CSSPropertyID::kColorScheme, "dark"); + UpdateAllLifecyclePhases(); + + EXPECT_EQ(Color::kBlack, GetDocument().View()->BaseBackgroundColor()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/css/style_invalidation_root.cc b/third_party/blink/renderer/core/css/style_invalidation_root.cc index 798ed798..bb29306e 100644 --- a/third_party/blink/renderer/core/css/style_invalidation_root.cc +++ b/third_party/blink/renderer/core/css/style_invalidation_root.cc
@@ -16,7 +16,7 @@ return &shadow_root->host(); if (root_node->IsDocumentNode()) return root_node->GetDocument().documentElement(); - return ToElement(root_node); + return To<Element>(root_node); } #if DCHECK_IS_ON()
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 435c475..f2a88bb9 100644 --- a/third_party/blink/renderer/core/css/style_property_serializer.cc +++ b/third_party/blink/renderer/core/css/style_property_serializer.cc
@@ -322,6 +322,12 @@ case CSSPropertyID::kBorderRight: case CSSPropertyID::kBorderBottom: case CSSPropertyID::kBorderLeft: + case CSSPropertyID::kBorderBlockStart: + case CSSPropertyID::kBorderBlockEnd: + case CSSPropertyID::kBorderInlineStart: + case CSSPropertyID::kBorderInlineEnd: + case CSSPropertyID::kBorderBlock: + case CSSPropertyID::kBorderInline: case CSSPropertyID::kOutline: case CSSPropertyID::kColumnRule: case CSSPropertyID::kColumns:
diff --git a/third_party/blink/renderer/core/css/style_sheet_candidate.cc b/third_party/blink/renderer/core/css/style_sheet_candidate.cc index 9db69be..91419b4 100644 --- a/third_party/blink/renderer/core/css/style_sheet_candidate.cc +++ b/third_party/blink/renderer/core/css/style_sheet_candidate.cc
@@ -40,7 +40,7 @@ using namespace html_names; AtomicString StyleSheetCandidate::Title() const { - return IsElement() ? ToElement(GetNode()).FastGetAttribute(kTitleAttr) + return IsElement() ? To<Element>(GetNode()).FastGetAttribute(kTitleAttr) : g_null_atom; }
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc b/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc index 1138e9e7..8c82115 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc +++ b/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc
@@ -1212,7 +1212,7 @@ auto* template_el = ToHTMLTemplateElement(GetDocument().getElementById("template")); - auto* child = ToElement(template_el->content()->firstChild()); + auto* child = To<Element>(template_el->content()->firstChild()); EXPECT_FALSE(child->isConnected()); ASSERT_TRUE(child->getDisplayLockForBindings()); @@ -1239,7 +1239,7 @@ // Try to lock an element that was moved from a template to a document. auto* document_child = - ToElement(GetDocument().adoptNode(child, ASSERT_NO_EXCEPTION)); + To<Element>(GetDocument().adoptNode(child, ASSERT_NO_EXCEPTION)); GetDocument().getElementById("container")->appendChild(document_child); {
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc b/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc index 644274a5..ad63a673 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc +++ b/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc
@@ -50,13 +50,14 @@ DisplayLockUtilities::ActivatableLockedInclusiveAncestors(Element& element) { HeapVector<Member<Element>> elements_to_activate; for (Node& ancestor : FlatTreeTraversal::InclusiveAncestorsOf(element)) { - if (!ancestor.IsElementNode()) + auto* ancestor_element = DynamicTo<Element>(ancestor); + if (!ancestor_element) continue; - if (auto* context = ToElement(ancestor).GetDisplayLockContext()) { + if (auto* context = ancestor_element->GetDisplayLockContext()) { DCHECK(context->IsActivatable()); if (!context->IsLocked()) continue; - elements_to_activate.push_back(&ToElement(ancestor)); + elements_to_activate.push_back(ancestor_element); } } return elements_to_activate; @@ -89,9 +90,10 @@ // structure that we can use to quickly identify nodes that are in the // locked subtree. for (Node& ancestor : ancestor_view) { - if (!ancestor.IsElementNode()) + auto* ancestor_node = DynamicTo<Element>(ancestor); + if (!ancestor_node) continue; - if (auto* context = ToElement(ancestor).GetDisplayLockContext()) + if (auto* context = ancestor_node->GetDisplayLockContext()) scoped_update_forced_list_.push_back(context->GetScopedForcedUpdate()); } } @@ -127,11 +129,12 @@ // TODO(crbug.com/924550): Once we figure out a more efficient way to // determine whether we're inside a locked subtree or not, change this. for (Node& ancestor : FlatTreeTraversal::AncestorsOf(node)) { - if (!ancestor.IsElementNode()) + auto* ancestor_element = DynamicTo<Element>(ancestor); + if (!ancestor_element) continue; - if (auto* context = ToElement(ancestor).GetDisplayLockContext()) { + if (auto* context = ancestor_element->GetDisplayLockContext()) { if (context->IsLocked()) - return &ToElement(ancestor); + return ancestor_element; } } return nullptr; @@ -146,11 +149,12 @@ } Element* locked_ancestor = nullptr; for (Node& ancestor : FlatTreeTraversal::InclusiveAncestorsOf(node)) { - if (!ancestor.IsElementNode()) + auto* ancestor_node = DynamicTo<Element>(ancestor); + if (!ancestor_node) continue; - if (auto* context = ToElement(ancestor).GetDisplayLockContext()) { + if (auto* context = ancestor_node->GetDisplayLockContext()) { if (context->IsLocked()) - locked_ancestor = &ToElement(ancestor); + locked_ancestor = ancestor_node; } } return locked_ancestor;
diff --git a/third_party/blink/renderer/core/dom/child_frame_disconnector.cc b/third_party/blink/renderer/core/dom/child_frame_disconnector.cc index 7412bbf..9ef4c7f 100644 --- a/third_party/blink/renderer/core/dom/child_frame_disconnector.cc +++ b/third_party/blink/renderer/core/dom/child_frame_disconnector.cc
@@ -63,13 +63,12 @@ #if DCHECK_IS_ON() static unsigned CheckConnectedSubframeCountIsConsistent(Node& node) { unsigned count = 0; - - if (node.IsElementNode()) { + if (auto* element = DynamicTo<Element>(node)) { auto* frame_owner_element = DynamicTo<HTMLFrameOwnerElement>(node); if (frame_owner_element && frame_owner_element->ContentFrame()) count++; - if (ShadowRoot* root = ToElement(node).GetShadowRoot()) + if (ShadowRoot* root = element->GetShadowRoot()) count += CheckConnectedSubframeCountIsConsistent(*root); }
diff --git a/third_party/blink/renderer/core/dom/container_node.cc b/third_party/blink/renderer/core/dom/container_node.cc index 31ea369..63b85e3e 100644 --- a/third_party/blink/renderer/core/dom/container_node.cc +++ b/third_party/blink/renderer/core/dom/container_node.cc
@@ -633,8 +633,8 @@ // e.g. mutation event listener can create a new range. GetDocument().NodeWillBeRemoved(child); - if (child.IsElementNode()) { - if (auto* context = ToElement(child).GetDisplayLockContext()) + if (auto* child_element = DynamicTo<Element>(child)) { + if (auto* context = child_element->GetDisplayLockContext()) context->NotifyWillDisconnect(); } } @@ -1044,8 +1044,9 @@ StyleChangeReasonForTracing::CreateWithExtraData( style_change_reason::kPseudoClass, style_change_extra_data::g_focus)); - if (IsElementNode() && ToElement(this)->ChildrenOrSiblingsAffectedByFocus()) - ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoFocus); + auto* this_element = DynamicTo<Element>(this); + if (this_element && this_element->ChildrenOrSiblingsAffectedByFocus()) + this_element->PseudoStateChanged(CSSSelector::kPseudoFocus); GetLayoutObject()->InvalidateIfControlStateChanged(kFocusControlState); FocusVisibleStateChanged(); @@ -1064,9 +1065,9 @@ style_change_reason::kPseudoClass, style_change_extra_data::g_focus_visible)); - if (IsElementNode() && - ToElement(this)->ChildrenOrSiblingsAffectedByFocusVisible()) - ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoFocusVisible); + auto* this_element = DynamicTo<Element>(this); + if (this_element && this_element->ChildrenOrSiblingsAffectedByFocusVisible()) + this_element->PseudoStateChanged(CSSSelector::kPseudoFocusVisible); } void ContainerNode::FocusWithinStateChanged() { @@ -1080,9 +1081,9 @@ style_change_reason::kPseudoClass, style_change_extra_data::g_focus_within)); } - if (IsElementNode() && - ToElement(this)->ChildrenOrSiblingsAffectedByFocusWithin()) - ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoFocusWithin); + auto* this_element = DynamicTo<Element>(this); + if (this_element && this_element->ChildrenOrSiblingsAffectedByFocusWithin()) + this_element->PseudoStateChanged(CSSSelector::kPseudoFocusWithin); } void ContainerNode::SetFocused(bool received, WebFocusType focus_type) { @@ -1096,11 +1097,12 @@ // If this is an author shadow host and indirectly focused (has focused // element within its shadow root), update focus. - if (IsElementNode() && GetDocument().FocusedElement() && + auto* this_element = DynamicTo<Element>(this); + if (this_element && GetDocument().FocusedElement() && GetDocument().FocusedElement() != this) { - if (ToElement(this)->AuthorShadowRoot()) - received = - received && ToElement(this)->AuthorShadowRoot()->delegatesFocus(); + if (this_element->AuthorShadowRoot()) { + received = received && this_element->AuthorShadowRoot()->delegatesFocus(); + } } if (IsFocused() == received) @@ -1115,8 +1117,8 @@ // If :focus sets display: none, we lose focus but still need to recalc our // style. - if (IsElementNode() && ToElement(this)->ChildrenOrSiblingsAffectedByFocus()) { - ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoFocus); + if (this_element && this_element->ChildrenOrSiblingsAffectedByFocus()) { + this_element->PseudoStateChanged(CSSSelector::kPseudoFocus); } else { SetNeedsStyleRecalc(kLocalStyleChange, StyleChangeReasonForTracing::CreateWithExtraData( @@ -1125,9 +1127,9 @@ } if (RuntimeEnabledFeatures::CSSFocusVisibleEnabled()) { - if (IsElementNode() && - ToElement(this)->ChildrenOrSiblingsAffectedByFocusVisible()) { - ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoFocusVisible); + if (this_element && + this_element->ChildrenOrSiblingsAffectedByFocusVisible()) { + this_element->PseudoStateChanged(CSSSelector::kPseudoFocusVisible); } else { SetNeedsStyleRecalc(kLocalStyleChange, StyleChangeReasonForTracing::CreateWithExtraData( @@ -1136,9 +1138,8 @@ } } - if (IsElementNode() && - ToElement(this)->ChildrenOrSiblingsAffectedByFocusWithin()) { - ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoFocusWithin); + if (this_element && this_element->ChildrenOrSiblingsAffectedByFocusWithin()) { + this_element->PseudoStateChanged(CSSSelector::kPseudoFocusWithin); } else { SetNeedsStyleRecalc(kLocalStyleChange, StyleChangeReasonForTracing::CreateWithExtraData( @@ -1162,9 +1163,9 @@ Node::SetActive(down); if (!GetLayoutObject()) { - if (IsElementNode() && - ToElement(this)->ChildrenOrSiblingsAffectedByActive()) { - ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoActive); + auto* this_element = DynamicTo<Element>(this); + if (this_element && this_element->ChildrenOrSiblingsAffectedByActive()) { + this_element->PseudoStateChanged(CSSSelector::kPseudoActive); } else { SetNeedsStyleRecalc(kLocalStyleChange, StyleChangeReasonForTracing::CreateWithExtraData( @@ -1184,8 +1185,9 @@ style_change_reason::kPseudoClass, style_change_extra_data::g_active)); } - if (IsElementNode() && ToElement(this)->ChildrenOrSiblingsAffectedByActive()) - ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoActive); + auto* this_element = DynamicTo<Element>(this); + if (this_element && this_element->ChildrenOrSiblingsAffectedByActive()) + this_element->PseudoStateChanged(CSSSelector::kPseudoActive); GetLayoutObject()->InvalidateIfControlStateChanged(kPressedControlState); } @@ -1201,9 +1203,9 @@ if (!GetLayoutObject()) { if (new_value) return; - if (IsElementNode() && - ToElement(this)->ChildrenOrSiblingsAffectedByDrag()) { - ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoDrag); + auto* this_element = DynamicTo<Element>(this); + if (this_element && this_element->ChildrenOrSiblingsAffectedByDrag()) { + this_element->PseudoStateChanged(CSSSelector::kPseudoDrag); } else { SetNeedsStyleRecalc(kLocalStyleChange, @@ -1224,8 +1226,9 @@ style_change_reason::kPseudoClass, style_change_extra_data::g_drag)); } - if (IsElementNode() && ToElement(this)->ChildrenOrSiblingsAffectedByDrag()) - ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoDrag); + auto* this_element = DynamicTo<Element>(this); + if (this_element && this_element->ChildrenOrSiblingsAffectedByDrag()) + this_element->PseudoStateChanged(CSSSelector::kPseudoDrag); } void ContainerNode::SetHovered(bool over) { @@ -1244,8 +1247,9 @@ style_change_reason::kPseudoClass, style_change_extra_data::g_hover)); } - if (IsElementNode() && ToElement(this)->ChildrenOrSiblingsAffectedByHover()) - ToElement(this)->PseudoStateChanged(CSSSelector::kPseudoHover); + auto* this_element = DynamicTo<Element>(this); + if (this_element && this_element->ChildrenOrSiblingsAffectedByHover()) + this_element->PseudoStateChanged(CSSSelector::kPseudoHover); if (LayoutObject* o = GetLayoutObject()) o->InvalidateIfControlStateChanged(kHoverControlState); @@ -1403,8 +1407,9 @@ continue; if (auto* child_text_node = DynamicTo<Text>(child)) child_text_node->RecalcTextStyle(change); - else if (child->IsElementNode()) - ToElement(child)->RecalcStyle(change); + + if (auto* child_element = DynamicTo<Element>(child)) + child_element->RecalcStyle(change); } } @@ -1419,10 +1424,10 @@ return; } - if (!child->IsElementNode()) + auto* element = DynamicTo<Element>(child); + if (!element) return; - Element* element = ToElement(child); if (element->NeedsRebuildLayoutTree(whitespace_attacher)) element->RebuildLayoutTree(whitespace_attacher); else @@ -1482,14 +1487,14 @@ if (!HasRestyleFlag(DynamicRestyleFlags::kChildrenAffectedByStructuralRules)) return; - Element* element_after_change = - !node_after_change || node_after_change->IsElementNode() - ? ToElement(node_after_change) - : ElementTraversal::NextSibling(*node_after_change); - Element* element_before_change = - !node_before_change || node_before_change->IsElementNode() - ? ToElement(node_before_change) - : ElementTraversal::PreviousSibling(*node_before_change); + auto* element_after_change = DynamicTo<Element>(node_after_change); + if (node_after_change && !element_after_change) + element_after_change = ElementTraversal::NextSibling(*node_after_change); + auto* element_before_change = DynamicTo<Element>(node_before_change); + if (node_before_change && !element_before_change) { + element_before_change = + ElementTraversal::PreviousSibling(*node_before_change); + } // TODO(futhark@chromium.org): move this code into StyleEngine and collect the // various invalidation sets into a single InvalidationLists object and
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index acfcd30..b94f64a 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -234,6 +234,7 @@ #include "third_party/blink/renderer/core/loader/prerenderer_client.h" #include "third_party/blink/renderer/core/loader/progress_tracker.h" #include "third_party/blink/renderer/core/loader/text_resource_decoder_builder.h" +#include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h" #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/event_with_hit_test_results.h" #include "third_party/blink/renderer/core/page/focus_controller.h" @@ -2352,6 +2353,7 @@ ClearChildNeedsReattachLayoutTree(); PropagateStyleToViewport(); + GetStyleEngine().UpdateColorSchemeBackground(); View()->UpdateCountersAfterStyleChange(); GetLayoutView()->RecalcLayoutOverflow(); @@ -8081,6 +8083,32 @@ } } +void Document::CountDeprecation(mojom::WebFeature feature) { + // TODO(yoichio): We should remove these counters when v0 APIs are removed. + // crbug.com/946875. + if (const OriginTrialContext* origin_trial_context = + OriginTrialContext::FromOrCreate(this)) { + if (feature == WebFeature::kHTMLImports && + origin_trial_context->IsFeatureEnabled( + OriginTrialFeature::kHTMLImports) && + !RuntimeEnabledFeatures::HTMLImportsEnabledByRuntimeFlag()) { + CountUse(WebFeature::kHTMLImportsOnReverseOriginTrials); + } else if (feature == WebFeature::kElementCreateShadowRoot && + origin_trial_context->IsFeatureEnabled( + OriginTrialFeature::kShadowDOMV0) && + !RuntimeEnabledFeatures::ShadowDOMV0EnabledByRuntimeFlag()) { + CountUse(WebFeature::kElementCreateShadowRootOnReverseOriginTrials); + } else if (feature == WebFeature::kDocumentRegisterElement && + origin_trial_context->IsFeatureEnabled( + OriginTrialFeature::kCustomElementsV0) && + !RuntimeEnabledFeatures:: + CustomElementsV0EnabledByRuntimeFlag()) { + CountUse(WebFeature::kDocumentRegisterElementOnReverseOriginTrials); + } + } + Deprecation::CountDeprecation(Loader(), feature); +} + void Document::CountUse(CSSPropertyID property, UseCounterHelper::CSSPropertyType type) const { if (DocumentLoader* loader = Loader()) {
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h index 5f0cd9ee..8f6f61a 100644 --- a/third_party/blink/renderer/core/dom/document.h +++ b/third_party/blink/renderer/core/dom/document.h
@@ -1562,6 +1562,7 @@ // Use counter related functions. void CountUse(mojom::WebFeature feature) final; + void CountDeprecation(mojom::WebFeature feature) final; void CountUse(mojom::WebFeature feature) const; void CountUse(CSSPropertyID property_id, UseCounterHelper::CSSPropertyType) const;
diff --git a/third_party/blink/renderer/core/dom/document_statistics_collector.cc b/third_party/blink/renderer/core/dom/document_statistics_collector.cc index 80defe0..308b4f94 100644 --- a/third_party/blink/renderer/core/dom/document_statistics_collector.cc +++ b/third_party/blink/renderer/core/dom/document_statistics_collector.cc
@@ -117,14 +117,9 @@ void CollectFeatures(Element& root, WebDistillabilityFeatures& features, bool under_list_item = false) { - for (Node& node : NodeTraversal::ChildrenOf(root)) { + for (Element& element : ElementTraversal::ChildrenOf(root)) { bool is_list_item = false; - if (!node.IsElementNode()) { - continue; - } - features.element_count++; - Element& element = ToElement(node); if (element.HasTagName(kATag)) { features.anchor_count++; } else if (element.HasTagName(kFormTag)) {
diff --git a/third_party/blink/renderer/core/dom/document_test.cc b/third_party/blink/renderer/core/dom/document_test.cc index 47aece5..88b9214 100644 --- a/third_party/blink/renderer/core/dom/document_test.cc +++ b/third_party/blink/renderer/core/dom/document_test.cc
@@ -37,7 +37,7 @@ #include "services/network/public/mojom/referrer_policy.mojom-shared.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/platform/web_application_cache_host.h" +#include "third_party/blink/public/web/web_application_cache_host.h" #include "third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index 6a0f2bd..4486fe3 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -1422,9 +1422,10 @@ HeapVector<Member<Element>> invisible_ancestors; HeapVector<Member<Element>> activated_elements; for (Node& ancestor : FlatTreeTraversal::InclusiveAncestorsOf(*this)) { - if (ancestor.IsElementNode() && - ToElement(ancestor).Invisible() != InvisibleState::kMissing) { - invisible_ancestors.push_back(ToElement(ancestor)); + auto* ancestor_element = DynamicTo<Element>(ancestor); + if (ancestor_element && + ancestor_element->Invisible() != InvisibleState::kMissing) { + invisible_ancestors.push_back(ancestor_element); activated_elements.push_back(ancestor.GetTreeScope().Retarget(*this)); } } @@ -1441,8 +1442,9 @@ if (!RuntimeEnabledFeatures::InvisibleDOMEnabled()) return false; for (Node& ancestor : FlatTreeTraversal::InclusiveAncestorsOf(*this)) { - if (ancestor.IsElementNode() && - ToElement(ancestor).Invisible() == InvisibleState::kStatic) + auto* ancestor_element = DynamicTo<Element>(ancestor); + if (ancestor_element && + ancestor_element->Invisible() == InvisibleState::kStatic) return true; } return false; @@ -1453,8 +1455,9 @@ !CanParticipateInFlatTree()) return false; for (Node& ancestor : FlatTreeTraversal::InclusiveAncestorsOf(*this)) { - if (ancestor.IsElementNode() && - ToElement(ancestor).Invisible() != InvisibleState::kMissing) + auto* ancestor_element = DynamicTo<Element>(ancestor); + if (ancestor_element && + ancestor_element->Invisible() != InvisibleState::kMissing) return true; } return false; @@ -2120,10 +2123,10 @@ if (Fullscreen::IsFullscreenElement(*this)) { SetContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false); - if (insertion_point.IsElementNode()) { - ToElement(insertion_point).SetContainsFullScreenElement(false); - ToElement(insertion_point) - .SetContainsFullScreenElementOnAncestorsCrossingFrameBoundaries( + if (auto* insertion_point_element = DynamicTo<Element>(insertion_point)) { + insertion_point_element->SetContainsFullScreenElement(false); + insertion_point_element + ->SetContainsFullScreenElementOnAncestorsCrossingFrameBoundaries( false); } } @@ -3081,7 +3084,7 @@ CheckForSiblingStyleChanges( change.type == kElementRemoved ? kSiblingElementRemoved : kSiblingElementInserted, - ToElement(change.sibling_changed), change.sibling_before_change, + To<Element>(change.sibling_changed.Get()), change.sibling_before_change, change.sibling_after_change); if (ShadowRoot* shadow_root = GetShadowRoot()) @@ -3555,14 +3558,15 @@ HeapVector<std::pair<Member<Element>, Member<Element>>> activatable_targets; for (Node& ancestor : FlatTreeTraversal::InclusiveAncestorsOf(*this)) { - if (!ancestor.IsElementNode()) + auto* ancestor_element = DynamicTo<Element>(ancestor); + if (!ancestor_element) continue; - if (auto* context = ToElement(ancestor).GetDisplayLockContext()) { + if (auto* context = ancestor_element->GetDisplayLockContext()) { // If any of the ancestors is not activatable, we can't activate. if (!context->IsActivatable()) return; activatable_targets.push_back(std::make_pair( - &ToElement(ancestor), &ancestor.GetTreeScope().Retarget(*this))); + ancestor_element, &ancestor.GetTreeScope().Retarget(*this))); } } @@ -3593,9 +3597,10 @@ // check whether a node is in a locked subtree quickly. // See crbug.com/924550 for more details. for (const Node& current : FlatTreeTraversal::InclusiveAncestorsOf(*this)) { - if (!current.IsElementNode()) + auto* current_element = DynamicTo<Element>(current); + if (!current_element) continue; - if (auto* context = ToElement(current).GetDisplayLockContext()) { + if (auto* context = current_element->GetDisplayLockContext()) { if (!context->IsActivatable()) return true; } @@ -3788,7 +3793,9 @@ "This element has no parent node."); return; } - if (!p->IsElementNode()) { + + auto* parent = DynamicTo<Element>(p); + if (!parent) { exception_state.ThrowDOMException( DOMExceptionCode::kNoModificationAllowedError, "This element's parent is of type '" + p->nodeName() + @@ -3796,7 +3803,6 @@ return; } - Element* parent = ToElement(p); Node* prev = previousSibling(); Node* next = nextSibling(); @@ -3954,7 +3960,7 @@ Element* new_child, ExceptionState& exception_state) { Node* return_value = InsertAdjacent(where, new_child, exception_state); - return ToElement(return_value); + return To<Element>(return_value); } void Element::insertAdjacentText(const String& where, @@ -4218,7 +4224,7 @@ // the first language. do { if (n->IsElementNode()) { - if (const ElementData* element_data = ToElement(n)->GetElementData()) { + if (const auto* element_data = To<Element>(n)->GetElementData()) { AttributeCollection attributes = element_data->Attributes(); // Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7 if (const Attribute* attribute = @@ -4666,13 +4672,13 @@ // the tree, part of the tree might still carry the flag. if (!value && Fullscreen::IsFullscreenElement(*this)) { for (Node* node = firstChild(); node;) { - if (!node->IsElementNode() || - !ToElement(node)->ContainsPersistentVideo()) { + auto* element = DynamicTo<Element>(node); + if (!element || !element->ContainsPersistentVideo()) { node = node->nextSibling(); break; } - ToElement(node)->SetContainsPersistentVideo(false); + element->SetContainsPersistentVideo(false); node = node->firstChild(); } }
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h index d4a6485..8184c7e 100644 --- a/third_party/blink/renderer/core/dom/element.h +++ b/third_party/blink/renderer/core/dom/element.h
@@ -1182,6 +1182,11 @@ return true; } +template <> +struct DowncastTraits<Element> { + static bool AllowFrom(const Node& node) { return node.IsElementNode(); } +}; + // Type casting. template <typename T> inline T& ToElement(Node& node) {
diff --git a/third_party/blink/renderer/core/events/application_cache_error_event.h b/third_party/blink/renderer/core/events/application_cache_error_event.h index 2c77fe58..bfbb4f9 100644 --- a/third_party/blink/renderer/core/events/application_cache_error_event.h +++ b/third_party/blink/renderer/core/events/application_cache_error_event.h
@@ -6,7 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_APPLICATION_CACHE_ERROR_EVENT_H_ #include "third_party/blink/public/mojom/appcache/appcache.mojom-blink.h" -#include "third_party/blink/public/platform/web_application_cache_host_client.h" +#include "third_party/blink/public/web/web_application_cache_host_client.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/event_interface_names.h" #include "third_party/blink/renderer/core/events/application_cache_error_event_init.h"
diff --git a/third_party/blink/renderer/core/exported/BUILD.gn b/third_party/blink/renderer/core/exported/BUILD.gn index a624305..ac43281 100644 --- a/third_party/blink/renderer/core/exported/BUILD.gn +++ b/third_party/blink/renderer/core/exported/BUILD.gn
@@ -5,8 +5,14 @@ blink_core_sources("exported") { sources = [ + "application_cache_host_for_shared_worker.cc", + "application_cache_host_for_shared_worker.h", "local_frame_client_impl.cc", "local_frame_client_impl.h", + "renderer_webapplicationcachehost_impl.cc", + "renderer_webapplicationcachehost_impl.h", + "web_application_cache_host_impl.cc", + "web_application_cache_host_impl.h", "web_array_buffer.cc", "web_array_buffer_converter.cc", "web_associated_url_loader_impl.cc",
diff --git a/third_party/blink/renderer/core/exported/application_cache_host_for_shared_worker.cc b/third_party/blink/renderer/core/exported/application_cache_host_for_shared_worker.cc new file mode 100644 index 0000000..e178c0e --- /dev/null +++ b/third_party/blink/renderer/core/exported/application_cache_host_for_shared_worker.cc
@@ -0,0 +1,54 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/exported/application_cache_host_for_shared_worker.h" + +namespace blink { + +ApplicationCacheHostForSharedWorker::ApplicationCacheHostForSharedWorker( + WebApplicationCacheHostClient* client, + const base::UnguessableToken& appcache_host_id, + scoped_refptr<base::SingleThreadTaskRunner> task_runner) + : WebApplicationCacheHostImpl(nullptr /* WebLocalFrame* */, + client, + appcache_host_id, + std::move(task_runner)) {} + +ApplicationCacheHostForSharedWorker::~ApplicationCacheHostForSharedWorker() = + default; + +void ApplicationCacheHostForSharedWorker::WillStartMainResourceRequest( + const WebURL& url, + const String& method, + const WebApplicationCacheHost* spawning_host) {} + +void ApplicationCacheHostForSharedWorker::DidReceiveResponseForMainResource( + const WebURLResponse&) {} + +void ApplicationCacheHostForSharedWorker::SelectCacheWithoutManifest() {} + +bool ApplicationCacheHostForSharedWorker::SelectCacheWithManifest( + const WebURL& manifestURL) { + return true; +} + +void ApplicationCacheHostForSharedWorker::LogMessage( + mojom::blink::ConsoleMessageLevel log_level, + const String& message) {} + +void ApplicationCacheHostForSharedWorker::SetSubresourceFactory( + network::mojom::blink::URLLoaderFactoryPtr url_loader_factory) {} + +std::unique_ptr<WebApplicationCacheHost> +WebApplicationCacheHost::CreateWebApplicationCacheHostForSharedWorker( + WebApplicationCacheHostClient* client, + const base::UnguessableToken& appcache_host_id, + scoped_refptr<base::SingleThreadTaskRunner> task_runner) { + auto application_cache_host_for_shared_worker = + std::make_unique<ApplicationCacheHostForSharedWorker>( + client, appcache_host_id, std::move(task_runner)); + return std::move(application_cache_host_for_shared_worker); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/exported/application_cache_host_for_shared_worker.h b/third_party/blink/renderer/core/exported/application_cache_host_for_shared_worker.h new file mode 100644 index 0000000..922fb8f --- /dev/null +++ b/third_party/blink/renderer/core/exported/application_cache_host_for_shared_worker.h
@@ -0,0 +1,46 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_APPLICATION_CACHE_HOST_FOR_SHARED_WORKER_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_APPLICATION_CACHE_HOST_FOR_SHARED_WORKER_H_ + +#include "base/unguessable_token.h" +#include "third_party/blink/renderer/core/exported/web_application_cache_host_impl.h" + +namespace blink { + +class ApplicationCacheHostForSharedWorker final + : public WebApplicationCacheHostImpl { + public: + ApplicationCacheHostForSharedWorker( + WebApplicationCacheHostClient* client, + const base::UnguessableToken& appcache_host_id, + scoped_refptr<base::SingleThreadTaskRunner> task_runner); + ~ApplicationCacheHostForSharedWorker() override; + + // Main resource loading is different for workers. The main resource is + // loaded by the worker using WorkerClassicScriptLoader. + // These overrides are stubbed out. + void WillStartMainResourceRequest( + const WebURL& url, + const String& method, + const WebApplicationCacheHost* spawning_host) override; + void DidReceiveResponseForMainResource(const WebURLResponse&) override; + + // Cache selection is also different for workers. We know at construction + // time what cache to select and do so then. + // These overrides are stubbed out. + void SelectCacheWithoutManifest() override; + bool SelectCacheWithManifest(const WebURL& manifestURL) override; + + // mojom::blink::AppCacheFrontend: + void LogMessage(mojom::blink::ConsoleMessageLevel log_level, + const String& message) override; + void SetSubresourceFactory( + network::mojom::blink::URLLoaderFactoryPtr url_loader_factory) override; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_APPLICATION_CACHE_HOST_FOR_SHARED_WORKER_H_
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 58227c9..89cab6fa 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
@@ -40,7 +40,6 @@ #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider.h" #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider_client.h" #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_application_cache_host.h" #include "third_party/blink/public/platform/web_media_player_source.h" #include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h" #include "third_party/blink/public/platform/web_scroll_into_view_params.h" @@ -48,6 +47,7 @@ #include "third_party/blink/public/platform/web_url.h" #include "third_party/blink/public/platform/web_url_error.h" #include "third_party/blink/public/platform/web_vector.h" +#include "third_party/blink/public/web/web_application_cache_host.h" #include "third_party/blink/public/web/web_autofill_client.h" #include "third_party/blink/public/web/web_document.h" #include "third_party/blink/public/web/web_dom_event.h"
diff --git a/third_party/blink/renderer/core/exported/renderer_webapplicationcachehost_impl.cc b/third_party/blink/renderer/core/exported/renderer_webapplicationcachehost_impl.cc new file mode 100644 index 0000000..c2c24db --- /dev/null +++ b/third_party/blink/renderer/core/exported/renderer_webapplicationcachehost_impl.cc
@@ -0,0 +1,66 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/exported/renderer_webapplicationcachehost_impl.h" + +#include "third_party/blink/public/common/loader/url_loader_factory_bundle.h" +#include "third_party/blink/public/web/web_console_message.h" +#include "third_party/blink/public/web/web_local_frame.h" +#include "third_party/blink/public/web/web_local_frame_client.h" +#include "third_party/blink/public/web/web_view.h" +#include "third_party/blink/renderer/platform/web_test_support.h" + +namespace blink { + +RendererWebApplicationCacheHostImpl::RendererWebApplicationCacheHostImpl( + WebLocalFrame* web_local_frame, + WebApplicationCacheHostClient* client, + const base::UnguessableToken& appcache_host_id, + scoped_refptr<base::SingleThreadTaskRunner> task_runner) + : WebApplicationCacheHostImpl(web_local_frame, + client, + appcache_host_id, + std::move(task_runner)), + web_local_frame_(web_local_frame) {} + +void RendererWebApplicationCacheHostImpl::LogMessage( + mojom::blink::ConsoleMessageLevel log_level, + const String& message) { + if (WebTestSupport::IsRunningWebTest()) + return; + + if (!web_local_frame_ || !web_local_frame_->View() || + !web_local_frame_->View()->MainFrame()) + return; + + WebFrame* main_frame = web_local_frame_->View()->MainFrame(); + if (!main_frame->IsWebLocalFrame()) + return; + // TODO(michaeln): Make app cache host per-frame and correctly report to the + // involved frame. + main_frame->ToWebLocalFrame()->AddMessageToConsole(WebConsoleMessage( + static_cast<mojom::blink::ConsoleMessageLevel>(log_level), message)); +} + +void RendererWebApplicationCacheHostImpl::SetSubresourceFactory( + network::mojom::blink::URLLoaderFactoryPtr url_loader_factory) { + auto info = std::make_unique<URLLoaderFactoryBundleInfo>(); + info->appcache_factory_info().set_handle( + url_loader_factory.PassInterface().PassHandle()); + web_local_frame_->Client()->UpdateSubresourceFactory(std::move(info)); +} + +std::unique_ptr<WebApplicationCacheHost> +WebApplicationCacheHost::CreateWebApplicationCacheHostForFrame( + WebLocalFrame* frame, + WebApplicationCacheHostClient* client, + const base::UnguessableToken& appcache_host_id, + scoped_refptr<base::SingleThreadTaskRunner> task_runner) { + auto renderer_webapplicationcachehost_impl = + std::make_unique<RendererWebApplicationCacheHostImpl>( + frame, client, appcache_host_id, std::move(task_runner)); + return std::move(renderer_webapplicationcachehost_impl); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/exported/renderer_webapplicationcachehost_impl.h b/third_party/blink/renderer/core/exported/renderer_webapplicationcachehost_impl.h new file mode 100644 index 0000000..d0726b3a --- /dev/null +++ b/third_party/blink/renderer/core/exported/renderer_webapplicationcachehost_impl.h
@@ -0,0 +1,37 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_RENDERER_WEBAPPLICATIONCACHEHOST_IMPL_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_RENDERER_WEBAPPLICATIONCACHEHOST_IMPL_H_ + +#include "third_party/blink/renderer/core/exported/web_application_cache_host_impl.h" + +namespace blink { +class WebLocalFrame; + +class RendererWebApplicationCacheHostImpl : public WebApplicationCacheHostImpl { + public: + RendererWebApplicationCacheHostImpl( + WebLocalFrame* web_frame, + blink::WebApplicationCacheHostClient* client, + const base::UnguessableToken& appcache_host_id, + scoped_refptr<base::SingleThreadTaskRunner> task_runner); + + // mojom::blink::AppCacheHostFrontend: + void LogMessage(mojom::blink::ConsoleMessageLevel log_level, + const String& message) override; + + void SetSubresourceFactory( + network::mojom::blink::URLLoaderFactoryPtr url_loader_factory) override; + + private: + // Stores the WebLocalFrame. |this| keeps it as a raw pointer because |this|'s + // owned by ApplicationCacheHost which is destroyed when + // DocumentLoader::DetachFromFrame is called. + WebLocalFrame* web_local_frame_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_RENDERER_WEBAPPLICATIONCACHEHOST_IMPL_H_
diff --git a/content/renderer/appcache/web_application_cache_host_impl.cc b/third_party/blink/renderer/core/exported/web_application_cache_host_impl.cc similarity index 60% rename from content/renderer/appcache/web_application_cache_host_impl.cc rename to third_party/blink/renderer/core/exported/web_application_cache_host_impl.cc index afea51c..ad8c3b1 100644 --- a/content/renderer/appcache/web_application_cache_host_impl.cc +++ b/third_party/blink/renderer/core/exported/web_application_cache_host_impl.cc
@@ -2,64 +2,59 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/renderer/appcache/web_application_cache_host_impl.h" +#include "third_party/blink/renderer/core/exported/web_application_cache_host_impl.h" -#include <stddef.h> -#include <vector> - -#include "base/compiler_specific.h" -#include "base/containers/id_map.h" -#include "base/strings/string_util.h" -#include "base/strings/stringprintf.h" -#include "content/common/appcache_interfaces.h" -#include "content/public/common/service_names.mojom.h" -#include "content/public/renderer/render_thread.h" -#include "content/renderer/render_frame_impl.h" -#include "mojo/public/cpp/bindings/interface_request.h" -#include "services/service_manager/public/cpp/connector.h" -#include "third_party/blink/public/mojom/appcache/appcache.mojom.h" -#include "third_party/blink/public/mojom/appcache/appcache_info.mojom.h" -#include "third_party/blink/public/mojom/devtools/console_message.mojom.h" -#include "third_party/blink/public/mojom/frame/document_interface_broker.mojom.h" +#include "third_party/blink/public/mojom/frame/document_interface_broker.mojom-blink.h" +#include "third_party/blink/public/platform/interface_provider.h" +#include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_url.h" #include "third_party/blink/public/platform/web_url_response.h" +#include "third_party/blink/public/web/web_application_cache_host_client.h" +#include "third_party/blink/public/web/web_frame.h" +#include "third_party/blink/public/web/web_local_frame.h" +#include "third_party/blink/renderer/core/frame/local_frame_client.h" -using blink::WebApplicationCacheHost; -using blink::WebApplicationCacheHostClient; -using blink::WebString; -using blink::WebURL; -using blink::WebURLResponse; -using blink::WebVector; - -namespace content { +namespace blink { namespace { +const char kHttpGETMethod[] = "GET"; + // Note: the order of the elements in this array must match those // of the EventID enum in appcache_interfaces.h. const char* const kEventNames[] = {"Checking", "Error", "NoUpdate", "Downloading", "Progress", "UpdateReady", "Cached", "Obsolete"}; -GURL ClearUrlRef(const GURL& url) { - if (!url.has_ref()) +KURL ClearUrlRef(const WebURL& web_url) { + KURL url(web_url); + if (!url.HasFragmentIdentifier()) return url; - GURL::Replacements replacements; - replacements.ClearRef(); - return url.ReplaceComponents(replacements); + url.RemoveFragmentIdentifier(); + return url; +} + +mojom::blink::DocumentInterfaceBroker* GetDocumentInterfaceBroker( + WebLocalFrame* web_frame) { + if (!web_frame) + return nullptr; + Frame* frame = WebFrame::ToCoreFrame(*web_frame); + if (auto* local_frame = DynamicTo<LocalFrame>(frame)) + return local_frame->Client()->GetDocumentInterfaceBroker(); + return nullptr; } } // namespace WebApplicationCacheHostImpl::WebApplicationCacheHostImpl( - blink::mojom::DocumentInterfaceBroker* interface_broker, + WebLocalFrame* web_frame, WebApplicationCacheHostClient* client, const base::UnguessableToken& appcache_host_id, scoped_refptr<base::SingleThreadTaskRunner> task_runner) : binding_(this), client_(client), - status_(blink::mojom::AppCacheStatus::APPCACHE_STATUS_UNCACHED), + status_(mojom::blink::AppCacheStatus::APPCACHE_STATUS_UNCACHED), is_scheme_supported_(false), is_get_method_(false), is_new_master_entry_(MAYBE_NEW_ENTRY), @@ -71,8 +66,11 @@ else host_id_ = base::UnguessableToken::Create(); - blink::mojom::AppCacheFrontendPtr frontend_ptr; + mojom::blink::AppCacheFrontendPtr frontend_ptr; binding_.Bind(mojo::MakeRequest(&frontend_ptr, task_runner), task_runner); + + mojom::blink::DocumentInterfaceBroker* interface_broker = + GetDocumentInterfaceBroker(web_frame); if (interface_broker) { interface_broker->RegisterAppCacheHost( mojo::MakeRequest(&backend_host_, std::move(task_runner)), @@ -80,27 +78,26 @@ return; } - static const base::NoDestructor<blink::mojom::AppCacheBackendPtr> backend_ptr( - [] { - blink::mojom::AppCacheBackendPtr result; - RenderThread::Get()->GetConnector()->BindInterface( - mojom::kBrowserServiceName, mojo::MakeRequest(&result)); + DEFINE_STATIC_LOCAL( + const mojom::blink::AppCacheBackendPtr, backend_ptr, ([] { + mojom::blink::AppCacheBackendPtr result; + Platform::Current()->GetInterfaceProvider()->GetInterface( + mojo::MakeRequest(&result)); return result; - }()); + }())); // Once we have 'WebContextInterfaceBroker', we can call this function through // it like render frame. // Refer to the design document, 'https://bit.ly/2GT0rZv'. - backend_ptr->get()->RegisterHost( + backend_ptr.get()->RegisterHost( mojo::MakeRequest(&backend_host_, std::move(task_runner)), std::move(frontend_ptr), host_id_); } -WebApplicationCacheHostImpl::~WebApplicationCacheHostImpl() { -} +WebApplicationCacheHostImpl::~WebApplicationCacheHostImpl() = default; void WebApplicationCacheHostImpl::CacheSelected( - blink::mojom::AppCacheInfoPtr info) { + mojom::blink::AppCacheInfoPtr info) { cache_info_ = *info; client_->DidChangeCacheAssociation(); if (select_cache_for_shared_worker_completion_callback_) @@ -108,37 +105,37 @@ } void WebApplicationCacheHostImpl::EventRaised( - blink::mojom::AppCacheEventID event_id) { + mojom::blink::AppCacheEventID event_id) { DCHECK_NE(event_id, - blink::mojom::AppCacheEventID:: + mojom::blink::AppCacheEventID:: APPCACHE_PROGRESS_EVENT); // See OnProgressEventRaised. DCHECK_NE(event_id, - blink::mojom::AppCacheEventID:: + mojom::blink::AppCacheEventID:: APPCACHE_ERROR_EVENT); // See OnErrorEventRaised. // Emit logging output prior to calling out to script as we can get // deleted within the script event handler. const char kFormatString[] = "Application Cache %s event"; - std::string message = base::StringPrintf( - kFormatString, kEventNames[static_cast<int>(event_id)]); - LogMessage(blink::mojom::ConsoleMessageLevel::kInfo, message); + String message = + String::Format(kFormatString, kEventNames[static_cast<int>(event_id)]); + LogMessage(mojom::blink::ConsoleMessageLevel::kInfo, message); switch (event_id) { - case blink::mojom::AppCacheEventID::APPCACHE_CHECKING_EVENT: - status_ = blink::mojom::AppCacheStatus::APPCACHE_STATUS_CHECKING; + case mojom::blink::AppCacheEventID::APPCACHE_CHECKING_EVENT: + status_ = mojom::blink::AppCacheStatus::APPCACHE_STATUS_CHECKING; break; - case blink::mojom::AppCacheEventID::APPCACHE_DOWNLOADING_EVENT: - status_ = blink::mojom::AppCacheStatus::APPCACHE_STATUS_DOWNLOADING; + case mojom::blink::AppCacheEventID::APPCACHE_DOWNLOADING_EVENT: + status_ = mojom::blink::AppCacheStatus::APPCACHE_STATUS_DOWNLOADING; break; - case blink::mojom::AppCacheEventID::APPCACHE_UPDATE_READY_EVENT: - status_ = blink::mojom::AppCacheStatus::APPCACHE_STATUS_UPDATE_READY; + case mojom::blink::AppCacheEventID::APPCACHE_UPDATE_READY_EVENT: + status_ = mojom::blink::AppCacheStatus::APPCACHE_STATUS_UPDATE_READY; break; - case blink::mojom::AppCacheEventID::APPCACHE_CACHED_EVENT: - case blink::mojom::AppCacheEventID::APPCACHE_NO_UPDATE_EVENT: - status_ = blink::mojom::AppCacheStatus::APPCACHE_STATUS_IDLE; + case mojom::blink::AppCacheEventID::APPCACHE_CACHED_EVENT: + case mojom::blink::AppCacheEventID::APPCACHE_NO_UPDATE_EVENT: + status_ = mojom::blink::AppCacheStatus::APPCACHE_STATUS_IDLE; break; - case blink::mojom::AppCacheEventID::APPCACHE_OBSOLETE_EVENT: - status_ = blink::mojom::AppCacheStatus::APPCACHE_STATUS_OBSOLETE; + case mojom::blink::AppCacheEventID::APPCACHE_OBSOLETE_EVENT: + status_ = mojom::blink::AppCacheStatus::APPCACHE_STATUS_OBSOLETE; break; default: NOTREACHED(); @@ -148,59 +145,57 @@ client_->NotifyEventListener(event_id); } -void WebApplicationCacheHostImpl::ProgressEventRaised(const GURL& url, +void WebApplicationCacheHostImpl::ProgressEventRaised(const KURL& url, int num_total, int num_complete) { // Emit logging output prior to calling out to script as we can get // deleted within the script event handler. const char kFormatString[] = "Application Cache Progress event (%d of %d) %s"; - std::string message = base::StringPrintf(kFormatString, num_complete, - num_total, url.spec().c_str()); - LogMessage(blink::mojom::ConsoleMessageLevel::kInfo, message); - status_ = blink::mojom::AppCacheStatus::APPCACHE_STATUS_DOWNLOADING; + String message = String::Format(kFormatString, num_complete, num_total, + url.GetString().Utf8().data()); + LogMessage(mojom::blink::ConsoleMessageLevel::kInfo, message); + status_ = mojom::blink::AppCacheStatus::APPCACHE_STATUS_DOWNLOADING; client_->NotifyProgressEventListener(url, num_total, num_complete); } void WebApplicationCacheHostImpl::ErrorEventRaised( - blink::mojom::AppCacheErrorDetailsPtr details) { + mojom::blink::AppCacheErrorDetailsPtr details) { // Emit logging output prior to calling out to script as we can get // deleted within the script event handler. const char kFormatString[] = "Application Cache Error event: %s"; - std::string full_message = - base::StringPrintf(kFormatString, details->message.c_str()); - LogMessage(blink::mojom::ConsoleMessageLevel::kError, full_message); + String full_message = + String::Format(kFormatString, details->message.Utf8().data()); + LogMessage(mojom::blink::ConsoleMessageLevel::kError, full_message); status_ = cache_info_.is_complete - ? blink::mojom::AppCacheStatus::APPCACHE_STATUS_IDLE - : blink::mojom::AppCacheStatus::APPCACHE_STATUS_UNCACHED; + ? mojom::blink::AppCacheStatus::APPCACHE_STATUS_IDLE + : mojom::blink::AppCacheStatus::APPCACHE_STATUS_UNCACHED; if (details->is_cross_origin) { // Don't leak detailed information to script for cross-origin resources. - DCHECK_EQ(blink::mojom::AppCacheErrorReason::APPCACHE_RESOURCE_ERROR, + DCHECK_EQ(mojom::blink::AppCacheErrorReason::APPCACHE_RESOURCE_ERROR, details->reason); client_->NotifyErrorEventListener(details->reason, details->url, 0, WebString()); } else { client_->NotifyErrorEventListener(details->reason, details->url, - details->status, - WebString::FromUTF8(details->message)); + details->status, details->message); } } void WebApplicationCacheHostImpl::WillStartMainResourceRequest( const WebURL& url, - const WebString& method_webstring, + const String& method, const WebApplicationCacheHost* spawning_host) { original_main_resource_url_ = ClearUrlRef(url); - std::string method = method_webstring.Utf8(); is_get_method_ = (method == kHttpGETMethod); - DCHECK(method == base::ToUpperASCII(method)); + DCHECK(method == method.UpperASCII()); const WebApplicationCacheHostImpl* spawning_host_impl = static_cast<const WebApplicationCacheHostImpl*>(spawning_host); if (spawning_host_impl && (spawning_host_impl != this) && (spawning_host_impl->status_ != - blink::mojom::AppCacheStatus::APPCACHE_STATUS_UNCACHED)) { + mojom::blink::AppCacheStatus::APPCACHE_STATUS_UNCACHED)) { backend_host_->SetSpawningHostId(spawning_host_impl->host_id()); } } @@ -211,12 +206,12 @@ was_select_cache_called_ = true; status_ = - (document_response_.AppCacheID() == blink::mojom::kAppCacheNoCacheId) - ? blink::mojom::AppCacheStatus::APPCACHE_STATUS_UNCACHED - : blink::mojom::AppCacheStatus::APPCACHE_STATUS_CHECKING; + (document_response_.AppCacheID() == mojom::blink::kAppCacheNoCacheId) + ? mojom::blink::AppCacheStatus::APPCACHE_STATUS_UNCACHED + : mojom::blink::AppCacheStatus::APPCACHE_STATUS_CHECKING; is_new_master_entry_ = OLD_ENTRY; backend_host_->SelectCache(document_url_, document_response_.AppCacheID(), - GURL()); + KURL()); } bool WebApplicationCacheHostImpl::SelectCacheWithManifest( @@ -225,22 +220,22 @@ return true; was_select_cache_called_ = true; - GURL manifest_gurl(ClearUrlRef(manifest_url)); + KURL manifest_kurl(ClearUrlRef(manifest_url)); // 6.9.6 The application cache selection algorithm // Check for new 'master' entries. - if (document_response_.AppCacheID() == blink::mojom::kAppCacheNoCacheId) { + if (document_response_.AppCacheID() == mojom::blink::kAppCacheNoCacheId) { if (is_scheme_supported_ && is_get_method_ && - (manifest_gurl.GetOrigin() == document_url_.GetOrigin())) { - status_ = blink::mojom::AppCacheStatus::APPCACHE_STATUS_CHECKING; + SecurityOrigin::AreSameSchemeHostPort(manifest_kurl, document_url_)) { + status_ = mojom::blink::AppCacheStatus::APPCACHE_STATUS_CHECKING; is_new_master_entry_ = NEW_ENTRY; } else { - status_ = blink::mojom::AppCacheStatus::APPCACHE_STATUS_UNCACHED; + status_ = mojom::blink::AppCacheStatus::APPCACHE_STATUS_UNCACHED; is_new_master_entry_ = OLD_ENTRY; - manifest_gurl = GURL(); + manifest_kurl = KURL(); } - backend_host_->SelectCache(document_url_, blink::mojom::kAppCacheNoCacheId, - manifest_gurl); + backend_host_->SelectCache(document_url_, mojom::blink::kAppCacheNoCacheId, + manifest_kurl); return true; } @@ -248,19 +243,19 @@ // 6.9.6 The application cache selection algorithm // Check for 'foreign' entries. - GURL document_manifest_gurl(document_response_.AppCacheManifestURL()); - if (document_manifest_gurl != manifest_gurl) { + KURL document_manifest_kurl(document_response_.AppCacheManifestURL()); + if (document_manifest_kurl != manifest_kurl) { backend_host_->MarkAsForeignEntry(document_url_, document_response_.AppCacheID()); - status_ = blink::mojom::AppCacheStatus::APPCACHE_STATUS_UNCACHED; + status_ = mojom::blink::AppCacheStatus::APPCACHE_STATUS_UNCACHED; return false; // the navigation will be restarted } - status_ = blink::mojom::AppCacheStatus::APPCACHE_STATUS_CHECKING; + status_ = mojom::blink::AppCacheStatus::APPCACHE_STATUS_CHECKING; - // Its a 'master' entry thats already in the cache. + // It's a 'master' entry that's already in the cache. backend_host_->SelectCache(document_url_, document_response_.AppCacheID(), - manifest_gurl); + manifest_kurl); return true; } @@ -270,15 +265,16 @@ document_url_ = ClearUrlRef(document_response_.CurrentRequestUrl()); if (document_url_ != original_main_resource_url_) is_get_method_ = true; // A redirect was involved. - original_main_resource_url_ = GURL(); + original_main_resource_url_ = KURL(); - is_scheme_supported_ = IsSchemeSupportedForAppCache(document_url_); - if ((document_response_.AppCacheID() != blink::mojom::kAppCacheNoCacheId) || + is_scheme_supported_ = + Platform::Current()->IsURLSupportedForAppCache(document_url_); + if ((document_response_.AppCacheID() != mojom::blink::kAppCacheNoCacheId) || !is_scheme_supported_ || !is_get_method_) is_new_master_entry_ = OLD_ENTRY; } -blink::mojom::AppCacheStatus WebApplicationCacheHostImpl::GetStatus() { +mojom::blink::AppCacheStatus WebApplicationCacheHostImpl::GetStatus() { return status_; } @@ -287,11 +283,11 @@ backend_host_->StartUpdate(&result); if (!result) return false; - if (status_ == blink::mojom::AppCacheStatus::APPCACHE_STATUS_IDLE || - status_ == blink::mojom::AppCacheStatus::APPCACHE_STATUS_UPDATE_READY) { - status_ = blink::mojom::AppCacheStatus::APPCACHE_STATUS_CHECKING; + if (status_ == mojom::blink::AppCacheStatus::APPCACHE_STATUS_IDLE || + status_ == mojom::blink::AppCacheStatus::APPCACHE_STATUS_UPDATE_READY) { + status_ = mojom::blink::AppCacheStatus::APPCACHE_STATUS_CHECKING; } else { - status_ = blink::mojom::AppCacheStatus::APPCACHE_STATUS_UNCACHED; + status_ = mojom::blink::AppCacheStatus::APPCACHE_STATUS_UNCACHED; backend_host_->GetStatus(&status_); } return true; @@ -325,9 +321,9 @@ WebVector<ResourceInfo>* resources) { if (!cache_info_.is_complete) return; - std::vector<blink::mojom::AppCacheResourceInfoPtr> boxed_infos; + Vector<mojom::blink::AppCacheResourceInfoPtr> boxed_infos; backend_host_->GetResourceList(&boxed_infos); - std::vector<blink::mojom::AppCacheResourceInfo> resource_infos; + Vector<mojom::blink::AppCacheResourceInfo> resource_infos; for (auto& b : boxed_infos) { resource_infos.emplace_back(std::move(*b)); } @@ -347,11 +343,11 @@ } void WebApplicationCacheHostImpl::SelectCacheForSharedWorker( - long long app_cache_id, + int64_t app_cache_id, base::OnceClosure completion_callback) { select_cache_for_shared_worker_completion_callback_ = std::move(completion_callback); backend_host_->SelectCacheForSharedWorker(app_cache_id); } -} // namespace content +} // namespace blink
diff --git a/third_party/blink/renderer/core/exported/web_application_cache_host_impl.h b/third_party/blink/renderer/core/exported/web_application_cache_host_impl.h new file mode 100644 index 0000000..16bc58e --- /dev/null +++ b/third_party/blink/renderer/core/exported/web_application_cache_host_impl.h
@@ -0,0 +1,84 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_APPLICATION_CACHE_HOST_IMPL_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_APPLICATION_CACHE_HOST_IMPL_H_ + +#include "mojo/public/cpp/bindings/binding.h" +#include "third_party/blink/public/mojom/appcache/appcache.mojom-blink.h" +#include "third_party/blink/public/mojom/appcache/appcache_info.mojom-blink.h" +#include "third_party/blink/public/mojom/devtools/console_message.mojom-blink.h" +#include "third_party/blink/public/platform/web_url_response.h" +#include "third_party/blink/public/platform/web_vector.h" +#include "third_party/blink/public/web/web_application_cache_host.h" +#include "third_party/blink/renderer/platform/weborigin/kurl.h" + +namespace blink { + +class WebApplicationCacheHostClient; + +class WebApplicationCacheHostImpl : public WebApplicationCacheHost, + public mojom::blink::AppCacheFrontend { + public: + WebApplicationCacheHostImpl( + // |web_frame| is used for accessing to DocumentInterfaceBroker. As it's + // not used for workers, |web_frame| is null for workers. + WebLocalFrame* web_frame, + WebApplicationCacheHostClient* client, + const base::UnguessableToken& appcache_host_id, + scoped_refptr<base::SingleThreadTaskRunner> task_runner); + ~WebApplicationCacheHostImpl() override; + + const base::UnguessableToken& host_id() const { return host_id_; } + WebApplicationCacheHostClient* client() const { return client_; } + + // mojom::blink::AppCacheFrontend + void CacheSelected(mojom::blink::AppCacheInfoPtr info) override; + void EventRaised(mojom::blink::AppCacheEventID event_id) override; + void ProgressEventRaised(const KURL& url, + int32_t num_total, + int32_t num_complete) override; + void ErrorEventRaised(mojom::blink::AppCacheErrorDetailsPtr details) override; + + // WebApplicationCacheHost: + void WillStartMainResourceRequest( + const WebURL& url, + const String& method, + const WebApplicationCacheHost* spawning_host) override; + void SelectCacheWithoutManifest() override; + bool SelectCacheWithManifest(const WebURL& manifestURL) override; + void DidReceiveResponseForMainResource(const WebURLResponse&) override; + mojom::blink::AppCacheStatus GetStatus() override; + bool StartUpdate() override; + bool SwapCache() override; + void GetResourceList(WebVector<ResourceInfo>* resources) override; + void GetAssociatedCacheInfo(CacheInfo* info) override; + const base::UnguessableToken& GetHostID() const override; + void SelectCacheForSharedWorker( + int64_t app_cache_id, + base::OnceClosure completion_callback) override; + + private: + enum IsNewMasterEntry { MAYBE_NEW_ENTRY, NEW_ENTRY, OLD_ENTRY }; + + mojo::Binding<mojom::blink::AppCacheFrontend> binding_; + WebApplicationCacheHostClient* client_; + mojom::blink::AppCacheHostPtr backend_host_; + base::UnguessableToken host_id_; + mojom::blink::AppCacheStatus status_; + WebURLResponse document_response_; + KURL document_url_; + bool is_scheme_supported_; + bool is_get_method_; + IsNewMasterEntry is_new_master_entry_; + mojom::blink::AppCacheInfo cache_info_; + KURL original_main_resource_url_; // Used to detect redirection. + bool was_select_cache_called_; + // Invoked when CacheSelected() is called. + base::OnceClosure select_cache_for_shared_worker_completion_callback_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_APPLICATION_CACHE_HOST_IMPL_H_
diff --git a/third_party/blink/renderer/core/exported/web_frame_test.cc b/third_party/blink/renderer/core/exported/web_frame_test.cc index 1d63ddc9..a2b59917 100644 --- a/third_party/blink/renderer/core/exported/web_frame_test.cc +++ b/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -12409,7 +12409,8 @@ TestWebFrameClient::BeginNavigation(std::move(info)); return; } - Frame()->WillStartNavigation(*info); + Frame()->WillStartNavigation( + *info, false /* is_history_navigation_in_new_child_frame */); } private:
diff --git a/third_party/blink/renderer/core/exported/web_view_test.cc b/third_party/blink/renderer/core/exported/web_view_test.cc index 6059a3c2..5b8c8e21 100644 --- a/third_party/blink/renderer/core/exported/web_view_test.cc +++ b/third_party/blink/renderer/core/exported/web_view_test.cc
@@ -551,6 +551,34 @@ EXPECT_TRUE(GreenChannel(color)); } +TEST_F(WebViewTest, SetBaseBackgroundColorWithColorScheme) { + ScopedCSSColorSchemeForTest enable_color_scheme(true); + + WebViewImpl* web_view = web_view_helper_.Initialize(); + web_view->SettingsImpl()->SetPreferredColorScheme( + PreferredColorScheme::kLight); + web_view->SetBaseBackgroundColor(SK_ColorBLUE); + + WebURL base_url = url_test_helpers::ToKURL("http://example.com/"); + frame_test_helpers::LoadHTMLString( + web_view->MainFrameImpl(), + "<style>:root { color-scheme: light dark }<style>", base_url); + UpdateAllLifecyclePhases(); + + LocalFrameView* frame_view = web_view->MainFrameImpl()->GetFrame()->View(); + EXPECT_EQ(Color(0, 0, 255), frame_view->BaseBackgroundColor()); + + web_view->SettingsImpl()->SetPreferredColorScheme( + PreferredColorScheme::kDark); + UpdateAllLifecyclePhases(); + EXPECT_EQ(Color::kBlack, frame_view->BaseBackgroundColor()); + + web_view->SettingsImpl()->SetPreferredColorScheme( + PreferredColorScheme::kLight); + UpdateAllLifecyclePhases(); + EXPECT_EQ(Color(0, 0, 255), frame_view->BaseBackgroundColor()); +} + TEST_F(WebViewTest, FocusIsInactive) { RegisterMockedHttpURLLoad("visible_iframe.html"); WebViewImpl* web_view =
diff --git a/third_party/blink/renderer/core/fetch/fetch_manager.cc b/third_party/blink/renderer/core/fetch/fetch_manager.cc index 0b8b34d..f4775378 100644 --- a/third_party/blink/renderer/core/fetch/fetch_manager.cc +++ b/third_party/blink/renderer/core/fetch/fetch_manager.cc
@@ -23,6 +23,7 @@ #include "third_party/blink/renderer/core/fileapi/blob.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" #include "third_party/blink/renderer/core/frame/frame.h" +#include "third_party/blink/renderer/core/frame/use_counter.h" #include "third_party/blink/renderer/core/inspector/console_message.h" #include "third_party/blink/renderer/core/loader/subresource_integrity_helper.h" #include "third_party/blink/renderer/core/loader/threadable_loader.h" @@ -746,6 +747,7 @@ return; } request.SetKeepalive(true); + UseCounter::Count(execution_context_, mojom::WebFeature::kFetchKeepalive); } // "3. Append `Host`, ..."
diff --git a/third_party/blink/renderer/core/frame/deprecation.cc b/third_party/blink/renderer/core/frame/deprecation.cc index 7ed7364..248766530 100644 --- a/third_party/blink/renderer/core/frame/deprecation.cc +++ b/third_party/blink/renderer/core/frame/deprecation.cc
@@ -19,7 +19,6 @@ #include "third_party/blink/renderer/core/frame/reporting_context.h" #include "third_party/blink/renderer/core/inspector/console_message.h" #include "third_party/blink/renderer/core/loader/document_loader.h" -#include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" @@ -659,37 +658,7 @@ if (!context) return; - // TODO(yoichio): We should remove these counters when v0 APIs are removed. - // crbug.com/946875. - if (const OriginTrialContext* origin_trial_context = - OriginTrialContext::FromOrCreate(context)) { - if (feature == WebFeature::kHTMLImports && - origin_trial_context->IsFeatureEnabled( - OriginTrialFeature::kHTMLImports) && - !RuntimeEnabledFeatures::HTMLImportsEnabledByRuntimeFlag()) { - UseCounter::Count(context, WebFeature::kHTMLImportsOnReverseOriginTrials); - } else if (feature == WebFeature::kElementCreateShadowRoot && - origin_trial_context->IsFeatureEnabled( - OriginTrialFeature::kShadowDOMV0) && - !RuntimeEnabledFeatures::ShadowDOMV0EnabledByRuntimeFlag()) { - UseCounter::Count( - context, WebFeature::kElementCreateShadowRootOnReverseOriginTrials); - } else if (feature == WebFeature::kDocumentRegisterElement && - origin_trial_context->IsFeatureEnabled( - OriginTrialFeature::kCustomElementsV0) && - !RuntimeEnabledFeatures:: - CustomElementsV0EnabledByRuntimeFlag()) { - UseCounter::Count( - context, WebFeature::kDocumentRegisterElementOnReverseOriginTrials); - } - } - // TODO(dcheng): Maybe this should be a virtual on ExecutionContext? - if (auto* document = DynamicTo<Document>(context)) { - Deprecation::CountDeprecation(*document, feature); - return; - } - if (auto* scope = DynamicTo<WorkerOrWorkletGlobalScope>(context)) - scope->CountDeprecation(feature); + context->CountDeprecation(feature); } void Deprecation::CountDeprecation(const Document& document,
diff --git a/third_party/blink/renderer/core/frame/frame_test_helpers.cc b/third_party/blink/renderer/core/frame/frame_test_helpers.cc index b63c2cbe..73ed8b6 100644 --- a/third_party/blink/renderer/core/frame/frame_test_helpers.cc +++ b/third_party/blink/renderer/core/frame/frame_test_helpers.cc
@@ -538,7 +538,8 @@ return; } - if (!frame_->WillStartNavigation(*info)) + if (!frame_->WillStartNavigation( + *info, false /* is_history_navigation_in_new_child_frame */)) return; navigation_callback_.Reset(
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 15d43f4..7532d62 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -1651,6 +1651,8 @@ } Color LocalFrameView::BaseBackgroundColor() const { + if (use_dark_scheme_background_) + return Color::kBlack; return base_background_color_; } @@ -1659,7 +1661,6 @@ return; base_background_color_ = background_color; - if (auto* layout_view = GetLayoutView()) { if (layout_view->Layer()->HasCompositedLayerMapping()) { CompositedLayerMapping* composited_layer_mapping = @@ -1676,6 +1677,15 @@ GetPage()->Animator().ScheduleVisualUpdate(frame_.Get()); } +void LocalFrameView::SetUseDarkSchemeBackground(bool dark_scheme) { + if (use_dark_scheme_background_ == dark_scheme) + return; + + use_dark_scheme_background_ = dark_scheme; + if (auto* layout_view = GetLayoutView()) + layout_view->SetBackgroundNeedsFullPaintInvalidation(); +} + void LocalFrameView::UpdateBaseBackgroundColorRecursively( const Color& base_background_color) { ForAllNonThrottledLocalFrameViews(
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.h b/third_party/blink/renderer/core/frame/local_frame_view.h index a7250be..32c24ac 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.h +++ b/third_party/blink/renderer/core/frame/local_frame_view.h
@@ -245,6 +245,7 @@ Color BaseBackgroundColor() const; void SetBaseBackgroundColor(const Color&); void UpdateBaseBackgroundColorRecursively(const Color&); + void SetUseDarkSchemeBackground(bool dark_scheme); void AdjustViewSize(); void AdjustViewSizeAndLayout(); @@ -871,6 +872,7 @@ TaskRunnerTimer<LocalFrameView> update_plugins_timer_; bool first_layout_; + bool use_dark_scheme_background_ = false; Color base_background_color_; IntSize last_viewport_size_; float last_zoom_factor_;
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc index 88bb36db..b12520b 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -2190,10 +2190,17 @@ GetFrame()->Loader().MarkAsLoading(); } -bool WebLocalFrameImpl::WillStartNavigation(const WebNavigationInfo& info) { +bool WebLocalFrameImpl::IsClientNavigationInitialHistoryLoad() { + return GetFrame()->Loader().IsClientNavigationInitialHistoryLoad(); +} + +bool WebLocalFrameImpl::WillStartNavigation( + const WebNavigationInfo& info, + bool is_history_navigation_in_new_child_frame) { DCHECK(!info.url_request.IsNull()); DCHECK(!info.url_request.Url().ProtocolIs("javascript")); - return GetFrame()->Loader().WillStartNavigation(info); + return GetFrame()->Loader().WillStartNavigation( + info, is_history_navigation_in_new_child_frame); } void WebLocalFrameImpl::SendOrientationChangeEvent() {
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/third_party/blink/renderer/core/frame/web_local_frame_impl.h index 3db1bec..b503bf7 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.h +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
@@ -332,7 +332,10 @@ bool HasCommittedFirstRealLoad() override; void DidDropNavigation() override; void MarkAsLoading() override; - bool WillStartNavigation(const WebNavigationInfo&) override; + bool IsClientNavigationInitialHistoryLoad() override; + bool WillStartNavigation( + const WebNavigationInfo&, + bool is_history_navigation_in_new_child_frame) override; void SetLifecycleState(mojom::FrameLifecycleState state) override; void WasHidden() override;
diff --git a/third_party/blink/renderer/core/html/html_image_element.cc b/third_party/blink/renderer/core/html/html_image_element.cc index b47fb7d..5941d76 100644 --- a/third_party/blink/renderer/core/html/html_image_element.cc +++ b/third_party/blink/renderer/core/html/html_image_element.cc
@@ -745,9 +745,17 @@ FastGetAttribute(kSrcAttr), FastGetAttribute(kSrcsetAttr), &GetDocument()); } + AtomicString old_url = best_fit_image_url_; SetBestFitURLAndDPRFromImageCandidate(candidate); - GetImageLoader().UpdateFromElement(behavior, referrer_policy_); + // Step 5 in + // https://html.spec.whatwg.org/multipage/images.html#reacting-to-environment-changes + // Deliberately not compliant and avoiding checking image density, to avoid + // spurious downloads. See https://github.com/whatwg/html/issues/4646 + if (behavior != HTMLImageLoader::kUpdateSizeChanged || + best_fit_image_url_ != old_url) { + GetImageLoader().UpdateFromElement(behavior, referrer_policy_); + } ImageResourceContent* image_content = GetImageLoader().GetContent(); // Images such as data: uri's can return immediately and may already have
diff --git a/third_party/blink/renderer/core/layout/layout_block_flow.cc b/third_party/blink/renderer/core/layout/layout_block_flow.cc index a5b4fd7..b92892fd 100644 --- a/third_party/blink/renderer/core/layout/layout_block_flow.cc +++ b/third_party/blink/renderer/core/layout/layout_block_flow.cc
@@ -385,7 +385,7 @@ ToElement(GetNode())->ShadowPseudoId() == "-webkit-input-placeholder")); - if (LogicalHeight() > LayoutUnit() || BorderAndPaddingLogicalHeight() || + if (LogicalHeight() > LayoutUnit() || StyleRef().LogicalMinHeight().IsPositive() || StyleRef().MarginBeforeCollapse() == EMarginCollapse::kSeparate || StyleRef().MarginAfterCollapse() == EMarginCollapse::kSeparate)
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc index 9e36e92..79ab401 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc
@@ -442,9 +442,13 @@ LayoutBlockFlow* layout_block_flow) { DCHECK(!layout_block_flow->GetDocument().NeedsLayoutTreeUpdate()); - // TODO(crbug.com/962129): Fix the root cause of the missing layout, and turn - // this into a DCHECK. - CHECK(!layout_block_flow->NeedsLayout()) << layout_block_flow; + if (UNLIKELY(layout_block_flow->NeedsLayout())) { + // TODO(kojii): This shouldn't happen, but is not easy to fix all cases. + // Return nullptr so that callers can chose to fail gracefully, or + // null-deref. crbug.com/946004 + NOTREACHED(); + return nullptr; + } // If |layout_block_flow| is LayoutNG, compute from |NGInlineNode|. if (layout_block_flow->IsLayoutNGMixin()) {
diff --git a/third_party/blink/renderer/core/loader/appcache/application_cache_host.cc b/third_party/blink/renderer/core/loader/appcache/application_cache_host.cc index d2cb2e1..6ca47a2 100644 --- a/third_party/blink/renderer/core/loader/appcache/application_cache_host.cc +++ b/third_party/blink/renderer/core/loader/appcache/application_cache_host.cc
@@ -32,13 +32,12 @@ #include "third_party/blink/public/mojom/appcache/appcache.mojom-blink.h" #include "third_party/blink/public/mojom/appcache/appcache_info.mojom-blink.h" -#include "third_party/blink/public/mojom/loader/request_context_frame_type.mojom-blink.h" -#include "third_party/blink/public/platform/web_application_cache_host.h" #include "third_party/blink/public/platform/web_url.h" #include "third_party/blink/public/platform/web_url_error.h" #include "third_party/blink/public/platform/web_url_request.h" #include "third_party/blink/public/platform/web_url_response.h" #include "third_party/blink/public/platform/web_vector.h" +#include "third_party/blink/public/web/web_application_cache_host.h" #include "third_party/blink/renderer/core/events/application_cache_error_event.h" #include "third_party/blink/renderer/core/events/progress_event.h" #include "third_party/blink/renderer/core/frame/deprecation.h"
diff --git a/third_party/blink/renderer/core/loader/appcache/application_cache_host.h b/third_party/blink/renderer/core/loader/appcache/application_cache_host.h index 04688c88..c66d160 100644 --- a/third_party/blink/renderer/core/loader/appcache/application_cache_host.h +++ b/third_party/blink/renderer/core/loader/appcache/application_cache_host.h
@@ -36,7 +36,7 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "third_party/blink/public/mojom/appcache/appcache.mojom-blink.h" -#include "third_party/blink/public/platform/web_application_cache_host_client.h" +#include "third_party/blink/public/web/web_application_cache_host_client.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" @@ -48,6 +48,7 @@ class DocumentLoader; class ResourceRequest; class ResourceResponse; +class WebApplicationCacheHost; class CORE_EXPORT ApplicationCacheHost final : public GarbageCollectedFinalized<ApplicationCacheHost>,
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc index 2d51c91..a20caff 100644 --- a/third_party/blink/renderer/core/loader/document_loader.cc +++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -1701,6 +1701,10 @@ return use_counter_.Count(feature, GetFrame()); } +void DocumentLoader::CountDeprecation(mojom::WebFeature feature) { + return Deprecation::CountDeprecation(this, feature); +} + void DocumentLoader::ReportPreviewsIntervention() const { // Only send reports for main frames. if (!frame_->IsMainFrame())
diff --git a/third_party/blink/renderer/core/loader/document_loader.h b/third_party/blink/renderer/core/loader/document_loader.h index d2e03922..38f73047 100644 --- a/third_party/blink/renderer/core/loader/document_loader.h +++ b/third_party/blink/renderer/core/loader/document_loader.h
@@ -275,6 +275,7 @@ // UseCounter void CountUse(mojom::WebFeature) override; + void CountDeprecation(mojom::WebFeature) override; protected: bool had_transient_activation() const { return had_transient_activation_; }
diff --git a/third_party/blink/renderer/core/loader/empty_clients.cc b/third_party/blink/renderer/core/loader/empty_clients.cc index d01423f3..b7459052 100644 --- a/third_party/blink/renderer/core/loader/empty_clients.cc +++ b/third_party/blink/renderer/core/loader/empty_clients.cc
@@ -32,8 +32,8 @@ #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider.h" #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider_client.h" #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_application_cache_host.h" #include "third_party/blink/public/platform/web_media_player.h" +#include "third_party/blink/public/web/web_application_cache_host.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/visual_viewport.h" #include "third_party/blink/renderer/core/html/forms/color_chooser.h"
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context.cc b/third_party/blink/renderer/core/loader/frame_fetch_context.cc index a833876..9239791 100644 --- a/third_party/blink/renderer/core/loader/frame_fetch_context.cc +++ b/third_party/blink/renderer/core/loader/frame_fetch_context.cc
@@ -42,11 +42,11 @@ #include "third_party/blink/public/mojom/loader/request_context_frame_type.mojom-blink.h" #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h" #include "third_party/blink/public/platform/scheduler/web_scoped_virtual_time_pauser.h" -#include "third_party/blink/public/platform/web_application_cache_host.h" #include "third_party/blink/public/platform/web_content_settings_client.h" #include "third_party/blink/public/platform/web_effective_connection_type.h" #include "third_party/blink/public/platform/web_insecure_request_policy.h" #include "third_party/blink/public/platform/websocket_handshake_throttle.h" +#include "third_party/blink/public/web/web_application_cache_host.h" #include "third_party/blink/public/web/web_frame.h" #include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/public/web/web_local_frame_client.h"
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc index 8ed007d..3a628fe 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.cc +++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -958,7 +958,8 @@ TakeObjectSnapshot(); } -bool FrameLoader::WillStartNavigation(const WebNavigationInfo& info) { +bool FrameLoader::WillStartNavigation(const WebNavigationInfo& info, + bool is_history_navigation_in_new_frame) { if (!CancelProvisionalLoaderForNewNavigation(!info.form.IsNull())) return false; @@ -966,6 +967,8 @@ client_navigation_ = std::make_unique<ClientNavigationState>(); client_navigation_->url = info.url_request.Url(); client_navigation_->http_method = info.url_request.HttpMethod(); + client_navigation_->is_history_navigation_in_new_frame = + is_history_navigation_in_new_frame; frame_->GetFrameScheduler()->DidStartProvisionalLoad(frame_->IsMainFrame()); probe::DidStartProvisionalLoad(frame_); virtual_time_pauser_.PauseVirtualTime(); @@ -1575,6 +1578,11 @@ ToTracedValue()); } +bool FrameLoader::IsClientNavigationInitialHistoryLoad() { + return client_navigation_ && + client_navigation_->is_history_navigation_in_new_frame; +} + STATIC_ASSERT_ENUM(kWebHistoryScrollRestorationManual, kScrollRestorationManual); STATIC_ASSERT_ENUM(kWebHistoryScrollRestorationAuto, kScrollRestorationAuto);
diff --git a/third_party/blink/renderer/core/loader/frame_loader.h b/third_party/blink/renderer/core/loader/frame_loader.h index ab41fa9e..9b9fc92 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.h +++ b/third_party/blink/renderer/core/loader/frame_loader.h
@@ -104,7 +104,8 @@ // Called before the browser process is asked to navigate this frame, to mark // the frame as loading and save some navigation information for later use. - bool WillStartNavigation(const WebNavigationInfo&); + bool WillStartNavigation(const WebNavigationInfo& info, + bool is_history_navigation_in_new_frame); // This runs the "stop document loading" algorithm in HTML: // https://html.spec.whatwg.org/C/browsing-the-web.html#stop-document-loading @@ -214,6 +215,8 @@ bool ShouldReuseDefaultView(const scoped_refptr<const SecurityOrigin>&, const ContentSecurityPolicy*); + bool IsClientNavigationInitialHistoryLoad(); + private: bool AllowRequestForThisFrame(const FrameLoadRequest&); WebFrameLoadType DetermineFrameLoadType(const KURL& url, @@ -272,6 +275,7 @@ struct ClientNavigationState { KURL url; AtomicString http_method; + bool is_history_navigation_in_new_frame = false; }; std::unique_ptr<ClientNavigationState> client_navigation_;
diff --git a/third_party/blink/renderer/core/script/script_runner.cc b/third_party/blink/renderer/core/script/script_runner.cc index a82cb82..6e76a64 100644 --- a/third_party/blink/renderer/core/script/script_runner.cc +++ b/third_party/blink/renderer/core/script/script_runner.cc
@@ -47,12 +47,10 @@ void ScriptRunner::QueueScriptForExecution(PendingScript* pending_script) { DCHECK(pending_script); document_->IncrementLoadEventDelayCount(); + pending_script->StartStreamingIfPossible(); switch (pending_script->GetSchedulingType()) { case ScriptSchedulingType::kAsync: pending_async_scripts_.insert(pending_script); - if (!is_suspended_) { - pending_script->StartStreamingIfPossible(); - } break; case ScriptSchedulingType::kInOrder:
diff --git a/third_party/blink/renderer/core/testing/null_execution_context.h b/third_party/blink/renderer/core/testing/null_execution_context.h index 9ecfd11..ab785d7 100644 --- a/third_party/blink/renderer/core/testing/null_execution_context.h +++ b/third_party/blink/renderer/core/testing/null_execution_context.h
@@ -66,6 +66,7 @@ scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(TaskType) override; void CountUse(mojom::WebFeature) override {} + void CountDeprecation(mojom::WebFeature) override {} using SecurityContext::GetSecurityOrigin; using SecurityContext::GetContentSecurityPolicy;
diff --git a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h index 6e94c0b..776089b 100644 --- a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h +++ b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h
@@ -76,9 +76,6 @@ // SecurityContext void DidUpdateSecurityOrigin() final {} - // UseCounter - void CountUse(WebFeature feature) final { CountFeature(feature); } - // Returns true when the WorkerOrWorkletGlobalScope is closing (e.g. via // WorkerGlobalScope#close() method). If this returns true, the worker is // going to be shutdown after the current task execution. Globals that @@ -95,9 +92,9 @@ // TODO(yhirano): Unify this with CountUse. void CountFeature(WebFeature); - // Called from UseCounter to record deprecated API use in this execution - // context. - void CountDeprecation(WebFeature); + // UseCounter + void CountUse(WebFeature feature) final { CountFeature(feature); } + void CountDeprecation(WebFeature) final; // May return nullptr if this global scope is not threaded (i.e., // WorkletGlobalScope for the main thread) or after Dispose() is called.
diff --git a/third_party/blink/renderer/modules/device_orientation/device_motion_controller.cc b/third_party/blink/renderer/modules/device_orientation/device_motion_controller.cc index ec9f9a0..e41374b 100644 --- a/third_party/blink/renderer/modules/device_orientation/device_motion_controller.cc +++ b/third_party/blink/renderer/modules/device_orientation/device_motion_controller.cc
@@ -46,7 +46,8 @@ // TOOD(crbug.com/932078): Investigate if this ever called with no |frame|. LocalFrame* frame = GetDocument().GetFrame(); if (frame) { - SECURITY_CHECK(GetDocument().IsSecureContext()); + if (!GetDocument().IsSecureContext()) + return; UseCounter::Count(GetDocument(), WebFeature::kDeviceMotionSecureOrigin); }
diff --git a/third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.cc b/third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.cc index 629895ed..91aa17c 100644 --- a/third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.cc +++ b/third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.cc
@@ -42,7 +42,8 @@ // TOOD(crbug.com/932078): Investigate if this ever called with no |frame|. LocalFrame* frame = GetDocument().GetFrame(); if (frame) { - SECURITY_CHECK(GetDocument().IsSecureContext()); + if (!GetDocument().IsSecureContext()) + return; UseCounter::Count(GetDocument(), WebFeature::kDeviceOrientationAbsoluteSecureOrigin); }
diff --git a/third_party/blink/renderer/modules/manifest/DEPS b/third_party/blink/renderer/modules/manifest/DEPS index 992e76f..b083bc9 100644 --- a/third_party/blink/renderer/modules/manifest/DEPS +++ b/third_party/blink/renderer/modules/manifest/DEPS
@@ -1,11 +1,6 @@ -# TODO(https://crbug.com/704441) : Added temporarily. include_rules = [ - "+base/json/json_reader.h", - "+base/memory/scoped_refptr.h", + # TODO(https://crbug.com/704441) : Added temporarily. "+base/strings", - "+base/values.h", "+net/base/mime_util.h", - "+ui/gfx/geometry/size.h", - "+url", "+third_party/blink/renderer/core/frame/web_local_frame_impl.h", ]
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc index b2f624dd..6bb3896 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -2899,6 +2899,15 @@ transceiver->receiver()->track()->Component()->Source()->SetReadyState( MediaStreamSource::kReadyStateLive); } + + // Transceiver modifications can cause changes in the set of ICE + // transports, which may affect ICE transport state. + // Note - this must be done every time the set of ICE transports happens. + // At the moment this only happens in SLD/SRD, and this function is called + // whenever these functions complete. + if (sdp_semantics_ == webrtc::SdpSemantics::kUnifiedPlan) { + UpdateIceConnectionState(); + } } void RTCPeerConnection::SetAssociatedMediaStreams(
diff --git a/third_party/blink/renderer/platform/fonts/win/font_unique_name_lookup_win.cc b/third_party/blink/renderer/platform/fonts/win/font_unique_name_lookup_win.cc index 91b57c0..ee12b3df 100644 --- a/third_party/blink/renderer/platform/fonts/win/font_unique_name_lookup_win.cc +++ b/third_party/blink/renderer/platform/fonts/win/font_unique_name_lookup_win.cc
@@ -160,6 +160,8 @@ } void FontUniqueNameLookupWin::EnsureServiceConnected() { + if (service_) + return; Platform::Current()->GetInterfaceProvider()->GetInterface( mojo::MakeRequest(&service_)); } @@ -181,7 +183,7 @@ EnsureServiceConnected(); - service_->GetUniqueNameLookupTable(base::BindRepeating( + service_->GetUniqueNameLookupTable(base::BindOnce( &FontUniqueNameLookupWin::ReceiveReadOnlySharedMemoryRegion, base::Unretained(this))); }
diff --git a/third_party/blink/renderer/platform/instrumentation/use_counter.h b/third_party/blink/renderer/platform/instrumentation/use_counter.h index 591ab8f..cc9e6ec 100644 --- a/third_party/blink/renderer/platform/instrumentation/use_counter.h +++ b/third_party/blink/renderer/platform/instrumentation/use_counter.h
@@ -50,6 +50,10 @@ // Counts a use of the given feature. Repeated calls are ignored. virtual void CountUse(mojom::WebFeature feature) = 0; + // Counts and reports a use of the given (deprecated) feature. Repeated + // calls are ignored. + virtual void CountDeprecation(mojom::WebFeature feature) = 0; + private: DISALLOW_COPY_AND_ASSIGN(UseCounter); };
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py index e996a11..5c0b98b 100755 --- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py +++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
@@ -702,20 +702,13 @@ 'sigslot::.+', ], }, - # TODO(https://crbug.com/704441) : Added temporarily. - { - 'paths': ['third_party/blink/renderer/modules/exported/web_manifest_parser.cc'], - 'allowed': [ - 'base::StringPiece', - 'GURL', - ], - }, { 'paths': ['third_party/blink/renderer/modules/manifest/'], 'allowed': [ + # TODO(https://crbug.com/704441) : Added temporarily. 'base::.+', + 'net::ParseMimeTypeWithoutParameter', - 'GURL', ], } ]
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-features=NetworkService b/third_party/blink/web_tests/FlagExpectations/disable-features=NetworkService index 968a59c..45ec228 100644 --- a/third_party/blink/web_tests/FlagExpectations/disable-features=NetworkService +++ b/third_party/blink/web_tests/FlagExpectations/disable-features=NetworkService
@@ -13,6 +13,7 @@ crbug.com/933880 external/wpt/FileAPI/url/cross-global-revoke.sub.html [ Failure ] crbug.com/933880 external/wpt/FileAPI/url/url-with-fetch.any.html [ Failure ] crbug.com/933880 external/wpt/FileAPI/url/url-with-xhr.any.html [ Failure ] +crbug.com/933880 external/wpt/service-workers/service-worker/fetch-request-xhr.https.html [ Failure ] crbug.com/950412 [ Linux Debug ] http/tests/inspector-protocol/network/request-interception-request-id.js [ Failure ]
diff --git a/third_party/blink/web_tests/animations/web-animations/animation-null-timeline.html b/third_party/blink/web_tests/animations/web-animations/animation-null-timeline.html new file mode 100644 index 0000000..a3ad3f9 --- /dev/null +++ b/third_party/blink/web_tests/animations/web-animations/animation-null-timeline.html
@@ -0,0 +1,38 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Operating on an animation with a null timeline</title> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<body> +<script> +// Ensure that operations on an animation object are well behaved with a +// null timeline. TODO(crbug.com/967416) Consider moving to WPT once edge cases +// for handling of null timelines are fully flushed out. + +// crbug.com/967509 +test(t => { + const effect = new KeyframeEffect(null, null, 1000); + const animation = new Animation(effect, null); + animation.finish(); + assert_equals(animation.startTime, null); + assert_equals(animation.currentTime, 1000); + assert_equals(animation.playState, 'finished'); +}, 'Animation finished with a null timeline'); + +// crbug.com/967507 +test(t => { + const effect = new KeyframeEffect(null, null, 1000); + const animation1 = document.body.animate([], 1000); + assert_true(!!animation1.effect.target); + const animation2 = new Animation(effect, null); + assert_false(!!animation2.effect.target); + animation2.pause(); + animation2.currentTime = 500; + assert_equals(animation2.playState, 'paused'); + assert_equals(animation2.currentTime, 500); + animation1.effect = effect; + assert_false(!!animation1.effect.target); + assert_false(!!animation2.effect); + assert_equals(animation2.playState, 'idle'); +}, 'Set effect with a null timeline'); +</script>
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json index af672bb..bc87669 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
@@ -185249,11 +185249,6 @@ {} ] ], - "mediacapture-streams/MediaStreamTrack-getCapabilities.https-expected.txt": [ - [ - {} - ] - ], "mediacapture-streams/OWNERS": [ [ {} @@ -203574,6 +203569,11 @@ {} ] ], + "wake-lock/wakelock-abortsignal.https.any.worker-expected.txt": [ + [ + {} + ] + ], "wake-lock/wakelock-applicability-manual.https-expected.txt": [ [ {} @@ -317768,10 +317768,28 @@ } ] ], - "wake-lock/wakelock-abortsignal-set.https.html": [ + "wake-lock/wakelock-abortsignal.https.any.js": [ [ - "wake-lock/wakelock-abortsignal-set.https.html", - {} + "wake-lock/wakelock-abortsignal.https.any.html", + { + "script_metadata": [ + [ + "title", + "WakeLock.request() AbortSignal Test" + ] + ] + } + ], + [ + "wake-lock/wakelock-abortsignal.https.any.worker.html", + { + "script_metadata": [ + [ + "title", + "WakeLock.request() AbortSignal Test" + ] + ] + } ] ], "wake-lock/wakelock-active-document.https.window.js": [ @@ -420179,7 +420197,7 @@ "reftest" ], "css/css-values/initial-background-color.html": [ - "f38226651774f9ac2151b9b951f47f519a4663ea", + "7a6c6173c4f6998f56bbcb7f992ad38fca45ce58", "reftest" ], "css/css-values/lh-rlh-on-root-001.html": [ @@ -470411,7 +470429,7 @@ "testharness" ], "mediacapture-streams/MediaDevices-getSupportedConstraints.https.html": [ - "fff4f349e1ccc01481be36c0ab0ff7c174fea681", + "453184a16919a63ea72068538bca4f7c038957cf", "testharness" ], "mediacapture-streams/MediaDevices-getUserMedia.https.html": [ @@ -470502,16 +470520,12 @@ "310d1b050b7032074ddd9250680a4e4540cc9c86", "manual" ], - "mediacapture-streams/MediaStreamTrack-getCapabilities.https-expected.txt": [ - "e7f474c303398f0d34de45d621f6b87dfe4da808", - "support" - ], "mediacapture-streams/MediaStreamTrack-getCapabilities.https.html": [ - "aeb79b500130144ed62eff13caff455e02097e7f", + "23345147744edc79d0dbca3ff8391d667dba7c3f", "testharness" ], "mediacapture-streams/MediaStreamTrack-getSettings.https.html": [ - "c062205f0d4bb6706170c07f0d58d4a63cdb7bca", + "4d51f9dc831efe53fd69eec08fd18a046ede2aa2", "testharness" ], "mediacapture-streams/MediaStreamTrack-id.https.html": [ @@ -494563,7 +494577,7 @@ "testharness" ], "service-workers/service-worker/fetch-request-xhr.https-expected.txt": [ - "44c6a053034ccd646803c60363b9890c4813175f", + "a35475540690e3137be8b4f797b6c89eacea7789", "support" ], "service-workers/service-worker/fetch-request-xhr.https.html": [ @@ -504883,7 +504897,7 @@ "support" ], "tools/wpt/browser.py": [ - "f617fc3252b13b7fba3d24619ece65e2c51f0a4e", + "ddc7837f192ae9307be0028636e92d4faf9b9ced", "support" ], "tools/wpt/commands.json": [ @@ -506886,10 +506900,14 @@ "7fc080d380c4bd46dfb011910e570ee412561b92", "support" ], - "wake-lock/wakelock-abortsignal-set.https.html": [ - "cc534d13d6ca81763627291680c8740d6bd5aff2", + "wake-lock/wakelock-abortsignal.https.any.js": [ + "7961674fea6e42f2a6a2b34b23be486e4685ccea", "testharness" ], + "wake-lock/wakelock-abortsignal.https.any.worker-expected.txt": [ + "c75b5871b2c7798083e191558d9887503c7ca637", + "support" + ], "wake-lock/wakelock-active-document.https.window.js": [ "f0f1e38ddf9defaf4a484ee5db39ec37e561ade5", "testharness" @@ -511115,7 +511133,7 @@ "support" ], "webrtc/RTCPeerConnection-iceConnectionState.https.html": [ - "6d4ab50b0e266c30d6ce329e1f587886f33ae5fb", + "dd95cabcc4f4ab69a194eaa0aec66422ebbe3c30", "testharness" ], "webrtc/RTCPeerConnection-iceGatheringState-expected.txt": [ @@ -511507,7 +511525,7 @@ "support" ], "webrtc/protocol/candidate-exchange.https.html": [ - "2603a02cddf3f026b09b8a233d17ff3f92bd43a1", + "d1bc35819cee8e13485765e6f70836521dc5e7e7", "testharness" ], "webrtc/protocol/dtls-fingerprint-validation.html": [
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/normal-flow/margin-collapse-through-percentage-padding.html b/third_party/blink/web_tests/external/wpt/css/CSS2/normal-flow/margin-collapse-through-percentage-padding.html new file mode 100644 index 0000000..dfd5015 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/CSS2/normal-flow/margin-collapse-through-percentage-padding.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/CSS22/box.html#collapsing-margins"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=967193"> +<link rel="match" href="../../reference/ref-filled-green-100px-square-only.html"> +<meta name="assert" content="A vertical percentage padding that resolves to 0 shouldn't prevent margins from collapsing through the box"> +<p>Test passes if there is a filled green square.</p> +<div style="float:left; width:100px; background:green;"> + <div id="container" style="width:100px;"> + <div style="width:100px; margin-bottom:100px;"></div> + <div style="padding:100% 0;"></div> + <div style="width:100px; margin-top:100px;"></div> + </div> +</div> +<script> + document.body.offsetTop; + container.style.width = "0"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-block-valid.html b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-block-valid.html new file mode 100644 index 0000000..973a1199 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-block-valid.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Logical Properties and Values: parsing border-block with valid values</title> +<link rel="help" href="https://drafts.csswg.org/css-logical/#propdef-border-block"> +<meta name="assert" content="border-block supports the full grammar '<line-width> || <line-style> || <color>'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +// Similar to css-backgrounds/parsing/border-valid.html + +test_valid_value("border-block", "1px dotted red"); +test_valid_value("border-block", "double", ["double", "medium double"]); + +test_valid_value("border-block-start", "green double thin", "thin double green"); +test_valid_value("border-block-start", "green", ["green", "medium none green"]); +test_valid_value("border-block-end", "thin", ["thin", "thin none"]); +test_valid_value("border-block-end", "calc(10px - 0.5em) dotted red"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-color-computed.html b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-color-computed.html new file mode 100644 index 0000000..e9eff241 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-color-computed.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Logical Properties and Values: getComputedValue().borderInlineColor</title> +<link rel="help" href="https://drafts.csswg.org/css-logical/#propdef-border-inline-color"> +<meta name="assert" content="border-inline-color is computed color(s)."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/computed-testcommon.js"></script> +</head> +<body> +<div id="box"></div> +<div id="target"></div> +<style> + #target { + color: lime; + } +</style> +<script> +test_computed_value("border-inline-start-color", "currentcolor", 'rgb(0, 255, 0)'); +test_computed_value("border-inline-start-color", "rgb(2, 3, 4)"); +test_computed_value("border-inline-end-color", "rgb(34, 51, 68)"); +test_computed_value("border-inline-end-color", "transparent", "rgba(0, 0, 0, 0)"); +test_computed_value("border-inline-color", "rgb(34, 51, 68)"); +test_computed_value("border-inline-color", "transparent rgb(2, 3, 4)", "rgba(0, 0, 0, 0) rgb(2, 3, 4)"); +test_computed_value("border-inline-color", "rgb(2, 3, 4) rgb(2, 3, 4)", "rgb(2, 3, 4)"); +test_computed_value("border-inline-color", "currentcolor lime", 'rgb(0, 255, 0)'); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-color-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-color-invalid.html new file mode 100644 index 0000000..f0070c7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-color-invalid.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Logical Properties and Values: parsing border-inline-color with invalid values</title> +<link rel="help" href="https://drafts.csswg.org/css-logical/#propdef-border-inline-color"> +<meta name="assert" content="border-inline-color supports only the grammar '<color>{1,2}'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_invalid_value("border-inline-start-color", "#12"); +test_invalid_value("border-inline-start-color", "auto"); +test_invalid_value("border-inline-start-color", "red green"); +test_invalid_value("border-inline-start-color", "rgb"); +test_invalid_value("border-inline-start-color", "rgb(1,2,3,4,5)"); +test_invalid_value("border-inline-start-color", "rgb(10%, 20, 30%)"); +test_invalid_value("border-inline-end-color", "#123456789"); +test_invalid_value("border-inline-end-color", "123"); +test_invalid_value("border-inline-end-color", "hsla(1,2,3,4,5)"); +test_invalid_value("border-inline-end-color", "red, green"); +test_invalid_value("border-inline-end-color", "rgb(1)"); +test_invalid_value("border-inline-end-color", "rgba(-2, 300, 400%, -0.5)"); +test_invalid_value("border-inline-color", "auto"); +test_invalid_value("border-inline-color", "lime, transparent"); +test_invalid_value("border-inline-color", "red green blue"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-color-valid.html b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-color-valid.html new file mode 100644 index 0000000..6bf24000 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-color-valid.html
@@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Logical Properties and Values: parsing border-inline-color with valid values</title> +<link rel="help" href="https://drafts.csswg.org/css-logical/#propdef-border-inline-color"> +<meta name="assert" content="border-inline-color supports the full grammar '<color>{1,2}'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_valid_value("border-inline-start-color", "currentcolor"); +test_valid_value("border-inline-start-color", "rgb(2, 3, 4)"); +test_valid_value("border-inline-end-color", "#234", "rgb(34, 51, 68)"); +test_valid_value("border-inline-end-color", "transparent"); +test_valid_value("border-inline-color", "#234", "rgb(34, 51, 68)"); +test_valid_value("border-inline-color", "transparent rgb(2, 3, 4)"); +test_valid_value("border-inline-color", "rgb(2, 3, 4) rgb(2, 3, 4)", "rgb(2, 3, 4)"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-style-computed.html b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-style-computed.html new file mode 100644 index 0000000..adcd6d02 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-style-computed.html
@@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Logical Properties and Values: getComputedValue().borderInlineStyle</title> +<link rel="help" href="https://drafts.csswg.org/css-logical/#propdef-border-inline-style"> +<meta name="assert" content="border-inline-style is specified keyword(s)."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/computed-testcommon.js"></script> +</head> +<body> +<div id="target"></div> +<script> +test_computed_value("border-inline-start-style", "dotted"); +test_computed_value("border-inline-start-style", "groove"); +test_computed_value("border-inline-start-style", "inset"); +test_computed_value("border-inline-start-style", "none"); +test_computed_value("border-inline-start-style", "solid"); +test_computed_value("border-inline-end-style", "dashed"); +test_computed_value("border-inline-end-style", "double"); +test_computed_value("border-inline-end-style", "hidden"); +test_computed_value("border-inline-end-style", "outset"); +test_computed_value("border-inline-end-style", "ridge"); +test_computed_value("border-inline-style", "dotted"); +test_computed_value("border-inline-style", "double groove"); +test_computed_value("border-inline-style", "hidden hidden", "hidden"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-style-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-style-invalid.html new file mode 100644 index 0000000..6684dc19 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-style-invalid.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Logical Properties and Values: parsing border-inline-style with invalid values</title> +<link rel="help" href="https://drafts.csswg.org/css-logical/#propdef-border-inline-style"> +<meta name="assert" content="border-inline-style supports only the grammar '<line-style>{1,2}'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_invalid_value("border-inline-start-style", "auto"); +test_invalid_value("border-inline-start-style", "hidden, outset"); +test_invalid_value("border-inline-end-style", "solid double"); +test_invalid_value("border-inline-style", "auto"); +test_invalid_value("border-inline-style", "groove, ridge"); +test_invalid_value("border-inline-style", "hidden inset dashed"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-style-valid.html b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-style-valid.html new file mode 100644 index 0000000..4fd0cbb --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-style-valid.html
@@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Logical Properties and Values: parsing border-inline-style with valid values</title> +<link rel="help" href="https://drafts.csswg.org/css-logical/#propdef-border-block"> +<meta name="assert" content="border-inline-style supports the full grammar '<line-style>{1,2}'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +// none | hidden | dotted | dashed | solid | double | groove | ridge | inset | outset +test_valid_value("border-inline-start-style", "dotted"); +test_valid_value("border-inline-start-style", "groove"); +test_valid_value("border-inline-start-style", "inset"); +test_valid_value("border-inline-start-style", "none"); +test_valid_value("border-inline-start-style", "solid"); +test_valid_value("border-inline-end-style", "dashed"); +test_valid_value("border-inline-end-style", "double"); +test_valid_value("border-inline-end-style", "hidden"); +test_valid_value("border-inline-end-style", "outset"); +test_valid_value("border-inline-end-style", "ridge"); +test_valid_value("border-inline-style", "dotted"); +test_valid_value("border-inline-style", "double groove"); +test_valid_value("border-inline-style", "hidden hidden", "hidden"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-valid.html b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-valid.html new file mode 100644 index 0000000..b7207c0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-valid.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Logical Properties and Values: parsing border-inline with valid values</title> +<link rel="help" href="https://drafts.csswg.org/css-logical/#propdef-border-inline"> +<meta name="assert" content="border-inline supports the full grammar '<line-width> || <line-style> || <color>'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +// Similar to css-backgrounds/parsing/border-valid.html + +test_valid_value("border-inline", "1px dotted red"); +test_valid_value("border-inline", "double", ["double", "medium double"]); + +test_valid_value("border-inline-start", "green double thin", "thin double green"); +test_valid_value("border-inline-start", "green", ["green", "medium none green"]); +test_valid_value("border-inline-end", "thin", ["thin", "thin none"]); +test_valid_value("border-inline-end", "calc(10px - 0.5em) dotted red"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-width-computed.html b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-width-computed.html new file mode 100644 index 0000000..d421329 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-width-computed.html
@@ -0,0 +1,76 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Logical Properties and Values: getComputedValue().borderInlineWidth</title> +<link rel="help" href="https://drafts.csswg.org/css-logical/#propdef-border-inline-width"> +<meta name="assert" content="border-inline-width is absolute length; zero if the border block style is none or hidden."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/computed-testcommon.js"></script> +</head> +<body> +<div id="box"></div> +<div id="target"></div> +<style> + #box { + border-style: dotted; /* Avoid border-*-width computed style 0 */ + border-top-width: thin; + border-right-width: medium; + border-bottom-width: thick; + } + #target { + font-size: 40px; + border-inline-style: dotted; /* Avoid border-inline-*-width computed style 0 */ + } +</style> +<script> +'use strict'; +const box = document.getElementById('box'); +const thinWidth = getComputedStyle(box).borderTopWidth; +const mediumWidth = getComputedStyle(box).borderRightWidth; +const thickWidth = getComputedStyle(box).borderBottomWidth; + +test_computed_value("border-inline-start-width", "calc(10px + 0.5em)", "30px"); +test_computed_value("border-inline-start-width", "calc(10px - 0.5em)", "0px"); +test_computed_value("border-inline-start-width", "thin", thinWidth); +test_computed_value("border-inline-start-width", "medium", mediumWidth); + +test_computed_value("border-inline-end-width", "calc(10px + 0.5em)", "30px"); +test_computed_value("border-inline-end-width", "calc(10px - 0.5em)", "0px"); +test_computed_value("border-inline-end-width", "thick", thickWidth); + +test_computed_value("border-inline-width", "10px"); +test_computed_value("border-inline-width", "10px 20px"); +test_computed_value("border-inline-width", "10px 10px", "10px"); +test(() => { + box.style.borderInlineStartWidth = '10px'; + box.style.borderInlineEndWidth = '10px'; + + box.style.borderInlineStartStyle = 'groove'; + box.style.borderInlineEndStyle = 'solid'; + assert_equals(getComputedStyle(box).borderInlineStartWidth, '10px'); + assert_equals(getComputedStyle(box).borderInlineEndWidth, '10px'); + assert_equals(getComputedStyle(box).borderInlineWidth, '10px'); + + box.style.borderInlineStartStyle = 'hidden'; + box.style.borderInlineEndStyle = 'dashed'; + assert_equals(getComputedStyle(box).borderInlineStartWidth, '0px'); + assert_equals(getComputedStyle(box).borderInlineEndWidth, '10px'); + assert_equals(getComputedStyle(box).borderInlineWidth, '0px 10px'); + + box.style.borderInlineStartStyle = 'inset'; + box.style.borderInlineEndStyle = 'none'; + assert_equals(getComputedStyle(box).borderInlineStartWidth, '10px'); + assert_equals(getComputedStyle(box).borderInlineEndWidth, '0px'); + assert_equals(getComputedStyle(box).borderInlineWidth, '10px 0px'); + + box.style.borderInlineStartStyle = 'none'; + box.style.borderInlineEndStyle = 'hidden'; + assert_equals(getComputedStyle(box).borderInlineStartWidth, '0px'); + assert_equals(getComputedStyle(box).borderInlineEndWidth, '0px'); + assert_equals(getComputedStyle(box).borderInlineWidth, '0px'); +}, 'width is zero if the border block style is none or hidden'); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-width-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-width-invalid.html new file mode 100644 index 0000000..8624fcf --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-width-invalid.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Logical Properties and Values: parsing border-inline-width with invalid values</title> +<link rel="help" href="https://drafts.csswg.org/css-logical/#propdef-border-inline-width"> +<meta name="assert" content="border-inline-width supports only the grammar '<line-width>{1,2}'."> +<meta name="assert" content="Negative lengths are not allowed."> + <script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_invalid_value("border-inline-start-width", "-20px"); +test_invalid_value("border-inline-start-width", "auto"); +test_invalid_value("border-inline-start-width", "medium 40px"); +test_invalid_value("border-inline-end-width", "10"); +test_invalid_value("border-inline-end-width", "30%"); + +test_invalid_value("border-inline-width", "thick, thin"); +test_invalid_value("border-inline-width", "10px 20px 30px"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-width-valid.html b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-width-valid.html new file mode 100644 index 0000000..03c3e0f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/border-inline-width-valid.html
@@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Logical Properties and Values: parsing border-inline-width with valid values</title> +<link rel="help" href="https://drafts.csswg.org/css-logical/#propdef-border-inline-width"> +<meta name="assert" content="border-inline-width supports the full grammar '<line-width>{1,2}'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +// <length> | thin | medium | thick +test_valid_value("border-inline-start-width", "10px"); +test_valid_value("border-inline-start-width", "calc(10px + 0.5em)"); +test_valid_value("border-inline-start-width", "thick"); +test_valid_value("border-inline-start-width", "thin"); +test_valid_value("border-inline-end-width", "0", "0px"); +test_valid_value("border-inline-end-width", "calc(10px - 0.5em)"); +test_valid_value("border-inline-end-width", "medium"); +test_valid_value("border-inline-width", "10px"); +test_valid_value("border-inline-width", "medium calc(10px + 0.5em)"); +test_valid_value("border-inline-width", "10px 10px", "10px"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/initial-background-color.html b/third_party/blink/web_tests/external/wpt/css/css-values/initial-background-color.html index f382266..7a6c617 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-values/initial-background-color.html +++ b/third_party/blink/web_tests/external/wpt/css/css-values/initial-background-color.html
@@ -16,7 +16,7 @@ href="mailto:fremycompany.developer@yahoo.fr" / > - <link rel="help" href="http://www.w3.org/TR/css3-values/#attr-notation"/> + <link rel="help" href="http://www.w3.org/TR/css3-values/#common-keywords"/> <link rel="match"
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/srcset/avoid-reload-on-resize.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/srcset/avoid-reload-on-resize.html new file mode 100644 index 0000000..a8038e5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/srcset/avoid-reload-on-resize.html
@@ -0,0 +1,20 @@ +<!doctype html> +<title>Avoid srcset image reloads when viewport resizes</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +setup({explicit_done:true}); +const image_was_loaded = () => { + const iframe = document.getElementById("iframe"); + // Resize the iframe + iframe.width="400"; + // Wait 500 ms + step_timeout(() => { + // Check that the iframe only loaded a single resource + const entries = iframe.contentWindow.performance.getEntriesByType("resource"); + assert_equals(entries.length, 1); + done(); + }, 500); +} +</script> +<iframe id=iframe width="401" src="resources/resized.html" onload="image_was_loaded()"></iframe>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/srcset/resources/image.png b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/srcset/resources/image.png new file mode 120000 index 0000000..c0d95fa --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/srcset/resources/image.png
@@ -0,0 +1 @@ +../../image.png \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/srcset/resources/image.png.headers b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/srcset/resources/image.png.headers new file mode 100644 index 0000000..edaec7a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/srcset/resources/image.png.headers
@@ -0,0 +1,3 @@ +Cache-Control: no-store + +
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/srcset/resources/resized.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/srcset/resources/resized.html new file mode 100644 index 0000000..6fb6847 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/srcset/resources/resized.html
@@ -0,0 +1,2 @@ +<!DOCTYPE html> +<img srcset="image.png?400 400w, image.png?800 800w, image.png?1600 1600w" sizes="50vw">
diff --git a/third_party/blink/web_tests/external/wpt/tools/wpt/browser.py b/third_party/blink/web_tests/external/wpt/tools/wpt/browser.py index f617fc3..ddc7837f 100644 --- a/third_party/blink/web_tests/external/wpt/tools/wpt/browser.py +++ b/third_party/blink/web_tests/external/wpt/tools/wpt/browser.py
@@ -634,7 +634,11 @@ class EdgeChromium(Browser): """MicrosoftEdge-specific interface.""" - + platform = { + "Linux": "linux", + "Windows": "win", + "Darwin": "macos" + }.get(uname[0]) product = "edgechromium" requirements = "requirements_edge_chromium.txt" @@ -642,13 +646,35 @@ raise NotImplementedError def find_binary(self, venv_path=None, channel=None): - raise find_executable("msedge") + binary = None + if self.platform == "win": + binaryname = "msedge" + binary = find_executable(binaryname) + if not binary: + # Use paths from different Edge channels starting with Release\Beta\Dev\Canary + winpaths = [os.path.expanduser("~\\AppData\\Local\\Microsoft\\Edge\\Application"), + os.path.expandvars("$SYSTEMDRIVE\\Program Files\\Microsoft\\Edge Beta\\Application"), + os.path.expandvars("$SYSTEMDRIVE\\Program Files\\Microsoft\\Edge Dev\\Application"), + os.path.expandvars("$SYSTEMDRIVE\\Program Files (x86)\\Microsoft\\Edge Beta\\Application"), + os.path.expandvars("$SYSTEMDRIVE\\Program Files (x86)\\Microsoft\\Edge Dev\\Application"), + os.path.expanduser("~\\AppData\Local\\Microsoft\\Edge SxS\\Application"),] + return find_executable(binaryname, os.pathsep.join(winpaths)) + if self.platform == "macos": + binaryname = "Microsoft Edge Canary" + binary = find_executable(binaryname) + if not binary: + macpaths = ["/Applications/Microsoft Edge.app/Contents/MacOS", + os.path.expanduser("~/Applications/Microsoft Edge.app/Contents/MacOS"), + "/Applications/Microsoft Edge Canary.app/Contents/MacOS", + os.path.expanduser("~/Applications/Microsoft Edge Canary.app/Contents/MacOS")] + return find_executable("Microsoft Edge Canary", os.pathsep.join(macpaths)) + return binary def find_webdriver(self, channel=None): return find_executable("msedgedriver") def install_webdriver(self, dest=None, channel=None, browser_binary=None): - if uname[0] != "Windows": + if self.platform == "win": raise ValueError("Only Windows platform is currently supported") if dest is None: @@ -666,19 +692,29 @@ return find_executable("msedgedriver", dest) def version(self, binary=None, webdriver_binary=None): - if uname[0] != "Windows": + if binary is None: + binary = self.find_binary() + if self.platform != "win": try: version_string = call(binary, "--version").strip() except subprocess.CalledProcessError: self.logger.warning("Failed to call %s" % binary) return None - m = re.match(r"(?:MSEdge|Edge) (.*)", version_string) + m = re.match(r"Microsoft Edge (.*) ", version_string) if not m: self.logger.warning("Failed to extract version from: %s" % version_string) return None return m.group(1) - self.logger.warning("Unable to extract version from binary on Windows.") - return None + else: + if binary is not None: + command = "(Get-Item '%s').VersionInfo.FileVersion" % binary + try: + return call("powershell.exe", command).strip() + except (subprocess.CalledProcessError, OSError): + self.logger.warning("Failed to call %s in PowerShell" % command) + return None + self.logger.warning("Failed to find Edge binary.") + return None class Edge(Browser): """Edge-specific interface."""
diff --git a/third_party/blink/web_tests/external/wpt/wake-lock/wakelock-abortsignal-set.https.html b/third_party/blink/web_tests/external/wpt/wake-lock/wakelock-abortsignal.https.any.js similarity index 69% rename from third_party/blink/web_tests/external/wpt/wake-lock/wakelock-abortsignal-set.https.html rename to third_party/blink/web_tests/external/wpt/wake-lock/wakelock-abortsignal.https.any.js index cc534d1..7961674 100644 --- a/third_party/blink/web_tests/external/wpt/wake-lock/wakelock-abortsignal-set.https.html +++ b/third_party/blink/web_tests/external/wpt/wake-lock/wakelock-abortsignal.https.any.js
@@ -1,10 +1,23 @@ -<!DOCTYPE html> -<meta charset="utf-8"> -<title>WakeLock: passing an AbortSignal already set aborts</title> -<link rel="help" href="https://w3c.github.io/wake-lock/"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script> +// META: title=WakeLock.request() AbortSignal Test + +'use strict'; + +promise_test(async t => { + const invalidSignals = [ + "string", + 123, + {}, + true, + Symbol(), + () => {}, + self + ]; + + for (let signal of invalidSignals) { + await promise_rejects(t, new TypeError(), WakeLock.request('screen', { signal: signal })); + } +}, "'TypeError' is thrown when the signal option is not an AbortSignal"); + promise_test(t => { const abortController = new AbortController(); const abortSignal = abortController.signal; @@ -28,4 +41,3 @@ await promise_rejects(t, "AbortError", lock2); await promise_rejects(t, "AbortError", lock3); }, "The same AbortSignal can be used to cause multiple wake locks to abort"); -</script>
diff --git a/third_party/blink/web_tests/external/wpt/wake-lock/wakelock-abortsignal.https.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/wake-lock/wakelock-abortsignal.https.any.worker-expected.txt new file mode 100644 index 0000000..c75b587 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/wake-lock/wakelock-abortsignal.https.any.worker-expected.txt
@@ -0,0 +1,6 @@ +This is a testharness.js-based test. +FAIL 'TypeError' is thrown when the signal option is not an AbortSignal promise_test: Unhandled rejection with value: object "ReferenceError: WakeLock is not defined" +FAIL A WakeLock request with an AbortSignal whose abort flag is set always aborts WakeLock is not defined +FAIL The same AbortSignal can be used to cause multiple wake locks to abort promise_test: Unhandled rejection with value: object "ReferenceError: WakeLock is not defined" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https.html index 6d4ab50..dd95cab 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https.html +++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https.html
@@ -276,5 +276,42 @@ closed The RTCIceTransport has shut down and is no longer responding to STUN requests. - */ + */ + +for (let bundle_policy of ['balanced', 'max-bundle', 'max-compat']) { + + + promise_test(async t => { + const caller = new RTCPeerConnection({bundlePolicy: bundle_policy}); + t.add_cleanup(() => caller.close()); + const stream = await navigator.mediaDevices.getUserMedia( + {audio: true, video:true}); + t.add_cleanup(() => stream.getTracks().forEach(track => track.stop())); + const [track1, track2] = stream.getTracks(); + const sender1 = caller.addTrack(track1); + const sender2 = caller.addTrack(track2); + caller.createDataChannel('datachannel'); + const callee = new RTCPeerConnection(); + t.add_cleanup(() => callee.close()); + coupleIceCandidates(caller, callee); + const offer = await caller.createOffer(); + await caller.setLocalDescription(offer); + const [caller_transceiver1, caller_transceiver2] = caller.getTransceivers(); + assert_equals(sender1.transport, caller_transceiver1.sender.transport); + await callee.setRemoteDescription(offer); + const [callee_transceiver1, callee_transceiver2] = callee.getTransceivers(); + const answer = await callee.createAnswer(); + await callee.setLocalDescription(answer); + await caller.setRemoteDescription(answer); + // At this point, we should have a single ICE transport, and it + // should be in the "connected" state. + assert_equals(caller_transceiver1.receiver.transport.iceTransport.state, + 'connected', 'ICE transport.state'); + // The PeerConnection's iceConnectionState should therefore be 'connected' + assert_equals(caller.iceConnectionState, 'connected', + 'PC.iceConnectionState:'); + }, 'iceConnectionState changes at the right time, with bundle policy ' + + bundle_policy); + } + </script>
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/protocol/candidate-exchange.https.html b/third_party/blink/web_tests/external/wpt/webrtc/protocol/candidate-exchange.https.html index 2603a02c..d1bc3581 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc/protocol/candidate-exchange.https.html +++ b/third_party/blink/web_tests/external/wpt/webrtc/protocol/candidate-exchange.https.html
@@ -26,15 +26,36 @@ return waiter; } +class StateLogger { + constructor(source, eventname, field) { + source.addEventListener(eventname, event => { + this.events.push(source[field]); + }); + this.events = [source[field]]; + } +} + +class IceStateLogger extends StateLogger { + constructor(source) { + super(source, 'iceconnectionstatechange', 'iceConnectionState'); + } +} + promise_test(async t => { const pc1 = new RTCPeerConnection(); const pc2 = new RTCPeerConnection(); t.add_cleanup(() => pc1.close()); t.add_cleanup(() => pc2.close()); pc1.createDataChannel('datachannel'); + pc1IceStates = new IceStateLogger(pc1); + pc2IceStates = new IceStateLogger(pc1); coupleIceCandidates(pc1, pc2); await doSignalingHandshake(pc1, pc2); - await waitForIceStateChange(pc1, ['connected', 'completed']); + // Note - it's been claimed that this state sometimes jumps straight + // to "completed". If so, this test should be flaky. + await waitForIceStateChange(pc1, ['connected']); + assert_array_equals(pc1IceStates.events, ['new', 'checking', 'connected']); + assert_array_equals(pc2IceStates.events, ['new', 'checking', 'connected']); }, 'Two way ICE exchange works'); promise_test(async t => { @@ -42,6 +63,8 @@ const pc2 = new RTCPeerConnection(); t.add_cleanup(() => pc1.close()); t.add_cleanup(() => pc2.close()); + pc1IceStates = new IceStateLogger(pc1); + pc2IceStates = new IceStateLogger(pc1); let candidates = []; pc1.createDataChannel('datachannel'); pc1.onicecandidate = e => { @@ -62,6 +85,8 @@ const candidate_pair = pc1.sctp.transport.iceTransport.getSelectedCandidatePair(); assert_equals(candidate_pair.local.type, 'host'); assert_equals(candidate_pair.remote.type, 'prflx'); + assert_array_equals(pc1IceStates.events, ['new', 'checking', 'connected']); + assert_array_equals(pc2IceStates.events, ['new', 'checking', 'connected']); }, 'Adding only caller -> callee candidates gives a connection'); promise_test(async t => { @@ -69,6 +94,8 @@ const pc2 = new RTCPeerConnection(); t.add_cleanup(() => pc1.close()); t.add_cleanup(() => pc2.close()); + pc1IceStates = new IceStateLogger(pc1); + pc2IceStates = new IceStateLogger(pc1); let candidates = []; pc1.createDataChannel('datachannel'); pc2.onicecandidate = e => { @@ -89,8 +116,92 @@ const candidate_pair = pc2.sctp.transport.iceTransport.getSelectedCandidatePair(); assert_equals(candidate_pair.local.type, 'host'); assert_equals(candidate_pair.remote.type, 'prflx'); + assert_array_equals(pc1IceStates.events, ['new', 'checking', 'connected']); + assert_array_equals(pc2IceStates.events, ['new', 'checking', 'connected']); }, 'Adding only callee -> caller candidates gives a connection'); +promise_test(async t => { + const pc1 = new RTCPeerConnection(); + const pc2 = new RTCPeerConnection(); + t.add_cleanup(() => pc1.close()); + t.add_cleanup(() => pc2.close()); + pc1IceStates = new IceStateLogger(pc1); + pc2IceStates = new IceStateLogger(pc1); + let pc2ToPc1Candidates = []; + pc1.createDataChannel('datachannel'); + pc2.onicecandidate = e => { + pc2ToPc1Candidates.push(e.candidate); + // This particular test verifies that candidates work + // properly if added from the pc2 onicecandidate event. + if (!e.candidate) { + for (const candidate of pc2ToPc1Candidates) { + if (candidate) { + pc1.addIceCandidate(candidate); + } + } + } + } + // Candidates from |pc1| are not delivered to |pc2|. |pc2| will use + // peer-reflexive candidates. + await doSignalingHandshake(pc1, pc2); + await Promise.all([waitForIceStateChange(pc1, ['connected', 'completed']), + waitForIceStateChange(pc2, ['connected', 'completed'])]); + const candidate_pair = pc2.sctp.transport.iceTransport.getSelectedCandidatePair(); + assert_equals(candidate_pair.local.type, 'host'); + assert_equals(candidate_pair.remote.type, 'prflx'); + assert_array_equals(pc1IceStates.events, ['new', 'checking', 'connected']); + assert_array_equals(pc2IceStates.events, ['new', 'checking', 'connected']); +}, 'Adding callee -> caller candidates from end-of-candidates gives a connection'); + +promise_test(async t => { + const pc1 = new RTCPeerConnection(); + const pc2 = new RTCPeerConnection(); + t.add_cleanup(() => pc1.close()); + t.add_cleanup(() => pc2.close()); + pc1IceStates = new IceStateLogger(pc1); + pc2IceStates = new IceStateLogger(pc1); + let pc1ToPc2Candidates = []; + let pc2ToPc1Candidates = []; + pc1.createDataChannel('datachannel'); + pc1.onicecandidate = e => { + pc1ToPc2Candidates.push(e.candidate); + } + pc2.onicecandidate = e => { + pc2ToPc1Candidates.push(e.candidate); + } + const offer = await pc1.createOffer(); + await Promise.all([pc1.setLocalDescription(offer), + pc2.setRemoteDescription(offer)]); + const answer = await pc2.createAnswer(); + await iceGatheringCompleteWaiter(pc1); + await pc2.setLocalDescription(answer).then(() => { + for (const candidate of pc1ToPc2Candidates) { + if (candidate) { + pc2.addIceCandidate(candidate); + } + } + }); + await iceGatheringCompleteWaiter(pc2); + pc1.setRemoteDescription(answer).then(async () => { + for (const candidate of pc2ToPc1Candidates) { + if (candidate) { + await pc1.addIceCandidate(candidate); + } + } + }); + await Promise.all([waitForIceStateChange(pc1, ['connected', 'completed']), + waitForIceStateChange(pc2, ['connected', 'completed'])]); + const candidate_pair = + pc1.sctp.transport.iceTransport.getSelectedCandidatePair(); + assert_equals(candidate_pair.local.type, 'host'); + // When we supply remote candidates, we expect a jump to the 'host' candidate, + // but it might also remain as 'prflx'. + assert_true(candidate_pair.remote.type == 'host' || + candidate_pair.remote.type == 'prflx'); + assert_array_equals(pc1IceStates.events, ['new', 'checking', 'connected']); + assert_array_equals(pc2IceStates.events, ['new', 'checking', 'connected']); +}, 'Explicit offer/answer exchange gives a connection'); + </script> </body> </html>
diff --git a/third_party/blink/web_tests/http/tests/security/powerfulFeatureRestrictions/device-orientation-events-unavailable-on-insecure-origins.html b/third_party/blink/web_tests/http/tests/security/powerfulFeatureRestrictions/device-orientation-events-unavailable-on-insecure-origins.html index 1cc1f6bf..9ba2557 100644 --- a/third_party/blink/web_tests/http/tests/security/powerfulFeatureRestrictions/device-orientation-events-unavailable-on-insecure-origins.html +++ b/third_party/blink/web_tests/http/tests/security/powerfulFeatureRestrictions/device-orientation-events-unavailable-on-insecure-origins.html
@@ -3,13 +3,28 @@ <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <script src="/resources/get-host-info.js"></script> +<script src="/resources/sensor-helpers.js"></script> +<script src="/gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script> +<script src="/gen/services/device/public/mojom/sensor_provider.mojom.js"></script> <script> +// Cannot use `step_timeout()` because we need the `sensor_test` infrastructure below, +// which, however, is using `promise_test` internally. Cannot use `promise_rejects` +// either, as `sensor_test` does not expose the `test_object`. +function waitForLackOfEvent(eventName) { + return new Promise((resolve, reject) => { + window.addEventListener(eventName, reject); + window.setTimeout(() => { + window.removeEventListener(eventName, reject); + resolve(); + }, 1000); + }); +} + if (window.location.origin != get_host_info().UNAUTHENTICATED_ORIGIN) { window.location = get_host_info().UNAUTHENTICATED_ORIGIN + window.location.pathname; promise_test(_ => new Promise(_ => {}), "Stall tests on the wrong host."); } else { - test(() => { assert_false('DeviceMotionEvent' in window); assert_false('DeviceOrientationEvent' in window); @@ -20,6 +35,30 @@ assert_false('ondeviceorientation' in window); assert_false('ondeviceorientationabsolute' in window); }, 'Event interfaces and event handlers are not exposed on `window`.'); -} + sensor_test(sensorProvider => { + const FAKE_ACCELERATION_DATA = [1, 2, 3]; + const FAKE_LINEAR_ACCELERATION_DATA = [4, 5, 6]; + const FAKE_GYROSCOPE_DATA = [7, 8, 9]; + setMockSensorDataForType(sensorProvider, device.mojom.SensorType.ACCELEROMETER, FAKE_ACCELERATION_DATA); + setMockSensorDataForType(sensorProvider, device.mojom.SensorType.LINEAR_ACCELERATION, FAKE_LINEAR_ACCELERATION_DATA); + setMockSensorDataForType(sensorProvider, device.mojom.SensorType.GYROSCOPE, FAKE_GYROSCOPE_DATA); + + return waitForLackOfEvent('devicemotion'); + }, 'addEventListener() for `devicemotion` does not crash but the handler never fires.'); + + sensor_test(sensorProvider => { + const FAKE_ORIENTATION_DATA = [1.1, 2.2, 3.3]; + setMockSensorDataForType(sensorProvider, device.mojom.SensorType.RELATIVE_ORIENTATION_EULER_ANGLES, FAKE_ORIENTATION_DATA); + + return waitForLackOfEvent('deviceorientation'); + }, 'addEventListener() for `deviceorientation` does not crash but the handler never fires.'); + + sensor_test(sensorProvider => { + const FAKE_ORIENTATION_DATA = [1.1, 2.2, 3.3]; + setMockSensorDataForType(sensorProvider, device.mojom.SensorType.ABSOLUTE_ORIENTATION_EULER_ANGLES, FAKE_ORIENTATION_DATA); + + return waitForLackOfEvent('deviceorientationabsolute'); + }, 'addEventListener() for `deviceorientationabsolute` does not crash but the handler never fires.'); +} </script>
diff --git a/third_party/blink/web_tests/http/tests/security/powerfulFeatureRestrictions/device-orientation-on-secure-origin.https.html b/third_party/blink/web_tests/http/tests/security/powerfulFeatureRestrictions/device-orientation-on-secure-origin.https.html index 7855472a..f3fd011 100644 --- a/third_party/blink/web_tests/http/tests/security/powerfulFeatureRestrictions/device-orientation-on-secure-origin.https.html +++ b/third_party/blink/web_tests/http/tests/security/powerfulFeatureRestrictions/device-orientation-on-secure-origin.https.html
@@ -58,4 +58,15 @@ })); }, 'DeviceOrientationEvent fires.'); +sensor_test(async sensorProvider => { + const FAKE_ORIENTATION_DATA = [1.1, 2.2, 3.3]; + setMockSensorDataForType(sensorProvider, device.mojom.SensorType.ABSOLUTE_ORIENTATION_EULER_ANGLES, FAKE_ORIENTATION_DATA); + + return waitForEvent(new DeviceOrientationEvent('deviceorientationabsolute', { + alpha: FAKE_ORIENTATION_DATA[2], + beta: FAKE_ORIENTATION_DATA[0], + gamma: FAKE_ORIENTATION_DATA[1], + absolute: true, + })); +}, 'DeviceOrientationEvent fires (with absolute orientation).'); </script>
diff --git a/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https-expected.txt b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https-expected.txt index b9fe8a5..552da96b 100644 --- a/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https-expected.txt +++ b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https-expected.txt
@@ -6,5 +6,8 @@ PASS connection with audio track should eventually have connected connection state PASS connection with audio and video tracks should eventually have connected connection state FAIL ICE can connect in a recvonly usecase promise_test: Unhandled rejection with value: object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'." +FAIL iceConnectionState changes at the right time, with bundle policy balanced promise_test: Unhandled rejection with value: object "TypeError: Cannot read property 'sender' of undefined" +FAIL iceConnectionState changes at the right time, with bundle policy max-bundle promise_test: Unhandled rejection with value: object "TypeError: Cannot read property 'sender' of undefined" +FAIL iceConnectionState changes at the right time, with bundle policy max-compat promise_test: Unhandled rejection with value: object "TypeError: Cannot read property 'sender' of undefined" Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/protocol/candidate-exchange.https-expected.txt b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/protocol/candidate-exchange.https-expected.txt index affbf0a..c342435 100644 --- a/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/protocol/candidate-exchange.https-expected.txt +++ b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/protocol/candidate-exchange.https-expected.txt
@@ -2,5 +2,7 @@ PASS Two way ICE exchange works FAIL Adding only caller -> callee candidates gives a connection promise_test: Unhandled rejection with value: object "TypeError: Cannot read property 'transport' of null" FAIL Adding only callee -> caller candidates gives a connection promise_test: Unhandled rejection with value: object "TypeError: Cannot read property 'transport' of null" +FAIL Adding callee -> caller candidates from end-of-candidates gives a connection promise_test: Unhandled rejection with value: object "TypeError: Cannot read property 'transport' of null" +FAIL Explicit offer/answer exchange gives a connection promise_test: Unhandled rejection with value: object "TypeError: Cannot read property 'transport' of null" Harness: the test ran to completion.
diff --git a/third_party/closure_compiler/externs/autofill_private.js b/third_party/closure_compiler/externs/autofill_private.js index d905d06..c9cc2cd 100644 --- a/third_party/closure_compiler/externs/autofill_private.js +++ b/third_party/closure_compiler/externs/autofill_private.js
@@ -197,15 +197,8 @@ chrome.autofillPrivate.logServerCardLinkClicked = function() {}; /** - * Fired when the address list has changed, meaning that an entry has been + * Fired when the perosnal data has changed, meaning that an entry has been * added, removed, or changed. |entries| The updated list of entries. * @type {!ChromeEvent} */ -chrome.autofillPrivate.onAddressListChanged; - -/** - * Fired when the credit card list has changed, meaning that an entry has been - * added, removed, or changed. |entries| The updated list of entries. - * @type {!ChromeEvent} - */ -chrome.autofillPrivate.onCreditCardListChanged; +chrome.autofillPrivate.onPersonalDataChanged;
diff --git a/tools/clang/scripts/build.py b/tools/clang/scripts/build.py index 354a3e4..1f29fb6 100755 --- a/tools/clang/scripts/build.py +++ b/tools/clang/scripts/build.py
@@ -424,9 +424,12 @@ # Need libc++ and compiler-rt for the bootstrap compiler on mac. projects += ';libcxx;compiler-rt' + bootstrap_targets = 'X86' + if sys.platform == 'darwin': + # Need ARM and AArch64 for building the ios clang_rt. + bootstrap_targets += ';ARM;AArch64' bootstrap_args = base_cmake_args + [ - # Need ARM and AArch64 for building the ios clang_rt. - '-DLLVM_TARGETS_TO_BUILD=X86;ARM;AArch64', + '-DLLVM_TARGETS_TO_BUILD=' + bootstrap_targets, '-DLLVM_ENABLE_PROJECTS=' + projects, '-DCMAKE_INSTALL_PREFIX=' + LLVM_BOOTSTRAP_INSTALL_DIR, '-DCMAKE_C_FLAGS=' + ' '.join(cflags), @@ -475,6 +478,30 @@ print('Bootstrap compiler installed; building final compiler.') + + compiler_rt_args = [ + "-DCOMPILER_RT_BUILD_CRT=OFF", + "-DCOMPILER_RT_BUILD_LIBFUZZER=ON", + "-DCOMPILER_RT_BUILD_PROFILE=ON", + "-DCOMPILER_RT_BUILD_SANITIZERS=ON", + "-DCOMPILER_RT_BUILD_XRAY=OFF", + ] + if sys.platform == 'darwin': + compiler_rt_args.extend([ + "-DCOMPILER_RT_BUILD_BUILTINS=ON", + "-DCOMPILER_RT_ENABLE_IOS=ON", + "-DCOMPILER_RT_ENABLE_WATCHOS=OFF", + "-DCOMPILER_RT_ENABLE_TVOS=OFF", + # armv7 is A5 and earlier, armv7s is A6+ (2012 and later, before 64-bit + # iPhones). armv7k is Apple Watch, which we don't need. + "-DDARWIN_ios_ARCHS=armv7;armv7s;arm64", + "-DDARWIN_iossim_ARCHS=i386;x86_64", + # We don't need 32-bit intel support for macOS, we only ship 64-bit. + "-DDARWIN_osx_ARCHS=x86_64", + ]) + else: + compiler_rt_args.append("-DCOMPILER_RT_BUILD_BUILTINS=OFF") + # LLVM uses C++11 starting in llvm 3.5. On Linux, this means libstdc++4.7+ is # needed, on OS X it requires libc++. clang only automatically links to libc++ # when targeting OS X 10.9+, so add stdlib=libc++ explicitly so clang can run @@ -556,7 +583,7 @@ chrome_tools = list(set(default_tools + args.extra_tools)) if cc is not None: base_cmake_args.append('-DCMAKE_C_COMPILER=' + cc) if cxx is not None: base_cmake_args.append('-DCMAKE_CXX_COMPILER=' + cxx) - cmake_args = base_cmake_args + [ + cmake_args = base_cmake_args + compiler_rt_args + [ '-DLLVM_ENABLE_THREADS=OFF', '-DCMAKE_C_FLAGS=' + ' '.join(cflags), '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags), @@ -619,7 +646,7 @@ # The bootstrap compiler produces 64-bit binaries by default. cflags += ['-m32'] cxxflags += ['-m32'] - compiler_rt_args = base_cmake_args + [ + compiler_rt_args = base_cmake_args + compiler_rt_args + [ '-DLLVM_ENABLE_THREADS=OFF', '-DCMAKE_C_FLAGS=' + ' '.join(cflags), '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags)] @@ -640,6 +667,9 @@ if args.with_android: make_toolchain = os.path.join( ANDROID_NDK_DIR, 'build', 'tools', 'make_standalone_toolchain.py') + # TODO(thakis): Now that the NDK uses clang, try to build all archs in + # one LLVM build instead of making 3 different toolchains and building + # 3 times. for target_arch in ['aarch64', 'arm', 'i686']: # Make standalone Android toolchain for target_arch. toolchain_dir = os.path.join( @@ -685,6 +715,12 @@ '-DCMAKE_C_FLAGS=' + ' '.join(cflags), '-DCMAKE_CXX_FLAGS=' + ' '.join(cflags), '-DCMAKE_ASM_FLAGS=' + ' '.join(cflags), + "-DCOMPILER_RT_BUILD_BUILTINS=OFF", + "-DCOMPILER_RT_BUILD_CRT=OFF", + "-DCOMPILER_RT_BUILD_LIBFUZZER=OFF", + "-DCOMPILER_RT_BUILD_PROFILE=ON", + "-DCOMPILER_RT_BUILD_SANITIZERS=ON", + "-DCOMPILER_RT_BUILD_XRAY=OFF", '-DSANITIZER_CXX_ABI=libcxxabi', '-DCMAKE_SHARED_LINKER_FLAGS=-Wl,-u__cxa_demangle', '-DANDROID=1'] @@ -730,6 +766,12 @@ '-DCMAKE_SYSTEM_NAME=Fuchsia', '-DCMAKE_C_COMPILER_TARGET=%s-fuchsia' % target_arch, '-DCMAKE_ASM_COMPILER_TARGET=%s-fuchsia' % target_arch, + "-DCOMPILER_RT_BUILD_BUILTINS=ON", + "-DCOMPILER_RT_BUILD_CRT=OFF", + "-DCOMPILER_RT_BUILD_LIBFUZZER=OFF", + "-DCOMPILER_RT_BUILD_PROFILE=OFF", + "-DCOMPILER_RT_BUILD_SANITIZERS=OFF", + "-DCOMPILER_RT_BUILD_XRAY=OFF", '-DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON', '-DCMAKE_SYSROOT=%s' % toolchain_dir, # TODO(thakis|scottmg): Use PER_TARGET_RUNTIME_DIR for all platforms.
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py index 876fb66d1..ca65631 100755 --- a/tools/clang/scripts/update.py +++ b/tools/clang/scripts/update.py
@@ -38,7 +38,7 @@ # Reverting problematic clang rolls is safe, though. CLANG_REVISION = '67510fac36d27b2e22c7cd955fc167136b737b93' CLANG_SVN_REVISION = '361212' -CLANG_SUB_REVISION = 2 +CLANG_SUB_REVISION = 3 PACKAGE_VERSION = '%s-%s-%s' % (CLANG_SVN_REVISION, CLANG_REVISION[:8], CLANG_SUB_REVISION)
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 75b0b7b..d21b50f 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -17659,8 +17659,9 @@ <int value="25" label="AUDIO_ON_DEVICES_CHANGED"/> <int value="26" label="AUDIO_ON_LEVEL_CHANGED"/> <int value="27" label="AUDIO_ON_MUTE_CHANGED"/> - <int value="28" label="AUTOFILL_PRIVATE_ON_ADDRESS_LIST_CHANGED"/> - <int value="29" label="AUTOFILL_PRIVATE_ON_CREDIT_CARD_LIST_CHANGED"/> + <int value="28" label="AUTOFILL_PRIVATE_ON_ADDRESS_LIST_CHANGED_DEPRECATED"/> + <int value="29" + label="AUTOFILL_PRIVATE_ON_CREDIT_CARD_LIST_CHANGED_DEPRECATED"/> <int value="30" label="AUTOMATION_INTERNAL_ON_ACCESSIBILITY_EVENT"/> <int value="31" label="AUTOMATION_INTERNAL_ON_ACCESSIBILITY_TREE_DESTROYED"/> <int value="32" label="BLUETOOTH_LOW_ENERGY_ON_CHARACTERISTIC_VALUE_CHANGED"/> @@ -18086,6 +18087,7 @@ <int value="436" label="MIME_HANDLER_PRIVATE_SAVE"/> <int value="437" label="RUNTIME_ON_CONNECT_NATIVE"/> <int value="438" label="ACTION_ON_CLICKED"/> + <int value="439" label="AUTOFILL_PRIVATE_ON_PERSONAL_DATA_CHANGED"/> </enum> <enum name="ExtensionFileWriteResult"> @@ -23405,6 +23407,7 @@ <int value="2910" label="V8XRInputSource_Gamepad_AttributeGetter"/> <int value="2911" label="V8XRSession_End_Method"/> <int value="2912" label="V8XRWebGLLayer_Constructor"/> + <int value="2913" label="FetchKeepalive"/> </enum> <enum name="FeaturePolicyFeature"> @@ -34368,6 +34371,7 @@ <int value="-59401847" label="ContentSuggestionsLargeThumbnail:disabled"/> <int value="-58242474" label="ash-disable-swipe-to-close-in-overview-mode"/> <int value="-57986995" label="DisablePostScriptPrinting:enabled"/> + <int value="-57383646" label="UseSearchClickForRightClick:disabled"/> <int value="-56235502" label="WebRtcHideLocalIpsWithMdns:enabled"/> <int value="-55944747" label="disable-child-account-detection"/> <int value="-55592344" label="SyncPseudoUSSDictionary:disabled"/> @@ -34414,6 +34418,7 @@ <int value="0" label="BAD_FLAG_FORMAT"> Command-line flag doesn't start with two dashes. </int> + <int value="1343197" label="UseSearchClickForRightClick:enabled"/> <int value="1558582" label="ResamplingInputEvents:enabled"/> <int value="5654819" label="CrostiniGpuSupport:disabled"/> <int value="7444737" label="NTPSuggestionsStandaloneUI:disabled"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 10f2d95..05756367 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -53210,7 +53210,6 @@ <histogram name="Media.Audio.Render.StreamBrokerDisconnectReason2" enum="AudioOutputStreamDisconnectReason2" expires_after="2019-09-01"> <owner>olka@chromium.org</owner> - <owner>grunell@chromium.org</owner> <owner>maxmorin@chromium.org</owner> <summary> Describes why and in which state an audio output stream ended. @@ -53219,7 +53218,7 @@ <histogram name="Media.Audio.Render.StreamBrokerDocumentDestroyedAwaitingCreatedTime" - units="ms" expires_after="2019-06-01"> + units="ms" expires_after="2019-09-01"> <owner>olka@chromium.org</owner> <owner>marinaciocea@chromium.org</owner> <owner>maxmorin@chromium.org</owner> @@ -53231,7 +53230,7 @@ </histogram> <histogram name="Media.Audio.Render.StreamBrokerStreamCreationTime" units="ms" - expires_after="2019-06-01"> + expires_after="2019-09-01"> <owner>olka@chromium.org</owner> <owner>marinaciocea@chromium.org</owner> <owner>maxmorin@chromium.org</owner> @@ -53298,7 +53297,7 @@ </histogram> <histogram name="Media.Audio.TrackAudioRenderer.DeviceStatus" - enum="OutputDeviceStatus" expires_after="2019-06-01"> + enum="OutputDeviceStatus" expires_after="2019-09-01"> <owner>olka@chromium.org</owner> <owner>maxmorin@chromium.org</owner> <summary> @@ -53308,7 +53307,7 @@ </histogram> <histogram name="Media.Audio.TrackAudioRenderer.SwitchDeviceStatus" - enum="OutputDeviceStatus" expires_after="2019-06-01"> + enum="OutputDeviceStatus" expires_after="2019-09-01"> <owner>olka@chromium.org</owner> <owner>maxmorin@chromium.org</owner> <summary> @@ -53331,7 +53330,7 @@ </histogram> <histogram name="Media.Audio.WebRTCAudioRenderer.DeviceStatus" - enum="OutputDeviceStatus" expires_after="2019-06-01"> + enum="OutputDeviceStatus" expires_after="2019-09-01"> <owner>olka@chromium.org</owner> <owner>maxmorin@chromium.org</owner> <summary> @@ -53341,7 +53340,7 @@ </histogram> <histogram name="Media.Audio.WebRTCAudioRenderer.SwitchDeviceStatus" - enum="OutputDeviceStatus" expires_after="2019-06-01"> + enum="OutputDeviceStatus" expires_after="2019-09-01"> <owner>olka@chromium.org</owner> <owner>maxmorin@chromium.org</owner> <summary> @@ -53467,7 +53466,7 @@ </histogram> <histogram name="Media.AudioOutputController.LifeTime" units="ms" - expires_after="2019-06-01"> + expires_after="2019-09-01"> <owner>olka@chromium.org</owner> <owner>marinaciocea@chromium.org</owner> <owner>maxmorin@chromium.org</owner> @@ -118921,7 +118920,7 @@ </histogram> <histogram name="Signin.AccountTracker.CountOfLoadedAccounts" units="Accounts" - expires_after="M76"> + expires_after="M80"> <owner>msarda@chromium.org</owner> <owner>sdefresne@chromium.org</owner> <summary> @@ -118953,7 +118952,7 @@ </histogram> <histogram name="Signin.AccountTracker.GaiaIdMigrationState" - enum="OAuth2LoginAccountRevokedMigrationState" expires_after="M76"> + enum="OAuth2LoginAccountRevokedMigrationState" expires_after="M80"> <owner>msarda@chromium.org</owner> <owner>sdefresne@chromium.org</owner> <summary>
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc index 389e5303..7a819e0b 100644 --- a/ui/accessibility/platform/ax_platform_node_auralinux.cc +++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -1150,7 +1150,7 @@ if (selection_num != 0) return nullptr; - return obj->GetSelection(start_offset, end_offset); + return obj->GetSelectionWithText(start_offset, end_offset); } gboolean RemoveSelection(AtkText* atk_text, int selection_num) { @@ -3777,6 +3777,11 @@ if (offset < 0 || offset > character_count) offset = character_count; + // Even if we don't change anything, we still want to act like we + // were successful. + if (offset == GetCaretOffset() && !HasSelection()) + return true; + offset = UnicodeToUTF16OffsetInText(offset); if (!SetHypertextSelection(offset, offset)) return false; @@ -3796,10 +3801,23 @@ if (end_offset < 0 || end_offset > int{text.length()}) return false; - bool result = SetHypertextSelection(start_offset, end_offset); - if (result) - OnTextSelectionChanged(); - return result; + // We must put these in the correct order so that we can do + // a comparison with the existing start and end below. + if (end_offset < start_offset) + std::swap(start_offset, end_offset); + + // Even if we don't change anything, we still want to act like we + // were successful. + int old_start_offset, old_end_offset; + GetSelectionExtents(&old_start_offset, &old_end_offset); + if (old_start_offset == start_offset && old_end_offset == end_offset) + return true; + + if (!SetHypertextSelection(start_offset, end_offset)) + return false; + + OnTextSelectionChanged(); + return true; } bool AXPlatformNodeAuraLinux::HasSelection() { @@ -3809,10 +3827,8 @@ selection_start != selection_end; } -// Since this method doesn't return a static gchar*, we expect the caller of -// atk_text_get_selection to free the return value. -gchar* AXPlatformNodeAuraLinux::GetSelection(int* start_offset, - int* end_offset) { +void AXPlatformNodeAuraLinux::GetSelectionExtents(int* start_offset, + int* end_offset) { if (start_offset) *start_offset = 0; if (end_offset) @@ -3822,7 +3838,7 @@ GetSelectionOffsets(&selection_start, &selection_end); if (selection_start < 0 || selection_end < 0 || selection_start == selection_end) - return nullptr; + return; // We should ignore the direction of the selection when exposing start and // end offsets. According to the ATK documentation the end offset is always @@ -3838,6 +3854,22 @@ *start_offset = selection_start; if (end_offset) *end_offset = selection_end; +} + +// Since this method doesn't return a static gchar*, we expect the caller of +// atk_text_get_selection to free the return value. +gchar* AXPlatformNodeAuraLinux::GetSelectionWithText(int* start_offset, + int* end_offset) { + int selection_start, selection_end; + GetSelectionExtents(&selection_start, &selection_end); + if (start_offset) + *start_offset = selection_start; + if (end_offset) + *end_offset = selection_end; + + if (selection_start < 0 || selection_end < 0 || + selection_start == selection_end) + return nullptr; return atk_text::GetText(ATK_TEXT(atk_object_), selection_start, selection_end);
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.h b/ui/accessibility/platform/ax_platform_node_auralinux.h index 1e559ad..141013f 100644 --- a/ui/accessibility/platform/ax_platform_node_auralinux.h +++ b/ui/accessibility/platform/ax_platform_node_auralinux.h
@@ -131,7 +131,8 @@ bool SetCaretOffset(int offset); bool SetTextSelectionForAtkText(int start_offset, int end_offset); bool HasSelection(); - gchar* GetSelection(int* start_offset, int* end_offset); + void GetSelectionExtents(int* start_offset, int* end_offset); + gchar* GetSelectionWithText(int* start_offset, int* end_offset); std::string accessible_name_;
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc b/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc index df8eadd..346358b 100644 --- a/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc +++ b/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc
@@ -1356,16 +1356,23 @@ ASSERT_EQ(atk_text_get_caret_offset(atk_text), 4); ASSERT_EQ(caret_position_from_event, 4); + // Setting the same position should not trigger another event. caret_position_from_event = -1; + atk_text_set_caret_offset(atk_text, 4); + ASSERT_EQ(atk_text_get_caret_offset(atk_text), 4); + ASSERT_EQ(caret_position_from_event, -1); + int character_count = atk_text_get_character_count(atk_text); atk_text_set_caret_offset(atk_text, -1); ASSERT_EQ(atk_text_get_caret_offset(atk_text), character_count); ASSERT_EQ(caret_position_from_event, character_count); + atk_text_set_caret_offset(atk_text, 0); // Reset position. caret_position_from_event = -1; atk_text_set_caret_offset(atk_text, -1000); ASSERT_EQ(atk_text_get_caret_offset(atk_text), character_count); ASSERT_EQ(caret_position_from_event, character_count); + atk_text_set_caret_offset(atk_text, 0); // Reset position. caret_position_from_event = -1; atk_text_set_caret_offset(atk_text, 1000); @@ -1993,6 +2000,9 @@ EXPECT_EQ(selection_start, 0); EXPECT_EQ(selection_end, 1); + // Reset position. + EXPECT_TRUE(atk_text_set_selection(atk_text, 0, 0, 0)); + saw_selection_change = false; EXPECT_TRUE(atk_text_set_selection(atk_text, 0, 1, 0)); EXPECT_TRUE(saw_selection_change); @@ -2000,6 +2010,15 @@ EXPECT_EQ(selection_start, 0); EXPECT_EQ(selection_end, 1); + // Setting the selection to the same location should not trigger + // another event. + saw_selection_change = false; + EXPECT_TRUE(atk_text_set_selection(atk_text, 0, 1, 0)); + EXPECT_FALSE(saw_selection_change); + g_free(atk_text_get_selection(atk_text, 0, &selection_start, &selection_end)); + EXPECT_EQ(selection_start, 0); + EXPECT_EQ(selection_end, 1); + saw_selection_change = false; EXPECT_TRUE(atk_text_set_selection(atk_text, 0, 2, 4)); EXPECT_TRUE(saw_selection_change); @@ -2033,6 +2052,9 @@ EXPECT_TRUE(saw_selection_change); EXPECT_EQ(0, atk_text_get_n_selections(atk_text)); + // Reset position. + EXPECT_TRUE(atk_text_set_selection(atk_text, 0, 0, 0)); + saw_selection_change = false; EXPECT_TRUE(atk_text_set_selection(atk_text, 0, 0, 1)); EXPECT_EQ(1, atk_text_get_n_selections(atk_text));
diff --git a/ui/message_center/BUILD.gn b/ui/message_center/BUILD.gn index 010d522..cf5163b 100644 --- a/ui/message_center/BUILD.gn +++ b/ui/message_center/BUILD.gn
@@ -92,8 +92,6 @@ if (toolkit_views) { sources += [ - "views/bounded_label.cc", - "views/bounded_label.h", "views/desktop_popup_alignment_delegate.cc", "views/desktop_popup_alignment_delegate.h", "views/message_popup_collection.cc", @@ -126,16 +124,6 @@ "views/slide_out_controller.cc", "views/slide_out_controller.h", ] - if (!is_chromeos) { - sources += [ - "views/message_view_context_menu_controller.cc", - "views/message_view_context_menu_controller.h", - "views/notification_menu_model.cc", - "views/notification_menu_model.h", - "views/notification_view.cc", - "views/notification_view.h", - ] - } deps += [ "//ui/compositor", "//ui/events", @@ -223,23 +211,13 @@ if (toolkit_views) { sources += [ - "views/bounded_label_unittest.cc", "views/message_popup_collection_unittest.cc", "views/notification_header_view_unittest.cc", "views/notification_view_md_unittest.cc", "views/relative_time_formatter_unittest.cc", "views/slide_out_controller_unittest.cc", ] - if (!is_chromeos) { - sources += [ - "views/notification_menu_model_unittest.cc", - "views/notification_view_unittest.cc", - ] - } deps += [ - # Compositor is needed by message_center_view_unittest.cc and for the - # fonts used by bounded_label_unittest.cc. - "//ui/compositor", "//ui/display", "//ui/strings", "//ui/views",
diff --git a/ui/message_center/public/cpp/BUILD.gn b/ui/message_center/public/cpp/BUILD.gn index a647bb5..6dc7ee3 100644 --- a/ui/message_center/public/cpp/BUILD.gn +++ b/ui/message_center/public/cpp/BUILD.gn
@@ -9,8 +9,6 @@ output_name = "ui_message_center_cpp" sources = [ - "features.cc", - "features.h", "message_center_constants.h", "message_center_public_export.h", "notification.cc",
diff --git a/ui/message_center/public/cpp/features.cc b/ui/message_center/public/cpp/features.cc deleted file mode 100644 index 3b923d0..0000000 --- a/ui/message_center/public/cpp/features.cc +++ /dev/null
@@ -1,12 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/message_center/public/cpp/features.h" - -namespace message_center { - -const base::Feature kNewStyleNotifications{"NewStyleNotifications", - base::FEATURE_ENABLED_BY_DEFAULT}; - -} // namespace message_center
diff --git a/ui/message_center/public/cpp/features.h b/ui/message_center/public/cpp/features.h deleted file mode 100644 index dadaddb..0000000 --- a/ui/message_center/public/cpp/features.h +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_MESSAGE_CENTER_PUBLIC_CPP_FEATURES_H_ -#define UI_MESSAGE_CENTER_PUBLIC_CPP_FEATURES_H_ - -#include "base/feature_list.h" -#include "ui/message_center/public/cpp/message_center_public_export.h" - -namespace message_center { - -// This feature controls whether the new (material design) style notifications -// should be used. -MESSAGE_CENTER_PUBLIC_EXPORT extern const base::Feature kNewStyleNotifications; - -} // namespace message_center - -#endif // UI_MESSAGE_CENTER_PUBLIC_CPP_FEATURES_H_
diff --git a/ui/message_center/views/bounded_label.cc b/ui/message_center/views/bounded_label.cc deleted file mode 100644 index 9fb79a38..0000000 --- a/ui/message_center/views/bounded_label.cc +++ /dev/null
@@ -1,380 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/message_center/views/bounded_label.h" - -#include <stddef.h> - -#include <limits> - -#include "base/macros.h" -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" -#include "ui/gfx/canvas.h" -#include "ui/gfx/text_elider.h" -#include "ui/gfx/text_utils.h" -#include "ui/views/controls/label.h" - -namespace { - -const size_t kPreferredLinesCacheSize = 10; - -} // namespace - -namespace message_center { - -// InnerBoundedLabel /////////////////////////////////////////////////////////// - -// InnerBoundedLabel is a views::Label subclass that does all of the work for -// BoundedLabel. It is kept private to prevent outside code from calling a -// number of views::Label methods like SetFontList() that break BoundedLabel's -// caching but can't be overridden. -// -// TODO(dharcourt): Move the line limiting functionality to views::Label to make -// this unnecessary. - -class InnerBoundedLabel : public views::Label { - public: - InnerBoundedLabel(const BoundedLabel& owner); - ~InnerBoundedLabel() override; - - void SetNativeTheme(const ui::NativeTheme* theme); - - // Pass in a -1 width to use the preferred width, a -1 limit to skip limits. - int GetLinesForWidthAndLimit(int width, int limit); - gfx::Size GetSizeForWidthAndLines(int width, int lines); - std::vector<base::string16> GetWrappedText(int width, int lines); - - // Overridden from views::Label. - void SetText(const base::string16& new_text) override; - void OnPaint(gfx::Canvas* canvas) override; - - protected: - // Overridden from views::Label. - void OnBoundsChanged(const gfx::Rect& previous_bounds) override; - - private: - int GetTextFlags(); - - void ClearCaches(); - int GetCachedLines(int width); - void SetCachedLines(int width, int lines); - gfx::Size GetCachedSize(const std::pair<int, int>& width_and_lines); - void SetCachedSize(std::pair<int, int> width_and_lines, gfx::Size size); - - const BoundedLabel* owner_; // Weak reference. - base::string16 wrapped_text_; - int wrapped_text_width_; - int wrapped_text_lines_; - std::map<int, int> lines_cache_; - std::list<int> lines_widths_; // Most recently used in front. - std::map<std::pair<int, int>, gfx::Size> size_cache_; - std::list<std::pair<int, int> > size_widths_and_lines_; // Recent in front. - - DISALLOW_COPY_AND_ASSIGN(InnerBoundedLabel); -}; - -InnerBoundedLabel::InnerBoundedLabel(const BoundedLabel& owner) - : owner_(&owner), - wrapped_text_width_(0), - wrapped_text_lines_(0) { - SetMultiLine(true); - SetAllowCharacterBreak(true); - SetHorizontalAlignment(gfx::ALIGN_LEFT); - set_collapse_when_hidden(true); -} - -InnerBoundedLabel::~InnerBoundedLabel() { -} - -void InnerBoundedLabel::SetNativeTheme(const ui::NativeTheme* theme) { - ClearCaches(); - OnThemeChanged(); -} - -int InnerBoundedLabel::GetLinesForWidthAndLimit(int width, int limit) { - if (width == 0 || limit == 0) - return 0; - int lines = GetCachedLines(width); - if (lines == std::numeric_limits<int>::max()) { - int text_width = std::max(width - owner_->GetInsets().width(), 0); - lines = GetWrappedText(text_width, lines).size(); - SetCachedLines(width, lines); - } - return (limit < 0 || lines <= limit) ? lines : limit; -} - -gfx::Size InnerBoundedLabel::GetSizeForWidthAndLines(int width, int lines) { - if (width == 0 || lines == 0) - return gfx::Size(); - std::pair<int, int> key(width, lines); - gfx::Size size = GetCachedSize(key); - if (size.height() == std::numeric_limits<int>::max()) { - gfx::Insets insets = owner_->GetInsets(); - int text_width = (width < 0) ? std::numeric_limits<int>::max() : - std::max(width - insets.width(), 0); - int text_height = std::numeric_limits<int>::max(); - std::vector<base::string16> wrapped = GetWrappedText(text_width, lines); - gfx::Canvas::SizeStringInt( - base::JoinString(wrapped, base::ASCIIToUTF16("\n")), - font_list(), &text_width, &text_height, owner_->GetLineHeight(), - GetTextFlags()); - size.set_width(text_width + insets.width()); - size.set_height(text_height + insets.height()); - SetCachedSize(key, size); - } - return size; -} - -std::vector<base::string16> InnerBoundedLabel::GetWrappedText(int width, - int lines) { - // Short circuit simple case. - if (width == 0 || lines == 0) - return std::vector<base::string16>(); - - // Restrict line limit to ensure (lines + 1) * line_height <= INT_MAX and - // use it to calculate a reasonable text height. - int height = std::numeric_limits<int>::max(); - if (lines > 0) { - int line_height = std::max(font_list().GetHeight(), - 2); // At least 2 pixels. - int max_lines = std::numeric_limits<int>::max() / line_height - 1; - lines = std::min(lines, max_lines); - height = (lines + 1) * line_height; - } - - // Wrap, using INT_MAX for -1 widths that indicate no wrapping. - std::vector<base::string16> wrapped; - gfx::ElideRectangleText(text(), font_list(), - (width < 0) ? std::numeric_limits<int>::max() : width, - height, gfx::WRAP_LONG_WORDS, &wrapped); - - // Elide if necessary. - if (lines > 0 && wrapped.size() > static_cast<unsigned int>(lines)) { - // Add an ellipsis to the last line. If this ellipsis makes the last line - // too wide, that line will be further elided by the gfx::ElideText below, - // so for example "ABC" could become "ABC..." and then "AB...". - base::string16 last = - wrapped[lines - 1] + base::UTF8ToUTF16(gfx::kEllipsis); - if (width > 0 && gfx::GetStringWidth(last, font_list()) > width) - last = gfx::ElideText(last, font_list(), width, gfx::ELIDE_TAIL); - wrapped.resize(lines - 1); - wrapped.push_back(last); - } - - return wrapped; -} - -void InnerBoundedLabel::OnBoundsChanged(const gfx::Rect& previous_bounds) { - ClearCaches(); - views::Label::OnBoundsChanged(previous_bounds); -} - -void InnerBoundedLabel::OnPaint(gfx::Canvas* canvas) { - views::Label::OnPaintBackground(canvas); - views::Label::OnPaintBorder(canvas); - int lines = owner_->GetLineLimit(); - int height = GetSizeForWidthAndLines(width(), lines).height(); - if (height > 0) { - gfx::Rect bounds(width(), height); - bounds.Inset(owner_->GetInsets()); - if (bounds.width() != wrapped_text_width_ || lines != wrapped_text_lines_) { - wrapped_text_ = base::JoinString(GetWrappedText(bounds.width(), lines), - base::ASCIIToUTF16("\n")); - wrapped_text_width_ = bounds.width(); - wrapped_text_lines_ = lines; - } - bounds.set_x(GetMirroredXForRect(bounds)); - canvas->DrawStringRectWithFlags( - wrapped_text_, font_list(), enabled_color(), bounds, GetTextFlags()); - } -} - -void InnerBoundedLabel::SetText(const base::string16& new_text) { - if (text() == new_text) - return; - views::Label::SetText(new_text); - ClearCaches(); -} - -int InnerBoundedLabel::GetTextFlags() { - int flags = gfx::Canvas::MULTI_LINE | gfx::Canvas::CHARACTER_BREAKABLE; - - // We can't use subpixel rendering if the background is non-opaque. - if (SkColorGetA(background_color()) != 0xFF) - flags |= gfx::Canvas::NO_SUBPIXEL_RENDERING; - - return flags | gfx::Canvas::TEXT_ALIGN_TO_HEAD; -} - -void InnerBoundedLabel::ClearCaches() { - wrapped_text_width_ = 0; - wrapped_text_lines_ = 0; - lines_cache_.clear(); - lines_widths_.clear(); - size_cache_.clear(); - size_widths_and_lines_.clear(); -} - -int InnerBoundedLabel::GetCachedLines(int width) { - int lines = std::numeric_limits<int>::max(); - std::map<int, int>::const_iterator found; - if ((found = lines_cache_.find(width)) != lines_cache_.end()) { - lines = found->second; - lines_widths_.remove(width); - lines_widths_.push_front(width); - } - return lines; -} - -void InnerBoundedLabel::SetCachedLines(int width, int lines) { - if (lines_cache_.size() >= kPreferredLinesCacheSize) { - lines_cache_.erase(lines_widths_.back()); - lines_widths_.pop_back(); - } - lines_cache_[width] = lines; - lines_widths_.push_front(width); -} - -gfx::Size InnerBoundedLabel::GetCachedSize( - const std::pair<int, int>& width_and_lines) { - gfx::Size size(width_and_lines.first, std::numeric_limits<int>::max()); - std::map<std::pair<int, int>, gfx::Size>::const_iterator found; - if ((found = size_cache_.find(width_and_lines)) != size_cache_.end()) { - size = found->second; - size_widths_and_lines_.remove(width_and_lines); - size_widths_and_lines_.push_front(width_and_lines); - } - return size; -} - -void InnerBoundedLabel::SetCachedSize(std::pair<int, int> width_and_lines, - gfx::Size size) { - if (size_cache_.size() >= kPreferredLinesCacheSize) { - size_cache_.erase(size_widths_and_lines_.back()); - size_widths_and_lines_.pop_back(); - } - size_cache_[width_and_lines] = size; - size_widths_and_lines_.push_front(width_and_lines); -} - -// BoundedLabel /////////////////////////////////////////////////////////// - -BoundedLabel::BoundedLabel(const base::string16& text, - const gfx::FontList& font_list) - : line_limit_(-1), fixed_width_(0) { - label_.reset(new InnerBoundedLabel(*this)); - label_->SetFontList(font_list); - label_->SetText(text); -} - -BoundedLabel::BoundedLabel(const base::string16& text) - : line_limit_(-1), fixed_width_(0) { - label_.reset(new InnerBoundedLabel(*this)); - label_->SetText(text); -} - -BoundedLabel::~BoundedLabel() { -} - -void BoundedLabel::SetColor(SkColor text_color) { - label_->SetEnabledColor(text_color); - label_->SetAutoColorReadabilityEnabled(false); -} - -void BoundedLabel::SetLineHeight(int height) { - label_->SetLineHeight(height); -} - -void BoundedLabel::SetLineLimit(int lines) { - line_limit_ = std::max(lines, -1); -} - -void BoundedLabel::SetText(const base::string16& text) { - label_->SetText(text); -} - -int BoundedLabel::GetLineHeight() const { - return label_->line_height(); -} - -int BoundedLabel::GetLineLimit() const { - return line_limit_; -} - -const gfx::FontList& BoundedLabel::font_list() const { - return label_->font_list(); -} - -int BoundedLabel::GetLinesForWidthAndLimit(int width, int limit) { - return GetVisible() ? label_->GetLinesForWidthAndLimit(width, limit) : 0; -} - -gfx::Size BoundedLabel::GetSizeForWidthAndLines(int width, int lines) { - return GetVisible() ? label_->GetSizeForWidthAndLines(width, lines) - : gfx::Size(); -} - -void BoundedLabel::SizeToFit(int fixed_width) { - fixed_width_ = fixed_width; - label_->SizeToFit(fixed_width); -} - -int BoundedLabel::GetBaseline() const { - return label_->GetBaseline(); -} - -gfx::Size BoundedLabel::CalculatePreferredSize() const { - if (!GetVisible()) - return gfx::Size(); - return fixed_width_ != 0 - ? label_->GetSizeForWidthAndLines(fixed_width_, line_limit_) - : label_->GetSizeForWidthAndLines(-1, -1); -} - -int BoundedLabel::GetHeightForWidth(int width) const { - return GetVisible() - ? label_->GetSizeForWidthAndLines(width, line_limit_).height() - : 0; -} - -void BoundedLabel::OnPaint(gfx::Canvas* canvas) { - label_->OnPaint(canvas); -} - -bool BoundedLabel::CanProcessEventsWithinSubtree() const { - return label_->CanProcessEventsWithinSubtree(); -} - -void BoundedLabel::GetAccessibleNodeData(ui::AXNodeData* node_data) { - label_->GetAccessibleNodeData(node_data); -} - -views::View* BoundedLabel::GetTooltipHandlerForPoint(const gfx::Point& point) { - if (GetSizeForWidthAndLines(width(), -1).height() <= - GetHeightForWidth(width())) { - return nullptr; - } - return HitTestPoint(point) ? this : nullptr; -} - -base::string16 BoundedLabel::GetTooltipText(const gfx::Point& p) const { - return label_->GetTooltipText(p); -} - -void BoundedLabel::OnBoundsChanged(const gfx::Rect& previous_bounds) { - label_->SetBoundsRect(bounds()); - views::View::OnBoundsChanged(previous_bounds); -} - -void BoundedLabel::OnThemeChanged() { - label_->SetNativeTheme(GetNativeTheme()); -} - -base::string16 BoundedLabel::GetWrappedTextForTest(int width, int lines) { - return base::JoinString(label_->GetWrappedText(width, lines), - base::ASCIIToUTF16("\n")); -} - -} // namespace message_center
diff --git a/ui/message_center/views/bounded_label.h b/ui/message_center/views/bounded_label.h deleted file mode 100644 index 92c6af6..0000000 --- a/ui/message_center/views/bounded_label.h +++ /dev/null
@@ -1,86 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_MESSAGE_CENTER_BOUNDED_LABEL_H_ -#define UI_MESSAGE_CENTER_BOUNDED_LABEL_H_ - -#include <list> -#include <map> -#include <memory> - -#include "base/macros.h" -#include "third_party/skia/include/core/SkColor.h" -#include "ui/message_center/message_center_export.h" -#include "ui/views/view.h" - -namespace gfx { -class FontList; -} - -namespace message_center { - -class InnerBoundedLabel; - -namespace test { -class BoundedLabelTest; -} - -// BoundedLabels display left aligned text up to a maximum number of lines, with -// ellipsis at the end of the last line for any omitted text. BoundedLabel is a -// direct subclass of views::Views rather than a subclass of views::Label -// to avoid exposing some of views::Label's methods that can't be made to work -// with BoundedLabel. See the description of InnerBoundedLabel in the -// bounded_label.cc file for details. -class MESSAGE_CENTER_EXPORT BoundedLabel : public views::View { - public: - BoundedLabel(const base::string16& text, const gfx::FontList& font_list); - BoundedLabel(const base::string16& text); - ~BoundedLabel() override; - - void SetColor(SkColor text_color); - void SetLineHeight(int height); // Pass in 0 for default height. - void SetLineLimit(int lines); // Pass in -1 for no limit. - void SetText(const base::string16& text); // Additionally clears caches. - void SizeToFit(int fixed_width); // Same interface as Label::SizeToFit. - - int GetLineHeight() const; - int GetLineLimit() const; - - // Gets the FontList used by this label. - const gfx::FontList& font_list() const; - - // Pass in a -1 width to use the preferred width, a -1 limit to skip limits. - int GetLinesForWidthAndLimit(int width, int limit); - gfx::Size GetSizeForWidthAndLines(int width, int lines); - - // views::View: - int GetBaseline() const override; - gfx::Size CalculatePreferredSize() const override; - int GetHeightForWidth(int width) const override; - void OnPaint(gfx::Canvas* canvas) override; - bool CanProcessEventsWithinSubtree() const override; - void GetAccessibleNodeData(ui::AXNodeData* node_data) override; - views::View* GetTooltipHandlerForPoint(const gfx::Point& point) override; - base::string16 GetTooltipText(const gfx::Point& p) const override; - - protected: - // Overridden from views::View. - void OnBoundsChanged(const gfx::Rect& previous_bounds) override; - void OnThemeChanged() override; - - private: - friend class test::BoundedLabelTest; - - base::string16 GetWrappedTextForTest(int width, int lines); - - std::unique_ptr<InnerBoundedLabel> label_; - int line_limit_; - int fixed_width_; - - DISALLOW_COPY_AND_ASSIGN(BoundedLabel); -}; - -} // namespace message_center - -#endif // UI_MESSAGE_CENTER_BOUNDED_LABEL_H_
diff --git a/ui/message_center/views/bounded_label_unittest.cc b/ui/message_center/views/bounded_label_unittest.cc deleted file mode 100644 index 45e4560..0000000 --- a/ui/message_center/views/bounded_label_unittest.cc +++ /dev/null
@@ -1,231 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/message_center/views/bounded_label.h" - -#include <limits> - -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" -#include "build/build_config.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/gfx/font_list.h" -#include "ui/gfx/text_utils.h" -#include "ui/views/controls/label.h" -#include "ui/views/test/views_test_base.h" - -#if defined(OS_MACOSX) -#include "base/mac/mac_util.h" -#endif - -namespace message_center { - -namespace test { - -/* Test fixture ***************************************************************/ - -class BoundedLabelTest : public views::ViewsTestBase { - public: - BoundedLabelTest() { - digit_pixels_ = gfx::GetStringWidthF(base::UTF8ToUTF16("0"), font_list_); - space_pixels_ = gfx::GetStringWidthF(base::UTF8ToUTF16(" "), font_list_); - ellipsis_pixels_ = - gfx::GetStringWidthF(base::UTF8ToUTF16("\xE2\x80\xA6"), font_list_); - } - - ~BoundedLabelTest() override {} - - // Replaces all occurences of three periods ("...") in the specified string - // with an ellipses character (UTF8 "\xE2\x80\xA6") and returns a string16 - // with the results. This allows test strings to be specified as ASCII const - // char* strings, making tests more readable and easier to write. - base::string16 ToString(const char* string) { - const char kPeriods[] = "..."; - const char kEllipses[] = "\xE2\x80\xA6"; - std::string result = string; - base::ReplaceSubstringsAfterOffset(&result, 0, kPeriods, kEllipses); - return base::UTF8ToUTF16(result); - } - - // Converts the specified elision width to pixels. To make tests somewhat - // independent of the fonts of the platform on which they're run, the elision - // widths are specified as XYZ integers, with the corresponding width in - // pixels being X times the width of digit characters plus Y times the width - // of spaces plus Z times the width of ellipses in the default font of the - // test plaform. It is assumed that all digits have the same width in that - // font, that this width is greater than the width of spaces, and that the - // width of 3 digits is greater than the width of ellipses. - int ToPixels(int width) { - return std::ceil(digit_pixels_ * (width / 100) + - space_pixels_ * ((width % 100) / 10) + - ellipsis_pixels_ * (width % 10)); - } - - // Exercise BounderLabel::GetWrappedText() using the fixture's test label. - base::string16 GetWrappedText(int width) { - return label_->GetWrappedTextForTest(width, lines_); - } - - // Exercise BounderLabel::GetLinesForWidthAndLimit() using the test label. - int GetLinesForWidth(int width) { - label_->SetBounds(0, 0, width, font_list_.GetHeight() * lines_); - return label_->GetLinesForWidthAndLimit(width, lines_); - } - - protected: - // Creates a label to test with. Returns this fixture, which can be used to - // test the newly created label using the exercise methods above. - BoundedLabelTest& Label(base::string16 text, int lines) { - lines_ = lines; - label_.reset(new BoundedLabel(text, font_list_)); - label_->SetLineLimit(lines_); - return *this; - } - - private: - // The default font list, which will be used for tests. - gfx::FontList font_list_; - float digit_pixels_; - float space_pixels_; - float ellipsis_pixels_; - std::unique_ptr<BoundedLabel> label_; - int lines_; -}; - -/* Test macro *****************************************************************/ - -#define TEST_WRAP(expected, text, width, lines) \ - EXPECT_EQ(ToString(expected), \ - Label(ToString(text), lines).GetWrappedText(ToPixels(width))) - -#define TEST_LINES(expected, text, width, lines) \ - EXPECT_EQ(expected, \ - Label(ToString(text), lines).GetLinesForWidth(ToPixels(width))) - -/* Elision tests **************************************************************/ - -TEST_F(BoundedLabelTest, GetWrappedTextTest) { -#if defined(OS_MACOSX) - // Skip this test on macOS 10.10, which has slightly different font metrics - // than the other OSes we support. - if (base::mac::IsOS10_10()) - return; -#endif - - // One word per line: No ellision should be made when not necessary. - TEST_WRAP("123", "123", 301, 1); - TEST_WRAP("123", "123", 301, 2); - TEST_WRAP("123", "123", 301, 3); - TEST_WRAP("123\n456", "123 456", 301, 2); - TEST_WRAP("123\n456", "123 456", 301, 3); - TEST_WRAP("123\n456\n789", "123 456 789", 301, 3); - - // One word per line: Ellisions should be made when necessary. - TEST_WRAP("123...", "123 456", 302, 1); - TEST_WRAP("123...", "123 456 789", 302, 1); - TEST_WRAP("123\n456...", "123 456 789", 302, 2); - - // Two words per line: No ellision should be made when not necessary. - TEST_WRAP("123 456", "123 456", 621, 1); - TEST_WRAP("123 456", "123 456", 621, 2); - TEST_WRAP("123 456", "123 456", 621, 3); - TEST_WRAP("123 456\n789 012", "123 456 789 012", 621, 2); - TEST_WRAP("123 456\n789 012", "123 456 789 012", 621, 3); - TEST_WRAP("123 456\n789 012\n345 678", "123 456 789 012 345 678", 621, 3); - - // Two words per line: Ellisions should be made when necessary. - TEST_WRAP("123 456...", "123 456 789 012", 621, 1); - TEST_WRAP("123 456...", "123 456 789 012 345 678", 621, 1); - TEST_WRAP("123 456\n789 012...", "123 456 789 012 345 678", 621, 2); - - // Single trailing spaces: No ellipses should be added. - TEST_WRAP("123", "123 ", 301, 1); - TEST_WRAP("123\n456", "123 456 ", 301, 2); - TEST_WRAP("123\n456\n789", "123 456 789 ", 301, 3); - TEST_WRAP("123 456", "123 456 ", 611, 1); - TEST_WRAP("123 456\n789 012", "123 456 789 012 ", 611, 2); - TEST_WRAP("123 456\n789 012\n345 678", "123 456 789 012 345 678 ", 611, 3); - - // Multiple trailing spaces: No ellipses should be added. - TEST_WRAP("123", "123 ", 301, 1); - TEST_WRAP("123\n456", "123 456 ", 301, 2); - TEST_WRAP("123\n456\n789", "123 456 789 ", 301, 3); - TEST_WRAP("123 456", "123 456 ", 611, 1); - TEST_WRAP("123 456\n789 012", "123 456 789 012 ", 611, 2); - TEST_WRAP("123 456\n789 012\n345 678", - "123 456 789 012 345 678 ", 611, 3); - - // Multiple spaces between words on the same line: Spaces should be preserved. - // Test cases for single spaces between such words are included in the "Two - // words per line" sections above. - TEST_WRAP("123 456", "123 456", 621, 1); - TEST_WRAP("123 456...", "123 456 789 012", 631, 1); - TEST_WRAP("123 456\n789 012", "123 456 789 012", 631, 2); - TEST_WRAP("123 456...", "123 456 789 012 345 678", 621, 1); - TEST_WRAP("123 456\n789 012...", "123 456 789 012 345 678", 631, 2); - TEST_WRAP("123 456\n789 012\n345 678", - "123 456 789 012 345 678", 641, 3); - - // Multiple spaces between words split across lines: Spaces should be removed - // even if lines are wide enough to include those spaces. Test cases for - // single spaces between such words are included in the "Two words per line" - // sections above. - TEST_WRAP("123\n456", "123 456", 321, 2); - TEST_WRAP("123\n456", "123 456", 391, 2); - TEST_WRAP("123\n456...", "123 456 789", 321, 2); - TEST_WRAP("123\n456...", "123 456 789", 391, 2); - TEST_WRAP("123 456\n789 012", "123 456 789 012", 641, 2); - TEST_WRAP("123 456\n789 012...", "123 456 789 012 345 678", 641, 2); - - // Long words without spaces should be wrapped when necessary. - TEST_WRAP("123\n456", "123456", 300, 9); - - // TODO(dharcourt): Add test cases to verify that: - // - Spaces before elisions are removed - // - Leading spaces are preserved - // - Words are split when they are longer than lines - // - Words are clipped when they are longer than the last line - // - No blank line are created before or after clipped word - // - Spaces at the end of the text are removed - - // TODO(dharcourt): Add test cases for: - // - Empty and very large strings - // - Zero, very large, and negative line limit values - // - Other input boundary conditions - // TODO(dharcourt): Add some randomly generated fuzz test cases. -} - -/* GetLinesTest ***************************************************************/ - -TEST_F(BoundedLabelTest, GetLinesTest) { - // Zero and negative width values should yield zero lines. - TEST_LINES(0, "123 456", 0, 1); - TEST_LINES(0, "123 456", -1, 1); - TEST_LINES(0, "123 456", -2, 1); - TEST_LINES(0, "123 456", std::numeric_limits<int>::min(), 1); - - // Small width values should yield one word per line. - TEST_LINES(1, "123 456", 1, 1); - TEST_LINES(2, "123 456", 1, 2); - TEST_LINES(1, "123 456", 2, 1); - TEST_LINES(2, "123 456", 2, 2); - TEST_LINES(1, "123 456", 3, 1); - TEST_LINES(2, "123 456", 3, 2); - - // Large width values should yield all words on one line. - TEST_LINES(1, "123 456", 610, 1); - TEST_LINES(1, "123 456", std::numeric_limits<int>::max(), 1); -} - -/* Other tests ****************************************************************/ - -// TODO(dharcourt): Add test cases to verify that: -// - SetMaxLines() affects the return values of some methods but not others. -// - Bound changes affects GetPreferredLines(), GetTextSize(), and -// GetWrappedText() return values. -// - GetTextFlags are as expected. - -} // namespace test - -} // namespace message_center
diff --git a/ui/message_center/views/message_popup_view.cc b/ui/message_center/views/message_popup_view.cc index a4e333c5..33f2ca7 100644 --- a/ui/message_center/views/message_popup_view.cc +++ b/ui/message_center/views/message_popup_view.cc
@@ -4,7 +4,6 @@ #include "ui/message_center/views/message_popup_view.h" -#include "base/feature_list.h" #include "build/build_config.h" #include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_node_data.h" @@ -12,11 +11,9 @@ #include "ui/aura/window_targeter.h" #include "ui/display/display.h" #include "ui/display/screen.h" -#include "ui/message_center/public/cpp/features.h" #include "ui/message_center/public/cpp/message_center_constants.h" #include "ui/message_center/views/message_popup_collection.h" #include "ui/message_center/views/message_view.h" -#include "ui/message_center/views/message_view_context_menu_controller.h" #include "ui/message_center/views/message_view_factory.h" #include "ui/message_center/views/popup_alignment_delegate.h" #include "ui/views/layout/fill_layout.h" @@ -37,14 +34,6 @@ a11y_feedback_on_init_( notification.rich_notification_data() .should_make_spoken_feedback_for_popup_updates) { -#if !defined(OS_CHROMEOS) - if (!base::FeatureList::IsEnabled(message_center::kNewStyleNotifications)) { - context_menu_controller_ = - std::make_unique<MessageViewContextMenuController>(); - message_view_->set_context_menu_controller(context_menu_controller_.get()); - } -#endif - SetLayoutManager(std::make_unique<views::FillLayout>()); if (!message_view_->IsManuallyExpandedOrCollapsed())
diff --git a/ui/message_center/views/message_popup_view.h b/ui/message_center/views/message_popup_view.h index 0be0187b..629d2da8 100644 --- a/ui/message_center/views/message_popup_view.h +++ b/ui/message_center/views/message_popup_view.h
@@ -13,7 +13,6 @@ class MessagePopupCollection; class MessageView; -class MessageViewContextMenuController; class Notification; class PopupAlignmentDelegate; @@ -81,8 +80,6 @@ PopupAlignmentDelegate* const alignment_delegate_; MessagePopupCollection* const popup_collection_; - std::unique_ptr<MessageViewContextMenuController> context_menu_controller_; - const bool a11y_feedback_on_init_; bool is_hovered_ = false; bool is_active_ = false;
diff --git a/ui/message_center/views/message_view.cc b/ui/message_center/views/message_view.cc index 8f75d860..65bee0e 100644 --- a/ui/message_center/views/message_view.cc +++ b/ui/message_center/views/message_view.cc
@@ -4,13 +4,11 @@ #include "ui/message_center/views/message_view.h" -#include "base/feature_list.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_node_data.h" #include "ui/base/l10n/l10n_util.h" -#include "ui/base/models/simple_menu_model.h" #include "ui/compositor/paint_recorder.h" #include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/gfx/canvas.h" @@ -18,7 +16,6 @@ #include "ui/gfx/shadow_util.h" #include "ui/gfx/shadow_value.h" #include "ui/message_center/message_center.h" -#include "ui/message_center/public/cpp/features.h" #include "ui/message_center/public/cpp/message_center_constants.h" #include "ui/message_center/views/notification_background_painter.h" #include "ui/message_center/views/notification_control_buttons_view.h"
diff --git a/ui/message_center/views/message_view_context_menu_controller.cc b/ui/message_center/views/message_view_context_menu_controller.cc deleted file mode 100644 index 8b043ca..0000000 --- a/ui/message_center/views/message_view_context_menu_controller.cc +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/message_center/views/message_view_context_menu_controller.h" - -#include "base/bind.h" -#include "ui/base/models/menu_model.h" -#include "ui/message_center/message_center.h" -#include "ui/message_center/views/message_view.h" -#include "ui/message_center/views/notification_menu_model.h" -#include "ui/views/controls/menu/menu_model_adapter.h" -#include "ui/views/controls/menu/menu_runner.h" -#include "ui/views/widget/widget.h" - -namespace message_center { - -MessageViewContextMenuController::MessageViewContextMenuController() = default; - -MessageViewContextMenuController::~MessageViewContextMenuController() = default; - -void MessageViewContextMenuController::ShowContextMenuForViewImpl( - views::View* source, - const gfx::Point& point, - ui::MenuSourceType source_type) { - // Assumes that the target view has to be MessageView. - MessageView* message_view = static_cast<MessageView*>(source); - Notification* notification = - MessageCenter::Get()->FindVisibleNotificationById( - message_view->notification_id()); - - // Notification is null if the notification view is being removed or some - // invalid status. In this case, just returns. - if (!notification) - return; - - menu_model_ = std::make_unique<NotificationMenuModel>(*notification); - - if (!menu_model_ || menu_model_->GetItemCount() == 0) - return; - - menu_runner_ = std::make_unique<views::MenuRunner>( - menu_model_.get(), views::MenuRunner::HAS_MNEMONICS, - base::Bind(&MessageViewContextMenuController::OnMenuClosed, - base::Unretained(this))); - - menu_runner_->RunMenuAt(source->GetWidget()->GetTopLevelWidget(), NULL, - gfx::Rect(point, gfx::Size()), - views::MenuAnchorPosition::kTopRight, source_type); -} - -void MessageViewContextMenuController::OnMenuClosed() { - menu_runner_.reset(); - menu_model_.reset(); -} - -} // namespace message_center
diff --git a/ui/message_center/views/message_view_context_menu_controller.h b/ui/message_center/views/message_view_context_menu_controller.h deleted file mode 100644 index 00bf172..0000000 --- a/ui/message_center/views/message_view_context_menu_controller.h +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_MESSAGE_CENTER_VIEWS_MESSAGE_VIEW_CONTEXT_MENU_CONTROLLER_H_ -#define UI_MESSAGE_CENTER_VIEWS_MESSAGE_VIEW_CONTEXT_MENU_CONTROLLER_H_ - -#include <memory> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "ui/message_center/message_center_export.h" -#include "ui/views/context_menu_controller.h" - -namespace ui { -class MenuModel; -} // namespace ui - -namespace views { -class MenuRunner; -} // namespace views - -namespace message_center { - -class MESSAGE_CENTER_EXPORT MessageViewContextMenuController - : public views::ContextMenuController { - public: - explicit MessageViewContextMenuController(); - ~MessageViewContextMenuController() override; - - private: - // Overridden from views::ContextMenuController: - void ShowContextMenuForViewImpl(views::View* source, - const gfx::Point& point, - ui::MenuSourceType source_type) override; - - // Callback for MenuRunner - void OnMenuClosed(); - - std::unique_ptr<ui::MenuModel> menu_model_; - std::unique_ptr<views::MenuRunner> menu_runner_; - - DISALLOW_COPY_AND_ASSIGN(MessageViewContextMenuController); -}; - -} // namespace message_center - -#endif // UI_MESSAGE_CENTER_VIEWS_MESSAGE_VIEW_CONTEXT_MENU_CONTROLLER_H_
diff --git a/ui/message_center/views/message_view_factory.cc b/ui/message_center/views/message_view_factory.cc index 8db23c8..e391549 100644 --- a/ui/message_center/views/message_view_factory.cc +++ b/ui/message_center/views/message_view_factory.cc
@@ -6,17 +6,10 @@ #include <vector> -#include "base/command_line.h" -#include "base/feature_list.h" #include "base/lazy_instance.h" -#include "ui/message_center/public/cpp/features.h" #include "ui/message_center/public/cpp/notification_types.h" #include "ui/message_center/views/notification_view_md.h" -#if !defined(OS_CHROMEOS) -#include "ui/message_center/views/notification_view.h" -#endif - namespace message_center { namespace { @@ -63,17 +56,8 @@ break; } - if (!notification_view) { -#if defined(OS_CHROMEOS) + if (!notification_view) notification_view = new NotificationViewMD(notification); -#else - // All above roads lead to the generic NotificationView. - if (base::FeatureList::IsEnabled(message_center::kNewStyleNotifications)) - notification_view = new NotificationViewMD(notification); - else - notification_view = new NotificationView(notification); -#endif - } return notification_view; }
diff --git a/ui/message_center/views/notification_menu_model.cc b/ui/message_center/views/notification_menu_model.cc deleted file mode 100644 index 0f88fa8..0000000 --- a/ui/message_center/views/notification_menu_model.cc +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/message_center/views/notification_menu_model.h" - -#include <memory> - -#include "base/macros.h" -#include "base/strings/utf_string_conversions.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/models/simple_menu_model.h" -#include "ui/message_center/message_center.h" -#include "ui/strings/grit/ui_strings.h" - -namespace message_center { - -namespace { - -// Menu constants -const int kTogglePermissionCommand = 0; - -} // namespace - -NotificationMenuModel::NotificationMenuModel(const Notification& notification) - : ui::SimpleMenuModel(this), notification_id_(notification.id()) { - DCHECK(!notification.display_source().empty()); - AddItem(kTogglePermissionCommand, - l10n_util::GetStringFUTF16(IDS_MESSAGE_CENTER_NOTIFIER_DISABLE, - notification.display_source())); -} - -NotificationMenuModel::~NotificationMenuModel() {} - -bool NotificationMenuModel::IsCommandIdChecked(int command_id) const { - return false; -} - -bool NotificationMenuModel::IsCommandIdEnabled(int command_id) const { - // TODO(estade): commands shouldn't always be enabled. For example, a - // notification's enabled state might be controlled by policy. See - // http://crbug.com/771269 - return true; -} - -void NotificationMenuModel::ExecuteCommand(int command_id, int event_flags) { - DCHECK_EQ(command_id, kTogglePermissionCommand); - MessageCenter::Get()->DisableNotification(notification_id_); -} - -} // namespace message_center
diff --git a/ui/message_center/views/notification_menu_model.h b/ui/message_center/views/notification_menu_model.h deleted file mode 100644 index 22658b74..0000000 --- a/ui/message_center/views/notification_menu_model.h +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_MESSAGE_CENTER_NOTIFICATION_MENU_MODEL_H_ -#define UI_MESSAGE_CENTER_NOTIFICATION_MENU_MODEL_H_ - -#include "base/macros.h" -#include "ui/base/models/simple_menu_model.h" -#include "ui/message_center/message_center_export.h" -#include "ui/message_center/public/cpp/notification.h" - -namespace message_center { - -// The model of the context menu for a notification card. -class MESSAGE_CENTER_EXPORT NotificationMenuModel - : public ui::SimpleMenuModel, - public ui::SimpleMenuModel::Delegate { - public: - NotificationMenuModel(const Notification& notification); - ~NotificationMenuModel() override; - - // Overridden from ui::SimpleMenuModel::Delegate: - bool IsCommandIdChecked(int command_id) const override; - bool IsCommandIdEnabled(int command_id) const override; - void ExecuteCommand(int command_id, int event_flags) override; - - private: - const std::string notification_id_; - DISALLOW_COPY_AND_ASSIGN(NotificationMenuModel); -}; - -} // namespace message_center - -#endif // UI_MESSAGE_CENTER_UI_CONTROLLER_H_
diff --git a/ui/message_center/views/notification_menu_model_unittest.cc b/ui/message_center/views/notification_menu_model_unittest.cc deleted file mode 100644 index 937ed1c1..0000000 --- a/ui/message_center/views/notification_menu_model_unittest.cc +++ /dev/null
@@ -1,102 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/message_center/views/notification_menu_model.h" - -#include <utility> - -#include "base/macros.h" -#include "base/strings/utf_string_conversions.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/base/models/menu_model.h" -#include "ui/message_center/message_center.h" -#include "ui/message_center/public/cpp/notification.h" -#include "ui/message_center/public/cpp/notification_types.h" - -namespace message_center { -namespace { - -class TestNotificationDelegate : public NotificationDelegate { - public: - TestNotificationDelegate() = default; - - private: - ~TestNotificationDelegate() override = default; - - DISALLOW_COPY_AND_ASSIGN(TestNotificationDelegate); -}; - -} // namespace - -class NotificationMenuModelTest : public testing::Test { - public: - NotificationMenuModelTest() = default; - ~NotificationMenuModelTest() override = default; - - void SetUp() override { - MessageCenter::Initialize(); - message_center_ = MessageCenter::Get(); - } - - void TearDown() override { - message_center_ = NULL; - MessageCenter::Shutdown(); - } - - protected: - NotifierId DummyNotifierId() { return NotifierId(); } - - Notification* AddNotification(const std::string& id) { - return AddNotification(id, DummyNotifierId()); - } - - Notification* AddNotification(const std::string& id, NotifierId notifier_id) { - std::unique_ptr<Notification> notification(new Notification( - NOTIFICATION_TYPE_SIMPLE, id, - base::ASCIIToUTF16("Test Web Notification"), - base::ASCIIToUTF16("Notification message body."), gfx::Image(), - base::ASCIIToUTF16("www.test.org"), GURL(), notifier_id, - RichNotificationData(), new TestNotificationDelegate())); - Notification* notification_ptr = notification.get(); - message_center_->AddNotification(std::move(notification)); - return notification_ptr; - } - MessageCenter* message_center_; - - private: - DISALLOW_COPY_AND_ASSIGN(NotificationMenuModelTest); -}; - -TEST_F(NotificationMenuModelTest, ContextMenuTestWithMessageCenter) { - const std::string id1 = "id1"; - const std::string id2 = "id2"; - const std::string id3 = "id3"; - AddNotification(id1); - - base::string16 display_source = base::ASCIIToUTF16("www.test.org"); - NotifierId notifier_id = DummyNotifierId(); - - NotifierId notifier_id2(NotifierType::APPLICATION, "sample-app"); - std::unique_ptr<Notification> notification = std::make_unique<Notification>( - NOTIFICATION_TYPE_SIMPLE, id2, - base::ASCIIToUTF16("Test Web Notification"), - base::ASCIIToUTF16("Notification message body."), gfx::Image(), - display_source, GURL(), notifier_id2, RichNotificationData(), - new TestNotificationDelegate()); - - std::unique_ptr<ui::MenuModel> model( - std::make_unique<NotificationMenuModel>(*notification)); - message_center_->AddNotification(std::move(notification)); - - AddNotification(id3); - EXPECT_EQ(1, model->GetItemCount()); - - // The first item is to disable notifications from the notifier id. It also - // removes the notification. - EXPECT_EQ(3u, message_center_->GetVisibleNotifications().size()); - model->ActivatedAt(0); - EXPECT_EQ(2u, message_center_->GetVisibleNotifications().size()); -} - -} // namespace message_center
diff --git a/ui/message_center/views/notification_view.cc b/ui/message_center/views/notification_view.cc deleted file mode 100644 index dd8798b..0000000 --- a/ui/message_center/views/notification_view.cc +++ /dev/null
@@ -1,657 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/message_center/views/notification_view.h" - -#include <stddef.h> - -#include "base/command_line.h" -#include "base/macros.h" -#include "base/strings/string_util.h" -#include "build/build_config.h" -#include "components/url_formatter/elide_url.h" -#include "third_party/skia/include/core/SkPaint.h" -#include "third_party/skia/include/core/SkPath.h" -#include "ui/base/cursor/cursor.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/layout.h" -#include "ui/gfx/canvas.h" -#include "ui/gfx/geometry/insets.h" -#include "ui/gfx/geometry/size.h" -#include "ui/gfx/skia_util.h" -#include "ui/gfx/text_elider.h" -#include "ui/message_center/message_center.h" -#include "ui/message_center/message_center_style.h" -#include "ui/message_center/public/cpp/message_center_constants.h" -#include "ui/message_center/public/cpp/notification.h" -#include "ui/message_center/public/cpp/notification_types.h" -#include "ui/message_center/views/bounded_label.h" -#include "ui/message_center/views/notification_button.h" -#include "ui/message_center/views/notification_control_buttons_view.h" -#include "ui/message_center/views/padded_button.h" -#include "ui/message_center/views/proportional_image_view.h" -#include "ui/native_theme/native_theme.h" -#include "ui/strings/grit/ui_strings.h" -#include "ui/views/background.h" -#include "ui/views/border.h" -#include "ui/views/controls/button/image_button.h" -#include "ui/views/controls/image_view.h" -#include "ui/views/controls/label.h" -#include "ui/views/controls/progress_bar.h" -#include "ui/views/layout/box_layout.h" -#include "ui/views/layout/fill_layout.h" -#include "ui/views/native_cursor.h" -#include "ui/views/painter.h" -#include "ui/views/widget/widget.h" -#include "url/gurl.h" - -namespace message_center { - -namespace { - -const int kTextBottomPadding = 12; -const int kItemTitleToMessagePadding = 3; - -// Character limit = pixels per line * line limit / min. pixels per character. -const int kMinPixelsPerTitleCharacter = 4; - -constexpr size_t kMessageCharacterLimit = - kNotificationWidth * kMessageExpandedLineLimit / 3; - -constexpr size_t kContextMessageCharacterLimit = - kNotificationWidth * kContextMessageLineLimit / 3; - -// Dimensions. -const int kProgressBarBottomPadding = 0; - -// static -std::unique_ptr<views::Border> MakeEmptyBorder(int top, - int left, - int bottom, - int right) { - return views::CreateEmptyBorder(top, left, bottom, right); -} - -// static -std::unique_ptr<views::Border> MakeTextBorder(int padding, - int top, - int bottom) { - // Split the padding between the top and the bottom, then add the extra space. - return MakeEmptyBorder(padding / 2 + top, kTextLeftPadding, - (padding + 1) / 2 + bottom, kTextRightPadding); -} - -// static -std::unique_ptr<views::Border> MakeProgressBarBorder(int top, int bottom) { - return MakeEmptyBorder(top, kTextLeftPadding, bottom, kTextRightPadding); -} - -// static -std::unique_ptr<views::Border> MakeSeparatorBorder(int top, - int left, - SkColor color) { - return views::CreateSolidSidedBorder(top, left, 0, 0, color); -} - -#if !defined(OS_CHROMEOS) -// static -void SetBorderRight(views::View* view, int right) { - const gfx::Insets& insets = view->GetInsets(); - if (insets.right() != right) { - view->SetBorder( - MakeEmptyBorder(insets.top(), insets.left(), insets.bottom(), right)); - } -} -#endif - -// NotificationItemView //////////////////////////////////////////////////////// - -// NotificationItemViews are responsible for drawing each list notification -// item's title and message next to each other within a single column. -class NotificationItemView : public views::View { - public: - explicit NotificationItemView(const NotificationItem& item); - private: - DISALLOW_COPY_AND_ASSIGN(NotificationItemView); -}; - -NotificationItemView::NotificationItemView(const NotificationItem& item) { - SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), - kItemTitleToMessagePadding)); - - views::Label* title = new views::Label(item.title); - title->set_collapse_when_hidden(true); - title->SetHorizontalAlignment(gfx::ALIGN_LEFT); - title->SetEnabledColor(kRegularTextColor); - title->SetAutoColorReadabilityEnabled(false); - AddChildView(title); - - views::Label* message = new views::Label(item.message); - message->set_collapse_when_hidden(true); - message->SetHorizontalAlignment(gfx::ALIGN_LEFT); - message->SetEnabledColor(kDimTextColor); - message->SetAutoColorReadabilityEnabled(false); - AddChildView(message); - - PreferredSizeChanged(); - SchedulePaint(); -} - -} // namespace - -// NotificationView //////////////////////////////////////////////////////////// - -void NotificationView::CreateOrUpdateViews(const Notification& notification) { - top_view_count_ = 0; - - CreateOrUpdateTitleView(notification); - CreateOrUpdateMessageView(notification); - CreateOrUpdateProgressBarView(notification); - CreateOrUpdateListItemViews(notification); - CreateOrUpdateIconView(notification); - CreateOrUpdateSmallIconView(notification); - CreateOrUpdateImageView(notification); - CreateOrUpdateContextMessageView(notification); - CreateOrUpdateActionButtonViews(notification); -} - -NotificationView::NotificationView(const Notification& notification) - : MessageView(notification) { - // Create the top_view_, which collects into a vertical box all content - // at the top of the notification (to the right of the icon) except for the - // close button. - top_view_ = new views::View(); - top_view_->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); - top_view_->SetBorder( - MakeEmptyBorder(kTextTopPadding - 8, 0, kTextBottomPadding - 5, 0)); - AddChildView(top_view_); - // Create the bottom_view_, which collects into a vertical box all content - // below the notification icon. - bottom_view_ = new views::View(); - bottom_view_->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); - AddChildView(bottom_view_); - - control_buttons_view_ = new NotificationControlButtonsView(this); - AddChildView(control_buttons_view_); - - views::ImageView* small_image_view = new views::ImageView(); - small_image_view->SetImageSize(gfx::Size(kSmallImageSize, kSmallImageSize)); - small_image_view->set_owned_by_client(); - small_image_view_.reset(small_image_view); - - CreateOrUpdateViews(notification); - - // Put together the different content and control views. Layering those allows - // for proper layout logic and it also allows the control buttons and small - // image to overlap the content as needed to provide large enough click and - // touch areas (<http://crbug.com/168822> and <http://crbug.com/168856>). - AddChildView(small_image_view_.get()); - UpdateControlButtonsVisibilityWithNotification(notification); - - set_notify_enter_exit_on_child(true); -} - -NotificationView::~NotificationView() { -} - -gfx::Size NotificationView::CalculatePreferredSize() const { - int top_width = top_view_->GetPreferredSize().width() + - icon_view_->GetPreferredSize().width(); - int bottom_width = bottom_view_->GetPreferredSize().width(); - int preferred_width = std::max(top_width, bottom_width) + GetInsets().width(); - return gfx::Size(preferred_width, GetHeightForWidth(preferred_width)); -} - -int NotificationView::GetHeightForWidth(int width) const { - // Get the height assuming no line limit changes. - int content_width = width - GetInsets().width(); - int top_height = top_view_->GetHeightForWidth(content_width); - int bottom_height = bottom_view_->GetHeightForWidth(content_width); - - // <http://crbug.com/230448> Fix: Adjust the height when the message_view's - // line limit would be different for the specified width than it currently is. - // TODO(dharcourt): Avoid BoxLayout and directly compute the correct height. - if (message_view_) { - int title_lines = 0; - if (title_view_) { - title_lines = title_view_->GetLinesForWidthAndLimit(width, - kMaxTitleLines); - } - int used_limit = message_view_->GetLineLimit(); - int correct_limit = GetMessageLineLimit(title_lines, width); - if (used_limit != correct_limit) { - top_height -= GetMessageHeight(content_width, used_limit); - top_height += GetMessageHeight(content_width, correct_limit); - } - } - - int content_height = - std::max(top_height, kNotificationIconSize) + bottom_height; - - // Adjust the height to make sure there is at least 16px of space below the - // icon if there is any space there (<http://crbug.com/232966>). - if (content_height > kNotificationIconSize) { - content_height = - std::max(content_height, kNotificationIconSize + kIconBottomPadding); - } - - return content_height + GetInsets().height(); -} - -void NotificationView::Layout() { - // |ShrinkTopmostLabel| updates the borders of views to make space for the - // control buttons. We have to update the borders before calling - // |MessageView::Layout| so that the latest values get taken into account - // while layouting. As |ShrinkTopmostLabel| only depends on the PreferredSize, - // this is valid to do before calling |MessageView::Layout|. - ShrinkTopmostLabel(); - MessageView::Layout(); - - gfx::Insets insets = GetInsets(); - int content_width = width() - insets.width(); - gfx::Rect content_bounds = GetContentsBounds(); - - // Before any resizing, set or adjust the number of message lines. - int title_lines = 0; - if (title_view_) { - title_lines = - title_view_->GetLinesForWidthAndLimit(width(), kMaxTitleLines); - } - if (message_view_) - message_view_->SetLineLimit(GetMessageLineLimit(title_lines, width())); - - // Top views. - int top_height = top_view_->GetHeightForWidth(content_width); - top_view_->SetBounds(insets.left(), insets.top(), content_width, top_height); - - // Icon. - icon_view_->SetBounds(insets.left(), insets.top(), kNotificationIconSize, - kNotificationIconSize); - - // Control buttons (close and settings buttons). - gfx::Rect control_buttons_bounds(content_bounds); - int buttons_width = control_buttons_view_->GetPreferredSize().width(); - int buttons_height = control_buttons_view_->GetPreferredSize().height(); - control_buttons_bounds.set_x(control_buttons_bounds.right() - buttons_width - - kControlButtonPadding); - control_buttons_bounds.set_y(control_buttons_bounds.y() + - kControlButtonPadding); - control_buttons_bounds.set_width(buttons_width); - control_buttons_bounds.set_height(buttons_height); - control_buttons_view_->SetBoundsRect(control_buttons_bounds); - - // Small icon. - gfx::Size small_image_size(small_image_view_->GetPreferredSize()); - gfx::Rect small_image_rect(small_image_size); - small_image_rect.set_origin(gfx::Point( - content_bounds.right() - small_image_size.width() - kSmallImagePadding, - content_bounds.bottom() - small_image_size.height() - - kSmallImagePadding)); - small_image_view_->SetBoundsRect(small_image_rect); - - // Bottom views. - int bottom_y = insets.top() + std::max(top_height, kNotificationIconSize); - int bottom_height = bottom_view_->GetHeightForWidth(content_width); - bottom_view_->SetBounds(insets.left(), bottom_y, - content_width, bottom_height); -} - -void NotificationView::OnFocus() { - MessageView::OnFocus(); - ScrollRectToVisible(GetLocalBounds()); -} - -void NotificationView::ScrollRectToVisible(const gfx::Rect& rect) { - // Notification want to show the whole notification when a part of it (like - // a button) gets focused. - views::View::ScrollRectToVisible(GetLocalBounds()); -} - -void NotificationView::OnMouseEntered(const ui::MouseEvent& event) { - MessageView::OnMouseEntered(event); - UpdateControlButtonsVisibility(); -} - -void NotificationView::OnMouseExited(const ui::MouseEvent& event) { - MessageView::OnMouseExited(event); - UpdateControlButtonsVisibility(); -} - -void NotificationView::UpdateWithNotification( - const Notification& notification) { - MessageView::UpdateWithNotification(notification); - - CreateOrUpdateViews(notification); - UpdateControlButtonsVisibilityWithNotification(notification); - Layout(); - SchedulePaint(); -} - -void NotificationView::ButtonPressed(views::Button* sender, - const ui::Event& event) { - // Certain operations can cause |this| to be destructed, so copy the members - // we send to other parts of the code. - // TODO(dewittj): Remove this hack. - std::string id(notification_id()); - - // See if the button pressed was an action button. - for (size_t i = 0; i < action_buttons_.size(); ++i) { - if (sender == action_buttons_[i]) { - MessageCenter::Get()->ClickOnNotificationButton(id, i); - return; - } - } - - NOTREACHED(); -} - -void NotificationView::CreateOrUpdateTitleView( - const Notification& notification) { - if (notification.title().empty()) { - // Deletion will also remove |title_view_| from its parent. - delete title_view_; - title_view_ = nullptr; - return; - } - - DCHECK(top_view_); - - const gfx::FontList& font_list = - views::Label().font_list().DeriveWithSizeDelta(2); - - constexpr int kTitleCharacterLimit = - kNotificationWidth * kMaxTitleLines / kMinPixelsPerTitleCharacter; - - base::string16 title = gfx::TruncateString( - notification.title(), kTitleCharacterLimit, gfx::WORD_BREAK); - if (!title_view_) { - int padding = kTitleLineHeight - font_list.GetHeight(); - - title_view_ = new BoundedLabel(title, font_list); - title_view_->SetLineHeight(kTitleLineHeight); - title_view_->SetLineLimit(kMaxTitleLines); - title_view_->SetColor(kRegularTextColor); - title_view_->SetBorder(MakeTextBorder(padding, 3, 0)); - top_view_->AddChildViewAt(title_view_, top_view_count_); - } else { - title_view_->SetText(title); - } - - top_view_count_++; -} - -void NotificationView::CreateOrUpdateMessageView( - const Notification& notification) { - if (notification.message().empty()) { - // Deletion will also remove |message_view_| from its parent. - delete message_view_; - message_view_ = nullptr; - return; - } - - DCHECK(top_view_ != NULL); - - base::string16 text = gfx::TruncateString(notification.message(), - kMessageCharacterLimit, - gfx::WORD_BREAK); - if (!message_view_) { - int padding = kMessageLineHeight - views::Label().font_list().GetHeight(); - message_view_ = new BoundedLabel(text); - message_view_->SetLineHeight(kMessageLineHeight); - message_view_->SetColor(kRegularTextColor); - message_view_->SetBorder(MakeTextBorder(padding, 4, 0)); - top_view_->AddChildViewAt(message_view_, top_view_count_); - } else { - message_view_->SetText(text); - } - - message_view_->SetVisible(notification.items().empty()); - top_view_count_++; -} - -base::string16 NotificationView::FormatContextMessage( - const Notification& notification) const { - if (notification.UseOriginAsContextMessage()) { - const GURL url = notification.origin_url(); - DCHECK(url.is_valid()); - return gfx::ElideText( - url_formatter::FormatUrlForSecurityDisplay( - url, url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS), - views::Label().font_list(), kContextMessageViewWidth, gfx::ELIDE_HEAD); - } - - return gfx::TruncateString(notification.context_message(), - kContextMessageCharacterLimit, gfx::WORD_BREAK); -} - -void NotificationView::CreateOrUpdateContextMessageView( - const Notification& notification) { - if (notification.context_message().empty() && - !notification.UseOriginAsContextMessage()) { - // Deletion will also remove |context_message_view_| from its parent. - delete context_message_view_; - context_message_view_ = nullptr; - return; - } - - DCHECK(top_view_ != NULL); - - base::string16 message = FormatContextMessage(notification); - - if (!context_message_view_) { - int padding = kMessageLineHeight - views::Label().font_list().GetHeight(); - context_message_view_ = new BoundedLabel(message); - context_message_view_->SetLineLimit(kContextMessageLineLimit); - context_message_view_->SetLineHeight(kMessageLineHeight); - context_message_view_->SetColor(kDimTextColor); - context_message_view_->SetBorder(MakeTextBorder(padding, 4, 0)); - top_view_->AddChildViewAt(context_message_view_, top_view_count_); - } else { - context_message_view_->SetText(message); - } - - top_view_count_++; -} - -void NotificationView::CreateOrUpdateProgressBarView( - const Notification& notification) { - if (notification.type() != NOTIFICATION_TYPE_PROGRESS) { - // Deletion will also remove |progress_bar_view_| from its parent. - delete progress_bar_view_; - progress_bar_view_ = nullptr; - return; - } - - DCHECK(top_view_); - - if (!progress_bar_view_) { - progress_bar_view_ = new views::ProgressBar(); - progress_bar_view_->SetBorder(MakeProgressBarBorder( - kProgressBarTopPadding, kProgressBarBottomPadding)); - top_view_->AddChildViewAt(progress_bar_view_, top_view_count_); - } - - progress_bar_view_->SetValue(notification.progress() / 100.0); - progress_bar_view_->SetVisible(notification.items().empty()); - top_view_count_++; -} - -void NotificationView::CreateOrUpdateListItemViews( - const Notification& notification) { - for (auto* item_view : item_views_) - delete item_view; - item_views_.clear(); - - int padding = kMessageLineHeight - views::Label().font_list().GetHeight(); - std::vector<NotificationItem> items = notification.items(); - - if (items.size() == 0) - return; - - DCHECK(top_view_); - for (size_t i = 0; i < items.size() && i < kNotificationMaximumItems; ++i) { - NotificationItemView* item_view = new NotificationItemView(items[i]); - item_view->SetBorder(MakeTextBorder(padding, i ? 0 : 4, 0)); - item_views_.push_back(item_view); - top_view_->AddChildViewAt(item_view, top_view_count_++); - } -} - -void NotificationView::CreateOrUpdateIconView( - const Notification& notification) { - gfx::Size image_view_size(kNotificationIconSize, kNotificationIconSize); - - if (!icon_view_) { - icon_view_ = new ProportionalImageView(image_view_size); - AddChildView(icon_view_); - } - - gfx::ImageSkia icon = notification.icon().AsImageSkia(); - icon_view_->SetImage(icon, icon.size()); -} - -void NotificationView::CreateOrUpdateSmallIconView( - const Notification& notification) { - small_image_view_->SetImage(notification.small_image().AsImageSkia()); -} - -void NotificationView::CreateOrUpdateImageView( - const Notification& notification) { - // |image_view_| is the view representing the area covered by the - // notification's image, including background and border. Its size can be - // specified in advance and images will be scaled to fit including a border if - // necessary. - if (notification.image().IsEmpty()) { - delete image_container_; - image_container_ = NULL; - image_view_ = NULL; - return; - } - - gfx::Size ideal_size(kNotificationPreferredImageWidth, - kNotificationPreferredImageHeight); - - if (!image_container_) { - DCHECK(!image_view_); - DCHECK(bottom_view_); - DCHECK_EQ(this, bottom_view_->parent()); - - image_container_ = new views::View(); - image_container_->SetLayoutManager(std::make_unique<views::FillLayout>()); - image_container_->SetBackground( - views::CreateSolidBackground(kImageBackgroundColor)); - - image_view_ = new ProportionalImageView(ideal_size); - image_container_->AddChildView(image_view_); - bottom_view_->AddChildViewAt(image_container_, 0); - } - - DCHECK(image_view_); - image_view_->SetImage(notification.image().AsImageSkia(), ideal_size); - - gfx::Size scaled_size = - GetImageSizeForContainerSize(ideal_size, notification.image().Size()); - image_view_->SetBorder( - ideal_size != scaled_size - ? views::CreateSolidBorder(kNotificationImageBorderSize, - SK_ColorTRANSPARENT) - : NULL); -} - -void NotificationView::CreateOrUpdateActionButtonViews( - const Notification& notification) { - std::vector<ButtonInfo> buttons = notification.buttons(); - bool new_buttons = action_buttons_.size() != buttons.size(); - - if (new_buttons || buttons.size() == 0) { - for (auto* item : separators_) - delete item; - separators_.clear(); - for (auto* item : action_buttons_) - delete item; - action_buttons_.clear(); - } - - DCHECK(bottom_view_); - DCHECK_EQ(this, bottom_view_->parent()); - - for (size_t i = 0; i < buttons.size(); ++i) { - ButtonInfo button_info = buttons[i]; - if (new_buttons) { - views::View* separator = new views::ImageView(); - separator->SetBorder(MakeSeparatorBorder(1, 0, kButtonSeparatorColor)); - separators_.push_back(separator); - bottom_view_->AddChildView(separator); - NotificationButton* button = new NotificationButton(this); - button->SetTitle(button_info.title); - button->SetIcon(button_info.icon.AsImageSkia()); - action_buttons_.push_back(button); - bottom_view_->AddChildView(button); - } else { - action_buttons_[i]->SetTitle(button_info.title); - action_buttons_[i]->SetIcon(button_info.icon.AsImageSkia()); - action_buttons_[i]->SchedulePaint(); - action_buttons_[i]->Layout(); - } - } - - if (new_buttons) { - Layout(); - views::Widget* widget = GetWidget(); - if (widget != NULL) { - widget->SetSize(widget->GetContentsView()->GetPreferredSize()); - GetWidget()->SynthesizeMouseMoveEvent(); - } - } -} - -void NotificationView::UpdateControlButtonsVisibilityWithNotification( - const Notification& notification) { - control_buttons_view_->ShowSettingsButton( - notification.should_show_settings_button()); - control_buttons_view_->ShowCloseButton(GetMode() == - MessageView::Mode::NORMAL); - UpdateControlButtonsVisibility(); -} - -NotificationControlButtonsView* NotificationView::GetControlButtonsView() - const { - return control_buttons_view_; -} - -int NotificationView::GetMessageLineLimit(int title_lines, int width) const { - int effective_title_lines = std::max(0, title_lines - 1); - int line_reduction_from_title = 2 * effective_title_lines; - // Title lines are counted as twice as big as message lines for the purpose - // of this calculation. - // The effect from the title reduction here should be: - // * 0 title lines: 5 max lines message. - // * 1 title line: 5 max lines message. - // * 2 title lines: 3 max lines message. - return std::max(0, kMessageExpandedLineLimit - line_reduction_from_title); -} - -int NotificationView::GetMessageHeight(int width, int limit) const { - return message_view_ ? - message_view_->GetSizeForWidthAndLines(width, limit).height() : 0; -} - -void NotificationView::ShrinkTopmostLabel() { -// Reduce width of the topmost label not to be covered by the control buttons -// only on non Chrome OS platform. -#if !defined(OS_CHROMEOS) - const auto& children = top_view_->children(); - int right = - kTextRightPadding + control_buttons_view_->GetPreferredSize().width(); - for (auto* child : children) { - SetBorderRight(child, right); - right = kTextRightPadding; - } -#endif -} - -} // namespace message_center
diff --git a/ui/message_center/views/notification_view.h b/ui/message_center/views/notification_view.h deleted file mode 100644 index e2e5507..0000000 --- a/ui/message_center/views/notification_view.h +++ /dev/null
@@ -1,121 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_MESSAGE_CENTER_VIEWS_NOTIFICATION_VIEW_H_ -#define UI_MESSAGE_CENTER_VIEWS_NOTIFICATION_VIEW_H_ - -#include <vector> - -#include "base/gtest_prod_util.h" -#include "base/macros.h" -#include "ui/message_center/message_center_export.h" -#include "ui/message_center/views/message_view.h" -#include "ui/views/controls/button/button.h" -#include "ui/views/controls/button/image_button.h" - -namespace views { -class ImageView; -class ProgressBar; -} - -namespace message_center { - -class BoundedLabel; -class NotificationButton; -class NotificationControlButtonsView; -class ProportionalImageView; - -// View that displays all current types of notification (web, basic, image, and -// list) except the custom notification. Future notification types may be -// handled by other classes, in which case instances of those classes would be -// returned by the Create() factory method below. -class MESSAGE_CENTER_EXPORT NotificationView : public MessageView, - public views::ButtonListener { - public: - explicit NotificationView(const Notification& notification); - ~NotificationView() override; - - // Overridden from views::View: - gfx::Size CalculatePreferredSize() const override; - int GetHeightForWidth(int width) const override; - void Layout() override; - void OnFocus() override; - void ScrollRectToVisible(const gfx::Rect& rect) override; - void OnMouseEntered(const ui::MouseEvent& event) override; - void OnMouseExited(const ui::MouseEvent& event) override; - - // Overridden from MessageView: - void UpdateWithNotification(const Notification& notification) override; - void ButtonPressed(views::Button* sender, const ui::Event& event) override; - NotificationControlButtonsView* GetControlButtonsView() const override; - - private: - FRIEND_TEST_ALL_PREFIXES(NotificationViewTest, CreateOrUpdateTest); - FRIEND_TEST_ALL_PREFIXES(NotificationViewTest, - CreateOrUpdateTestSettingsButton); - FRIEND_TEST_ALL_PREFIXES(NotificationViewTest, FormatContextMessageTest); - FRIEND_TEST_ALL_PREFIXES(NotificationViewTest, SettingsButtonTest); - FRIEND_TEST_ALL_PREFIXES(NotificationViewTest, TestLineLimits); - FRIEND_TEST_ALL_PREFIXES(NotificationViewTest, TestIconSizing); - FRIEND_TEST_ALL_PREFIXES(NotificationViewTest, TestImageSizing); - FRIEND_TEST_ALL_PREFIXES(NotificationViewTest, TitleWrappingTest); - FRIEND_TEST_ALL_PREFIXES(NotificationViewTest, UpdateButtonsStateTest); - FRIEND_TEST_ALL_PREFIXES(NotificationViewTest, UpdateButtonCountTest); - FRIEND_TEST_ALL_PREFIXES(NotificationViewTest, UpdateViewsOrderingTest); - - friend class NotificationViewTest; - - void CreateOrUpdateViews(const Notification& notification); - - void CreateOrUpdateTitleView(const Notification& notification); - void CreateOrUpdateMessageView(const Notification& notification); - void CreateOrUpdateContextMessageView(const Notification& notification); - void CreateOrUpdateProgressBarView(const Notification& notification); - void CreateOrUpdateListItemViews(const Notification& notification); - void CreateOrUpdateIconView(const Notification& notification); - void CreateOrUpdateSmallIconView(const Notification& notification); - void CreateOrUpdateImageView(const Notification& notification); - void CreateOrUpdateActionButtonViews(const Notification& notification); - // TODO(yoshiki): Move this to MessageView - void UpdateControlButtonsVisibilityWithNotification( - const Notification& notification); - - int GetMessageLineLimit(int title_lines, int width) const; - int GetMessageHeight(int width, int limit) const; - - // Formats the context message to be displayed based on |context| - // so it shows as much information as possible - // given the space available in the ContextMessage section of the - // notification. - base::string16 FormatContextMessage(const Notification& notification) const; - - // Shrink the topmost label not to be covered by the control button. - void ShrinkTopmostLabel(); - - // Weak references to NotificationView descendants owned by their parents. - views::View* top_view_ = nullptr; - BoundedLabel* title_view_ = nullptr; - BoundedLabel* message_view_ = nullptr; - BoundedLabel* context_message_view_ = nullptr; - std::vector<views::View*> item_views_; - ProportionalImageView* icon_view_ = nullptr; - views::View* bottom_view_ = nullptr; - views::View* image_container_ = nullptr; - ProportionalImageView* image_view_ = nullptr; - views::ProgressBar* progress_bar_view_ = nullptr; - std::vector<NotificationButton*> action_buttons_; - std::vector<views::View*> separators_; - std::unique_ptr<views::ImageView> small_image_view_; - NotificationControlButtonsView* control_buttons_view_; - - // Counter for view layouting, which is used during the CreateOrUpdate* - // phases to keep track of the view ordering. See crbug.com/901045 - int top_view_count_; - - DISALLOW_COPY_AND_ASSIGN(NotificationView); -}; - -} // namespace message_center - -#endif // UI_MESSAGE_CENTER_VIEWS_NOTIFICATION_VIEW_H_
diff --git a/ui/message_center/views/notification_view_md.cc b/ui/message_center/views/notification_view_md.cc index 977a527c..e5d6498 100644 --- a/ui/message_center/views/notification_view_md.cc +++ b/ui/message_center/views/notification_view_md.cc
@@ -29,7 +29,6 @@ #include "ui/message_center/public/cpp/notification.h" #include "ui/message_center/public/cpp/notification_types.h" #include "ui/message_center/vector_icons.h" -#include "ui/message_center/views/bounded_label.h" #include "ui/message_center/views/notification_background_painter.h" #include "ui/message_center/views/notification_control_buttons_view.h" #include "ui/message_center/views/notification_header_view.h" @@ -69,7 +68,7 @@ // TODO(tetsui): Move |kIconViewSize| to public/cpp/message_center_constants.h // and merge with contradicting |kNotificationIconSize|. constexpr gfx::Size kIconViewSize(36, 36); -constexpr gfx::Insets kLargeImageContainerPadding(0, 12, 12, 12); +constexpr gfx::Insets kLargeImageContainerPadding(0, 16, 16, 16); constexpr gfx::Size kLargeImageMinSize(328, 0); constexpr gfx::Size kLargeImageMaxSize(328, 218); constexpr gfx::Insets kLeftContentPadding(2, 4, 0, 4); @@ -103,6 +102,8 @@ // The icon size of inline reply input field. constexpr int kInputReplyButtonSize = 20; +// Max number of lines for title_view_. +constexpr int kMaxLinesForTitleView = 1; // Max number of lines for message_view_. constexpr int kMaxLinesForMessageView = 1; constexpr int kMaxLinesForExpandedMessageView = 4; @@ -136,6 +137,9 @@ // the ratio of the message width is limited to this value. constexpr double kProgressNotificationMessageRatio = 0.7; +// Line height of title and message views. +constexpr int kLineHeightMD = 17; + // This key/property allows tagging the textfield with its index. DEFINE_UI_CLASS_PROPERTY_KEY(int, kTextfieldIndexKey, 0U) @@ -706,7 +710,7 @@ notification.should_show_settings_button()); control_buttons_view_->ShowSnoozeButton( notification.should_show_snooze_button()); - control_buttons_view_->ShowCloseButton(GetMode() == Mode::NORMAL); + control_buttons_view_->ShowCloseButton(GetMode() != Mode::PINNED); UpdateControlButtonsVisibility(); } @@ -813,6 +817,13 @@ title_view_->SetFontList(font_list); title_view_->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD); title_view_->SetEnabledColor(kRegularTextColorMD); + title_view_->SetLineHeight(kLineHeightMD); + // TODO(knollr): multiline should not be required, but we need to set the + // width of |title_view_| (because of crbug.com/682266), which only works in + // multiline mode. + title_view_->SetMultiLine(true); + title_view_->SetMaxLines(kMaxLinesForTitleView); + title_view_->SetAllowCharacterBreak(true); left_content_->AddChildViewAt(title_view_, left_content_count_); } else { title_view_->SetText(title); @@ -834,13 +845,17 @@ base::string16 text = gfx::TruncateString( notification.message(), kMessageCharacterLimitMD, gfx::WORD_BREAK); - const gfx::FontList& font_list = GetTextFontList(); - if (!message_view_) { - message_view_ = new BoundedLabel(text, font_list); - message_view_->SetLineLimit(kMaxLinesForMessageView); - message_view_->SetColor(kDimTextColorMD); + const gfx::FontList& font_list = GetTextFontList(); + message_view_ = new views::Label(text); + message_view_->SetFontList(font_list); + message_view_->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD); + message_view_->SetEnabledColor(kDimTextColorMD); + message_view_->SetLineHeight(kLineHeightMD); + message_view_->SetMultiLine(true); + message_view_->SetMaxLines(kMaxLinesForMessageView); + message_view_->SetAllowCharacterBreak(true); left_content_->AddChildViewAt(message_view_, left_content_count_); } else { message_view_->SetText(text); @@ -1156,7 +1171,7 @@ // Expandable if the message exceeds one line. if (message_view_ && message_view_->GetVisible() && - message_view_->GetLinesForWidthAndLimit(message_view_->width(), -1) > 1) { + message_view_->GetRequiredLines() > 1) { return true; } // Expandable if there is at least one inline action. @@ -1183,8 +1198,8 @@ void NotificationViewMD::UpdateViewForExpandedState(bool expanded) { header_row_->SetExpanded(expanded); if (message_view_) { - message_view_->SetLineLimit(expanded ? kMaxLinesForExpandedMessageView - : kMaxLinesForMessageView); + message_view_->SetMaxLines(expanded ? kMaxLinesForExpandedMessageView + : kMaxLinesForMessageView); } if (image_container_view_) image_container_view_->SetVisible(expanded); @@ -1216,10 +1231,14 @@ // Ideally, we should fix the original bug, but it seems there's no obvious // solution for the bug according to https://crbug.com/678337#c7, we should // ensure that the change won't break any of the users of BoxLayout class. + if (title_view_) + title_view_->SizeToFit(kMessageViewWidthWithIcon); if (message_view_) message_view_->SizeToFit(kMessageViewWidthWithIcon); } else { left_content_->SetBorder(views::CreateEmptyBorder(kLeftContentPadding)); + if (title_view_) + title_view_->SizeToFit(kMessageViewWidth); if (message_view_) message_view_->SizeToFit(kMessageViewWidth); }
diff --git a/ui/message_center/views/notification_view_md.h b/ui/message_center/views/notification_view_md.h index 75954e0..45e199e 100644 --- a/ui/message_center/views/notification_view_md.h +++ b/ui/message_center/views/notification_view_md.h
@@ -29,7 +29,6 @@ namespace message_center { -class BoundedLabel; class NotificationHeaderView; class ProportionalImageView; @@ -227,9 +226,11 @@ TestInlineReplyActivateWithKeyPress); FRIEND_TEST_ALL_PREFIXES(NotificationViewMDTest, TestInlineReplyRemovedByUpdate); + FRIEND_TEST_ALL_PREFIXES(NotificationViewMDTest, TestLongTitleAndMessage); FRIEND_TEST_ALL_PREFIXES(NotificationViewMDTest, UpdateAddingIcon); FRIEND_TEST_ALL_PREFIXES(NotificationViewMDTest, UpdateButtonCountTest); FRIEND_TEST_ALL_PREFIXES(NotificationViewMDTest, UpdateButtonsStateTest); + FRIEND_TEST_ALL_PREFIXES(NotificationViewMDTest, UpdateInSettings); FRIEND_TEST_ALL_PREFIXES(NotificationViewMDTest, UpdateViewsOrderingTest); FRIEND_TEST_ALL_PREFIXES(NotificationViewMDTest, UseImageAsIcon); @@ -303,7 +304,7 @@ // Views which are dynamically created inside view hierarchy. views::Label* title_view_ = nullptr; - BoundedLabel* message_view_ = nullptr; + views::Label* message_view_ = nullptr; views::Label* status_view_ = nullptr; ProportionalImageView* icon_view_ = nullptr; views::View* image_container_view_ = nullptr;
diff --git a/ui/message_center/views/notification_view_md_unittest.cc b/ui/message_center/views/notification_view_md_unittest.cc index 4dc1483..7054701 100644 --- a/ui/message_center/views/notification_view_md_unittest.cc +++ b/ui/message_center/views/notification_view_md_unittest.cc
@@ -18,7 +18,6 @@ #include "ui/message_center/message_center.h" #include "ui/message_center/message_center_observer.h" #include "ui/message_center/public/cpp/message_center_constants.h" -#include "ui/message_center/views/bounded_label.h" #include "ui/message_center/views/notification_control_buttons_view.h" #include "ui/message_center/views/notification_header_view.h" #include "ui/message_center/views/padded_button.h" @@ -1098,6 +1097,33 @@ EXPECT_LT(notification_view()->left_content_->width(), left_content_width); } +TEST_F(NotificationViewMDTest, UpdateInSettings) { + std::unique_ptr<Notification> notification = CreateSimpleNotification(); + notification->set_type(NOTIFICATION_TYPE_SIMPLE); + UpdateNotificationViews(*notification); + + ui::test::EventGenerator generator(GetRootWindow(widget())); + + // Inline settings will be shown by clicking settings button. + EXPECT_FALSE(notification_view()->settings_row_->GetVisible()); + gfx::Point settings_cursor_location(1, 1); + views::View::ConvertPointToTarget( + notification_view()->control_buttons_view_->settings_button(), + notification_view(), &settings_cursor_location); + generator.MoveMouseTo(settings_cursor_location); + generator.ClickLeftButton(); + EXPECT_TRUE(notification_view()->settings_row_->GetVisible()); + + // Trigger an update event. + UpdateNotificationViews(*notification); + + // The close button should be visible. + views::Button* close_button = + notification_view()->control_buttons_view_->close_button(); + ASSERT_NE(nullptr, close_button); + EXPECT_TRUE(close_button->GetVisible()); +} + TEST_F(NotificationViewMDTest, InlineSettings) { std::unique_ptr<Notification> notification = CreateSimpleNotification(); notification->set_type(NOTIFICATION_TYPE_SIMPLE); @@ -1266,4 +1292,28 @@ DummyEvent()); } +TEST_F(NotificationViewMDTest, TestLongTitleAndMessage) { + std::unique_ptr<Notification> notification = CreateSimpleNotification(); + notification->set_type(NotificationType::NOTIFICATION_TYPE_SIMPLE); + notification->set_title(base::ASCIIToUTF16("title")); + notification->set_message(base::ASCIIToUTF16( + "consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore " + "et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud " + "exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.")); + UpdateNotificationViews(*notification); + notification_view()->ToggleExpanded(); + + // Get the height of the message view with a short title. + const int message_height = notification_view()->message_view_->height(); + + notification->set_title(base::ASCIIToUTF16( + "consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore " + "et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud " + "exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.")); + UpdateNotificationViews(*notification); + + // The height of the message view should stay the same with a long title. + EXPECT_EQ(message_height, notification_view()->message_view_->height()); +} + } // namespace message_center
diff --git a/ui/message_center/views/notification_view_unittest.cc b/ui/message_center/views/notification_view_unittest.cc deleted file mode 100644 index c464eff..0000000 --- a/ui/message_center/views/notification_view_unittest.cc +++ /dev/null
@@ -1,853 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/message_center/views/notification_view.h" - -#include <memory> - -#include "base/macros.h" -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" -#include "build/build_config.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "third_party/skia/include/core/SkCanvas.h" -#include "third_party/skia/include/core/SkColor.h" -#include "ui/compositor/scoped_animation_duration_scale_mode.h" -#include "ui/events/event_processor.h" -#include "ui/events/event_utils.h" -#include "ui/events/test/event_generator.h" -#include "ui/gfx/canvas.h" -#include "ui/gfx/geometry/rect.h" -#include "ui/gfx/geometry/size.h" -#include "ui/gfx/image/image.h" -#include "ui/gfx/text_utils.h" -#include "ui/message_center/message_center.h" -#include "ui/message_center/message_center_style.h" -#include "ui/message_center/notification_list.h" -#include "ui/message_center/public/cpp/message_center_constants.h" -#include "ui/message_center/public/cpp/notification.h" -#include "ui/message_center/public/cpp/notification_types.h" -#include "ui/message_center/views/bounded_label.h" -#include "ui/message_center/views/message_view_factory.h" -#include "ui/message_center/views/notification_button.h" -#include "ui/message_center/views/notification_control_buttons_view.h" -#include "ui/message_center/views/padded_button.h" -#include "ui/message_center/views/proportional_image_view.h" -#include "ui/views/controls/button/image_button.h" -#include "ui/views/controls/label.h" -#include "ui/views/layout/fill_layout.h" -#include "ui/views/test/views_test_base.h" -#include "ui/views/test/widget_test.h" -#include "ui/views/widget/widget_delegate.h" -#include "ui/views/widget/widget_utils.h" - -#if defined(OS_WIN) -#include "ui/base/win/shell.h" -#endif - -namespace message_center { - -/* Test fixture ***************************************************************/ - -class NotificationViewTest : public views::ViewsTestBase { - public: - NotificationViewTest(); - ~NotificationViewTest() override; - - void SetUp() override; - void TearDown() override; - - views::Widget* widget() { return notification_view_->GetWidget(); } - NotificationView* notification_view() const { - return notification_view_.get(); - } - Notification* notification() { return notification_.get(); } - RichNotificationData* data() { return data_.get(); } - - protected: - // Used to fill bitmaps returned by CreateBitmap(). - static const SkColor kBitmapColor = SK_ColorGREEN; - - const gfx::Image CreateTestImage(int width, int height) { - return gfx::Image::CreateFrom1xBitmap(CreateBitmap(width, height)); - } - - const SkBitmap CreateBitmap(int width, int height) { - SkBitmap bitmap; - bitmap.allocN32Pixels(width, height); - bitmap.eraseColor(kBitmapColor); - return bitmap; - } - - std::vector<ButtonInfo> CreateButtons(int number) { - ButtonInfo info(base::ASCIIToUTF16("Test button title.")); - info.icon = CreateTestImage(4, 4); - return std::vector<ButtonInfo>(number, info); - } - - // Paints |view| and returns the size that the original image (which must have - // been created by CreateBitmap()) was scaled to. - gfx::Size GetImagePaintSize(ProportionalImageView* view) { - CHECK(view); - if (view->bounds().IsEmpty()) - return gfx::Size(); - - gfx::Size canvas_size = view->bounds().size(); - gfx::Canvas canvas(canvas_size, 1.0 /* image_scale */, - true /* is_opaque */); - static_assert(kBitmapColor != SK_ColorBLACK, - "The bitmap color must match the background color"); - canvas.DrawColor(SK_ColorBLACK); - view->OnPaint(&canvas); - - SkBitmap bitmap = canvas.GetBitmap(); - // Incrementally inset each edge at its midpoint to find the bounds of the - // rect containing the image's color. This assumes that the image is - // centered in the canvas. - const int kHalfWidth = canvas_size.width() / 2; - const int kHalfHeight = canvas_size.height() / 2; - gfx::Rect rect(canvas_size); - while (rect.width() > 0 && - bitmap.getColor(rect.x(), kHalfHeight) != kBitmapColor) - rect.Inset(1, 0, 0, 0); - while (rect.height() > 0 && - bitmap.getColor(kHalfWidth, rect.y()) != kBitmapColor) - rect.Inset(0, 1, 0, 0); - while (rect.width() > 0 && - bitmap.getColor(rect.right() - 1, kHalfHeight) != kBitmapColor) - rect.Inset(0, 0, 1, 0); - while (rect.height() > 0 && - bitmap.getColor(kHalfWidth, rect.bottom() - 1) != kBitmapColor) - rect.Inset(0, 0, 0, 1); - - return rect.size(); - } - - void CheckVerticalOrderInNotification() { - std::vector<views::View*> vertical_order; - vertical_order.push_back(notification_view()->top_view_); - vertical_order.push_back(notification_view()->image_view_); - std::copy(notification_view()->action_buttons_.begin(), - notification_view()->action_buttons_.end(), - std::back_inserter(vertical_order)); - auto current = vertical_order.begin(); - auto last = current++; - while (current != vertical_order.end()) { - gfx::Point last_point = (*last)->origin(); - views::View::ConvertPointToTarget( - (*last), notification_view(), &last_point); - - gfx::Point current_point = (*current)->origin(); - views::View::ConvertPointToTarget( - (*current), notification_view(), ¤t_point); - - EXPECT_LT(last_point.y(), current_point.y()); - last = current++; - } - } - - views::Button* GetCloseButton() { - return notification_view()->control_buttons_view_->close_button(); - } - - views::Button* GetSettingsButton() { - return notification_view()->control_buttons_view_->settings_button(); - } - - void UpdateNotificationViews() { - MessageCenter::Get()->AddNotification( - std::make_unique<Notification>(*notification())); - notification_view()->UpdateWithNotification(*notification()); - } - - float GetNotificationSlideAmount() const { - return notification_view_->GetSlideOutLayer() - ->transform() - .To2dTranslation() - .x(); - } - - int GetTitleWidth() { - return notification_view()->title_view_->GetContentsBounds().width(); - } - - int GetTitleHeight() { - return notification_view()->title_view_->GetContentsBounds().height(); - } - - int GetTitleCharactersPerLine(base::char16 character) { - int available_width = GetTitleWidth(); -#if !defined(OS_CHROMEOS) - // On non-ChromeOS systems, we expect the available width to be reduced by - // the width of the control buttons view. - available_width -= - notification_view()->control_buttons_view_->GetPreferredSize().width(); -#endif - const gfx::FontList& font_list = - notification_view()->title_view_->font_list(); - - // To get the number of characters that fit into one line of text with a - // given width, we first get the width of one character. - int char_width = - gfx::GetStringWidth(base::string16(1, character), font_list); - - // We then assume that multiple of these characters next to each other have - // a total width of N * char_width. This is usually a very good estimation, - // but based on the platform, it may vary due to font shaping. - int characters_per_line = available_width / char_width; - - // These while loops account for any unexpected font shaping and are not - // expected to be expensive. - while (gfx::GetStringWidth(base::string16(characters_per_line, character), - font_list) <= available_width) { - characters_per_line++; - } - while (gfx::GetStringWidth(base::string16(characters_per_line, character), - font_list) > available_width) { - characters_per_line--; - } - - return characters_per_line; - } - - bool IsRemovedAfterIdle(const std::string& notification_id) const { - base::RunLoop().RunUntilIdle(); - return !MessageCenter::Get()->FindVisibleNotificationById(notification_id); - } - - void RemoveNotificationView() { notification_view_.reset(); } - - void DispatchGesture(const ui::GestureEventDetails& details) { - ui::test::EventGenerator generator( - GetRootWindow(notification_view()->GetWidget())); - ui::GestureEvent event(0, 0, 0, ui::EventTimeForNow(), details); - generator.Dispatch(&event); - } - - void BeginScroll() { - DispatchGesture(ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN)); - } - - void EndScroll() { - DispatchGesture(ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END)); - } - - void ScrollBy(int dx) { - DispatchGesture( - ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, dx, 0)); - } - - private: - std::unique_ptr<RichNotificationData> data_; - std::unique_ptr<Notification> notification_; - std::unique_ptr<NotificationView> notification_view_; - - DISALLOW_COPY_AND_ASSIGN(NotificationViewTest); -}; - -NotificationViewTest::NotificationViewTest() { -} - -NotificationViewTest::~NotificationViewTest() { -} - -void NotificationViewTest::SetUp() { - views::ViewsTestBase::SetUp(); - - MessageCenter::Initialize(); - - // Create a dummy notification. - SkBitmap bitmap; - data_.reset(new RichNotificationData()); - notification_.reset(new Notification( - NOTIFICATION_TYPE_BASE_FORMAT, std::string("notification id"), - base::UTF8ToUTF16("title"), base::UTF8ToUTF16("message"), - CreateTestImage(80, 80), base::UTF8ToUTF16("display source"), GURL(), - NotifierId(NotifierType::APPLICATION, "extension_id"), *data_, NULL)); - notification_->set_small_image(CreateTestImage(16, 16)); - notification_->set_image(CreateTestImage(320, 240)); - - // Then create a new NotificationView with that single notification. - notification_view_.reset(new NotificationView(*notification_)); - - // It depends on platform whether shadows are added. - // See MessageViewFactory::Create. - bool is_nested = true; -#if defined(OS_LINUX) - is_nested = false; -#endif -#if defined(OS_WIN) - if (!ui::win::IsAeroGlassEnabled()) - is_nested = false; -#endif - if (is_nested) - notification_view_->SetIsNested(); - - notification_view_->set_owned_by_client(); - - views::Widget::InitParams init_params( - CreateParams(views::Widget::InitParams::TYPE_POPUP)); - views::Widget* widget = new views::Widget(); - widget->Init(init_params); - widget->SetContentsView(notification_view_.get()); - widget->SetSize(notification_view_->GetPreferredSize()); - widget->Show(); -} - -void NotificationViewTest::TearDown() { - widget()->Close(); - notification_view_.reset(); - views::ViewsTestBase::TearDown(); - MessageCenter::Shutdown(); -} - -/* Unit tests *****************************************************************/ - -TEST_F(NotificationViewTest, CreateOrUpdateTest) { - EXPECT_TRUE(NULL != notification_view()->title_view_); - EXPECT_TRUE(NULL != notification_view()->message_view_); - EXPECT_TRUE(NULL != notification_view()->icon_view_); - EXPECT_TRUE(NULL != notification_view()->image_view_); - - notification()->set_image(gfx::Image()); - notification()->set_title(base::ASCIIToUTF16("")); - notification()->set_message(base::ASCIIToUTF16("")); - notification()->set_icon(gfx::Image()); - - notification_view()->UpdateWithNotification(*notification()); - EXPECT_TRUE(NULL == notification_view()->title_view_); - EXPECT_TRUE(NULL == notification_view()->message_view_); - EXPECT_TRUE(NULL == notification_view()->image_view_); - // Notification must have a control buttons view. - EXPECT_TRUE(NULL != notification_view()->control_buttons_view_); - // Notification is not pinned and have a close button by default. - EXPECT_TRUE(NULL != GetCloseButton()); - // Notification doesn't have a settings button by default. - EXPECT_TRUE(NULL == GetSettingsButton()); - // We still expect an icon view for all layouts. - EXPECT_TRUE(NULL != notification_view()->icon_view_); -} - -TEST_F(NotificationViewTest, UpdateViewsOrderingTest) { - EXPECT_NE(nullptr, notification_view()->title_view_); - EXPECT_NE(nullptr, notification_view()->message_view_); - EXPECT_EQ(0, notification_view()->top_view_->GetIndexOf( - notification_view()->title_view_)); - EXPECT_EQ(1, notification_view()->top_view_->GetIndexOf( - notification_view()->message_view_)); - - notification()->set_title(base::string16()); - - notification_view()->CreateOrUpdateViews(*notification()); - - EXPECT_EQ(nullptr, notification_view()->title_view_); - EXPECT_NE(nullptr, notification_view()->message_view_); - EXPECT_EQ(0, notification_view()->top_view_->GetIndexOf( - notification_view()->message_view_)); - - notification()->set_title(base::UTF8ToUTF16("title")); - - notification_view()->CreateOrUpdateViews(*notification()); - - EXPECT_NE(nullptr, notification_view()->title_view_); - EXPECT_NE(nullptr, notification_view()->message_view_); - EXPECT_EQ(0, notification_view()->top_view_->GetIndexOf( - notification_view()->title_view_)); - EXPECT_EQ(1, notification_view()->top_view_->GetIndexOf( - notification_view()->message_view_)); -} - -TEST_F(NotificationViewTest, CreateOrUpdateTestSettingsButton) { - data()->settings_button_handler = SettingsButtonHandler::INLINE; - Notification notification( - NOTIFICATION_TYPE_BASE_FORMAT, std::string("notification id"), - base::UTF8ToUTF16("title"), base::UTF8ToUTF16("message"), - CreateTestImage(80, 80), base::UTF8ToUTF16("display source"), - GURL("https://hello.com"), - NotifierId(NotifierType::APPLICATION, "extension_id"), *data(), nullptr); - - notification_view()->UpdateWithNotification(notification); - EXPECT_TRUE(NULL != notification_view()->title_view_); - EXPECT_TRUE(NULL != notification_view()->message_view_); - EXPECT_TRUE(NULL != notification_view()->context_message_view_); - EXPECT_TRUE(NULL != GetCloseButton()); - EXPECT_TRUE(NULL != GetSettingsButton()); - EXPECT_TRUE(NULL != notification_view()->icon_view_); - - EXPECT_TRUE(NULL == notification_view()->image_view_); -} - -TEST_F(NotificationViewTest, TestLineLimits) { - notification()->set_image(CreateTestImage(0, 0)); - notification()->set_context_message(base::ASCIIToUTF16("")); - notification_view()->UpdateWithNotification(*notification()); - - EXPECT_EQ(5, notification_view()->GetMessageLineLimit(0, 360)); - EXPECT_EQ(5, notification_view()->GetMessageLineLimit(1, 360)); - EXPECT_EQ(3, notification_view()->GetMessageLineLimit(2, 360)); - - notification()->set_image(CreateTestImage(2, 2)); - notification_view()->UpdateWithNotification(*notification()); - - EXPECT_EQ(5, notification_view()->GetMessageLineLimit(0, 360)); - EXPECT_EQ(5, notification_view()->GetMessageLineLimit(1, 360)); - EXPECT_EQ(3, notification_view()->GetMessageLineLimit(2, 360)); - - notification()->set_context_message(base::ASCIIToUTF16("foo")); - notification_view()->UpdateWithNotification(*notification()); - - EXPECT_TRUE(notification_view()->context_message_view_ != NULL); - - EXPECT_EQ(5, notification_view()->GetMessageLineLimit(0, 360)); - EXPECT_EQ(5, notification_view()->GetMessageLineLimit(1, 360)); - EXPECT_EQ(3, notification_view()->GetMessageLineLimit(2, 360)); -} - -TEST_F(NotificationViewTest, TestIconSizing) { - notification()->set_type(NOTIFICATION_TYPE_SIMPLE); - ProportionalImageView* view = notification_view()->icon_view_; - - // Icons smaller than the maximum size should remain unscaled. - notification()->set_icon(CreateTestImage(kNotificationIconSize / 2, - kNotificationIconSize / 4)); - UpdateNotificationViews(); - EXPECT_EQ(gfx::Size(kNotificationIconSize / 2, - kNotificationIconSize / 4).ToString(), - GetImagePaintSize(view).ToString()); - - // Icons of exactly the intended icon size should remain unscaled. - notification()->set_icon(CreateTestImage(kNotificationIconSize, - kNotificationIconSize)); - UpdateNotificationViews(); - EXPECT_EQ(gfx::Size(kNotificationIconSize, kNotificationIconSize).ToString(), - GetImagePaintSize(view).ToString()); - - // Icons over the maximum size should be scaled down, maintaining proportions. - notification()->set_icon(CreateTestImage(2 * kNotificationIconSize, - 2 * kNotificationIconSize)); - UpdateNotificationViews(); - EXPECT_EQ(gfx::Size(kNotificationIconSize, kNotificationIconSize).ToString(), - GetImagePaintSize(view).ToString()); - - notification()->set_icon(CreateTestImage(4 * kNotificationIconSize, - 2 * kNotificationIconSize)); - UpdateNotificationViews(); - EXPECT_EQ(gfx::Size(kNotificationIconSize, - kNotificationIconSize / 2).ToString(), - GetImagePaintSize(view).ToString()); -} - -TEST_F(NotificationViewTest, TestImageSizing) { - ProportionalImageView* view = notification_view()->image_view_; - const gfx::Size kIdealSize(kNotificationPreferredImageWidth, - kNotificationPreferredImageHeight); - - // Images should be scaled to the ideal size. - notification()->set_image(CreateTestImage(kIdealSize.width() / 2, - kIdealSize.height() / 2)); - UpdateNotificationViews(); - EXPECT_EQ(kIdealSize.ToString(), GetImagePaintSize(view).ToString()); - - notification()->set_image(CreateTestImage(kIdealSize.width(), - kIdealSize.height())); - UpdateNotificationViews(); - EXPECT_EQ(kIdealSize.ToString(), GetImagePaintSize(view).ToString()); - - notification()->set_image(CreateTestImage(kIdealSize.width() * 2, - kIdealSize.height() * 2)); - UpdateNotificationViews(); - EXPECT_EQ(kIdealSize.ToString(), GetImagePaintSize(view).ToString()); - - // Original aspect ratios should be preserved. - gfx::Size orig_size(kIdealSize.width() * 2, kIdealSize.height()); - notification()->set_image( - CreateTestImage(orig_size.width(), orig_size.height())); - UpdateNotificationViews(); - gfx::Size paint_size = GetImagePaintSize(view); - gfx::Size container_size = kIdealSize; - container_size.Enlarge(-2 * kNotificationImageBorderSize, - -2 * kNotificationImageBorderSize); - EXPECT_EQ(GetImageSizeForContainerSize(container_size, orig_size).ToString(), - paint_size.ToString()); - ASSERT_GT(paint_size.height(), 0); - EXPECT_EQ(orig_size.width() / orig_size.height(), - paint_size.width() / paint_size.height()); - - orig_size.SetSize(kIdealSize.width(), kIdealSize.height() * 2); - notification()->set_image( - CreateTestImage(orig_size.width(), orig_size.height())); - UpdateNotificationViews(); - paint_size = GetImagePaintSize(view); - EXPECT_EQ(GetImageSizeForContainerSize(container_size, orig_size).ToString(), - paint_size.ToString()); - ASSERT_GT(paint_size.height(), 0); - EXPECT_EQ(orig_size.width() / orig_size.height(), - paint_size.width() / paint_size.height()); -} - -TEST_F(NotificationViewTest, UpdateButtonsStateTest) { - notification()->set_buttons(CreateButtons(2)); - notification_view()->UpdateWithNotification(*notification()); - widget()->Show(); - - EXPECT_EQ(views::Button::STATE_NORMAL, - notification_view()->action_buttons_[0]->state()); - - // Now construct a mouse move event 1 pixel inside the boundary of the action - // button. - gfx::Point cursor_location(1, 1); - views::View::ConvertPointToWidget(notification_view()->action_buttons_[0], - &cursor_location); - ui::MouseEvent move(ui::ET_MOUSE_MOVED, cursor_location, cursor_location, - ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE); - widget()->OnMouseEvent(&move); - - EXPECT_EQ(views::Button::STATE_HOVERED, - notification_view()->action_buttons_[0]->state()); - - notification_view()->UpdateWithNotification(*notification()); - - EXPECT_EQ(views::Button::STATE_HOVERED, - notification_view()->action_buttons_[0]->state()); - - // Now construct a mouse move event 1 pixel outside the boundary of the - // widget. - cursor_location = gfx::Point(-1, -1); - move = ui::MouseEvent(ui::ET_MOUSE_MOVED, cursor_location, cursor_location, - ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE); - widget()->OnMouseEvent(&move); - - EXPECT_EQ(views::Button::STATE_NORMAL, - notification_view()->action_buttons_[0]->state()); -} - -TEST_F(NotificationViewTest, UpdateButtonCountTest) { - notification()->set_buttons(CreateButtons(2)); - notification_view()->UpdateWithNotification(*notification()); - widget()->Show(); - - EXPECT_EQ(views::Button::STATE_NORMAL, - notification_view()->action_buttons_[0]->state()); - EXPECT_EQ(views::Button::STATE_NORMAL, - notification_view()->action_buttons_[1]->state()); - - ui::test::EventGenerator generator( - GetRootWindow(notification_view()->GetWidget())); - - // Now construct a mouse move event 1 pixel inside the boundary of the action - // button. - gfx::Point cursor_location(1, 1); - views::View::ConvertPointToTarget(notification_view()->action_buttons_[0], - notification_view(), &cursor_location); - generator.MoveMouseTo(cursor_location); - - EXPECT_EQ(views::Button::STATE_HOVERED, - notification_view()->action_buttons_[0]->state()); - EXPECT_EQ(views::Button::STATE_NORMAL, - notification_view()->action_buttons_[1]->state()); - - notification()->set_buttons(CreateButtons(1)); - notification_view()->UpdateWithNotification(*notification()); - - EXPECT_EQ(views::Button::STATE_HOVERED, - notification_view()->action_buttons_[0]->state()); - EXPECT_EQ(1u, notification_view()->action_buttons_.size()); - - // Now construct a mouse move event 1 pixel outside the boundary of the - // widget. - cursor_location = gfx::Point(-1, -1); - views::View::ConvertPointToScreen(notification_view(), &cursor_location); - generator.MoveMouseTo(cursor_location); - - EXPECT_EQ(views::Button::STATE_NORMAL, - notification_view()->action_buttons_[0]->state()); -} - -TEST_F(NotificationViewTest, SettingsButtonTest) { - data()->settings_button_handler = SettingsButtonHandler::INLINE; - Notification notf( - NOTIFICATION_TYPE_BASE_FORMAT, std::string("notification id"), - base::UTF8ToUTF16("title"), base::UTF8ToUTF16("message"), - CreateTestImage(80, 80), base::UTF8ToUTF16("display source"), - GURL("https://hello.com"), - NotifierId(NotifierType::APPLICATION, "extension_id"), *data(), nullptr); - notification_view()->UpdateWithNotification(notf); - widget()->Show(); - - EXPECT_TRUE(NULL != GetSettingsButton()); - EXPECT_EQ(views::Button::STATE_NORMAL, GetSettingsButton()->state()); - - ui::test::EventGenerator generator(GetRootWindow(widget())); - - // Now construct a mouse move event 1 pixel inside the boundary of the action - // button. - gfx::Point cursor_location(1, 1); - views::View::ConvertPointToTarget(GetSettingsButton(), notification_view(), - &cursor_location); - generator.MoveMouseTo(cursor_location); - - EXPECT_EQ(views::Button::STATE_HOVERED, GetSettingsButton()->state()); - - // Now construct a mouse move event 1 pixel outside the boundary of the - // widget. - cursor_location = gfx::Point(-1, -1); - views::View::ConvertPointToTarget(GetSettingsButton(), notification_view(), - &cursor_location); - generator.MoveMouseTo(cursor_location); - - EXPECT_EQ(views::Button::STATE_NORMAL, GetSettingsButton()->state()); -} - -TEST_F(NotificationViewTest, ViewOrderingTest) { - // Tests that views are created in the correct vertical order. - notification()->set_buttons(CreateButtons(2)); - - // Layout the initial views. - UpdateNotificationViews(); - - // Double-check that vertical order is correct. - CheckVerticalOrderInNotification(); - - // Tests that views remain in that order even after an update. - UpdateNotificationViews(); - CheckVerticalOrderInNotification(); -} - -TEST_F(NotificationViewTest, TitleWrappingTest) { - data()->settings_button_handler = SettingsButtonHandler::INLINE; - Notification notf( - NOTIFICATION_TYPE_BASE_FORMAT, std::string("notification id"), - base::UTF8ToUTF16(""), base::UTF8ToUTF16("message"), - CreateTestImage(80, 80), base::UTF8ToUTF16("display source"), - GURL("https://hello.com"), - NotifierId(NotifierType::APPLICATION, "extension_id"), *data(), nullptr); - - const base::char16 character = '1'; - const int characters_per_line = GetTitleCharactersPerLine(character); - - // Test a very short title - notf.set_title(base::string16(1, character)); - notification_view()->UpdateWithNotification(notf); - int one_line_height = GetTitleHeight(); - - // Test a title that exactly fits into one line - notf.set_title(base::string16(characters_per_line, character)); - notification_view()->UpdateWithNotification(notf); - EXPECT_EQ(one_line_height, GetTitleHeight()); - - // Test a title that breaks into 2 lines with only 1 char in the second line - notf.set_title(base::string16(characters_per_line + 1, character)); - notification_view()->UpdateWithNotification(notf); - int two_line_height = GetTitleHeight(); - EXPECT_GT(two_line_height, one_line_height); - - // Test a title that clearly breaks into 2 lines - notf.set_title(base::string16(characters_per_line + 10, character)); - notification_view()->UpdateWithNotification(notf); - EXPECT_EQ(two_line_height, GetTitleHeight()); - - // Test a title that fits exactly into 2 lines - notf.set_title(base::string16(characters_per_line * 2, character)); - notification_view()->UpdateWithNotification(notf); - EXPECT_EQ(two_line_height, GetTitleHeight()); - - // Test a title that would break into 3 lines but has ellipsis in the 2nd line - notf.set_title(base::string16(characters_per_line * 2 + 1, character)); - notification_view()->UpdateWithNotification(notf); - EXPECT_EQ(two_line_height, GetTitleHeight()); -} - -TEST_F(NotificationViewTest, FormatContextMessageTest) { - const std::string kRegularContextText = "Context Text"; - const std::string kVeryLongContextText = - "VERY VERY VERY VERY VERY VERY VERY VERY VERY VERY VERY VERY" - "VERY VERY VERY VERY VERY VERY VERY VERY VERY VERY VERY VERY" - "VERY VERY VERY VERY Long Long Long Long Long Long Long Long context"; - - const std::string kVeryLongElidedContextText = - "VERY VERY VERY VERY VERY VERY VERY VERY VERY VERY VERY VERYVERY VERY " - "VERY VERY VERY VERY VERY VERY VERY VERY VERY\xE2\x80\xA6"; - - const std::string kChromeUrl = "chrome://settings"; - const std::string kUrlContext = "http://chromium.org/hello"; - const std::string kHostContext = "chromium.org"; - const std::string kLongUrlContext = - "https://" - "veryveryveryveryveyryveryveryveryveryveyryveryvery.veryveryveyrylong." - "chromium.org/hello"; - - Notification notification1(NOTIFICATION_TYPE_BASE_FORMAT, std::string(""), - base::UTF8ToUTF16(""), base::UTF8ToUTF16(""), - CreateTestImage(80, 80), base::UTF8ToUTF16(""), - GURL(), NotifierId(GURL()), *data(), NULL); - notification1.set_context_message(base::ASCIIToUTF16(kRegularContextText)); - - base::string16 result = - notification_view()->FormatContextMessage(notification1); - EXPECT_EQ(kRegularContextText, base::UTF16ToUTF8(result)); - - notification1.set_context_message(base::ASCIIToUTF16(kVeryLongContextText)); - result = notification_view()->FormatContextMessage(notification1); - EXPECT_EQ(kVeryLongElidedContextText, base::UTF16ToUTF8(result)); - - Notification notification2( - NOTIFICATION_TYPE_BASE_FORMAT, std::string(""), base::UTF8ToUTF16(""), - base::UTF8ToUTF16(""), CreateTestImage(80, 80), base::UTF8ToUTF16(""), - GURL(kUrlContext), NotifierId(GURL()), *data(), NULL); - notification2.set_context_message(base::ASCIIToUTF16("")); - - result = notification_view()->FormatContextMessage(notification2); - EXPECT_EQ(kHostContext, base::UTF16ToUTF8(result)); - - // Non http url and empty context message should yield an empty context - // message. - Notification notification3( - NOTIFICATION_TYPE_BASE_FORMAT, std::string(""), base::UTF8ToUTF16(""), - base::UTF8ToUTF16(""), CreateTestImage(80, 80), base::UTF8ToUTF16(""), - GURL(kChromeUrl), NotifierId(GURL()), *data(), NULL); - notification3.set_context_message(base::ASCIIToUTF16("")); - result = notification_view()->FormatContextMessage(notification3); - EXPECT_TRUE(result.empty()); - - // Long http url should be elided - Notification notification4( - NOTIFICATION_TYPE_BASE_FORMAT, std::string(""), base::UTF8ToUTF16(""), - base::UTF8ToUTF16(""), CreateTestImage(80, 80), base::UTF8ToUTF16(""), - GURL(kLongUrlContext), NotifierId(GURL()), *data(), NULL); - notification4.set_context_message(base::ASCIIToUTF16("")); - result = notification_view()->FormatContextMessage(notification4); - - // Different platforms elide at different lengths so we do - // some generic checking here. - // The url has been elided (it starts with an ellipsis) - // The end of the domainsuffix is shown - // the url piece is not shown - std::string result_utf8 = base::UTF16ToUTF8(result); - EXPECT_TRUE(result_utf8.find(".veryveryveyrylong.chromium.org") != - std::string::npos); - EXPECT_TRUE(base::StartsWith(result_utf8, "\xE2\x80\xA6", - base::CompareCase::SENSITIVE)); - EXPECT_TRUE(result_utf8.find("hello") == std::string::npos); -} - -// Synthetic scroll events are not supported on Mac in the views -// test framework. -#if defined(OS_MACOSX) -#define MAYBE_SlideOut DISABLED_SlideOut -#else -#define MAYBE_SlideOut SlideOut -#endif -TEST_F(NotificationViewTest, MAYBE_SlideOut) { - ui::ScopedAnimationDurationScaleMode zero_duration_scope( - ui::ScopedAnimationDurationScaleMode::ZERO_DURATION); - - UpdateNotificationViews(); - std::string notification_id = notification()->id(); - - BeginScroll(); - ScrollBy(-10); - EXPECT_FALSE(IsRemovedAfterIdle(notification_id)); - EXPECT_EQ(-10.f, GetNotificationSlideAmount()); - EndScroll(); - EXPECT_FALSE(IsRemovedAfterIdle(notification_id)); - EXPECT_EQ(0.f, GetNotificationSlideAmount()); - - BeginScroll(); - ScrollBy(-200); - EXPECT_FALSE(IsRemovedAfterIdle(notification_id)); - EXPECT_EQ(-200.f, GetNotificationSlideAmount()); - EndScroll(); - EXPECT_TRUE(IsRemovedAfterIdle(notification_id)); -} - -#if defined(OS_MACOSX) -#define MAYBE_SlideOutNested DISABLED_SlideOutNested -#else -#define MAYBE_SlideOutNested SlideOutNested -#endif -TEST_F(NotificationViewTest, MAYBE_SlideOutNested) { - ui::ScopedAnimationDurationScaleMode zero_duration_scope( - ui::ScopedAnimationDurationScaleMode::ZERO_DURATION); - - UpdateNotificationViews(); - std::string notification_id = notification()->id(); - - BeginScroll(); - ScrollBy(-10); - EXPECT_FALSE(IsRemovedAfterIdle(notification_id)); - EXPECT_EQ(-10.f, GetNotificationSlideAmount()); - EndScroll(); - EXPECT_FALSE(IsRemovedAfterIdle(notification_id)); - EXPECT_EQ(0.f, GetNotificationSlideAmount()); - - BeginScroll(); - ScrollBy(-200); - EXPECT_FALSE(IsRemovedAfterIdle(notification_id)); - EXPECT_EQ(-200.f, GetNotificationSlideAmount()); - EndScroll(); - EXPECT_TRUE(IsRemovedAfterIdle(notification_id)); -} - -// Pinning notification is ChromeOS only feature. -#if defined(OS_CHROMEOS) - -TEST_F(NotificationViewTest, SlideOutPinned) { - ui::ScopedAnimationDurationScaleMode zero_duration_scope( - ui::ScopedAnimationDurationScaleMode::ZERO_DURATION); - - notification()->set_pinned(true); - notification_view()->SetIsNested(); - UpdateNotificationViews(); - std::string notification_id = notification()->id(); - - BeginScroll(); - ScrollBy(-200); - EXPECT_FALSE(IsRemovedAfterIdle(notification_id)); - EXPECT_LT(-200.f, GetNotificationSlideAmount()); - EndScroll(); - EXPECT_FALSE(IsRemovedAfterIdle(notification_id)); -} - -TEST_F(NotificationViewTest, PopupsCantPin) { - ui::ScopedAnimationDurationScaleMode zero_duration_scope( - ui::ScopedAnimationDurationScaleMode::ZERO_DURATION); - - notification()->set_pinned(true); - UpdateNotificationViews(); - std::string notification_id = notification()->id(); - - auto shown_as_popup = [](const std::string& notification_id) { - auto notifications = MessageCenter::Get()->GetPopupNotifications(); - for (auto* notification : notifications) { - if (notification->id() == notification_id) - return true; - } - return false; - }; - - BeginScroll(); - ScrollBy(-200); - EXPECT_FALSE(IsRemovedAfterIdle(notification_id)); - EXPECT_TRUE(shown_as_popup(notification_id)); - EXPECT_EQ(-200.f, GetNotificationSlideAmount()); - EndScroll(); - EXPECT_FALSE(IsRemovedAfterIdle(notification_id)); - EXPECT_FALSE(shown_as_popup(notification_id)); -} - -TEST_F(NotificationViewTest, Pinned) { - // Notifications are popups by default (can't be pinned). - notification()->set_pinned(true); - UpdateNotificationViews(); - EXPECT_TRUE(GetCloseButton()); - - notification_view()->SetIsNested(); - UpdateNotificationViews(); - EXPECT_FALSE(GetCloseButton()); -} - -#endif // defined(OS_CHROMEOS) - -} // namespace message_center
diff --git a/ui/strings/ui_strings.grd b/ui/strings/ui_strings.grd index d908726..14cce14b 100644 --- a/ui/strings/ui_strings.grd +++ b/ui/strings/ui_strings.grd
@@ -689,9 +689,6 @@ <message name="IDS_MESSAGE_CENTER_NOTIFICATION_ACCESSIBLE_NAME_PLURAL" desc="The accessible name for a multiple notifications."> Notifications </message> - <message name="IDS_MESSAGE_CENTER_NOTIFIER_DISABLE" desc="The menu entry for disabling a notifier from a notification."> - Disable notifications from <ph name="notifier_name">$1<ex>Notification Galore!</ex></ph> - </message> <message name="IDS_MESSAGE_CENTER_EXPAND_NOTIFICATION" desc="The button for expanding the notification. By clicking this, the long message and the buttons of the notification are shown."> Expand notification </message>
diff --git a/ui/views/controls/label.cc b/ui/views/controls/label.cc index 8b42eab..24d08c79 100644 --- a/ui/views/controls/label.cc +++ b/ui/views/controls/label.cc
@@ -228,6 +228,10 @@ SizeToPreferredSize(); } +size_t Label::GetRequiredLines() const { + return full_text_->GetNumLines(); +} + base::string16 Label::GetDisplayTextForTesting() { ClearDisplayText(); MaybeBuildDisplayText();
diff --git a/ui/views/controls/label.h b/ui/views/controls/label.h index f21722f..50e30e5 100644 --- a/ui/views/controls/label.h +++ b/ui/views/controls/label.h
@@ -145,6 +145,10 @@ int max_lines() const { return max_lines_; } void SetMaxLines(int max_lines); + // Returns the number of lines required to render all text. The actual number + // of rendered lines might be limited by |max_lines_| which elides the rest. + size_t GetRequiredLines() const; + // Get or set if the label text should be obscured before rendering (e.g. // should "Password!" display as "*********"); default is false. bool obscured() const { return full_text_->obscured(); }
diff --git a/ui/views/examples/button_sticker_sheet.cc b/ui/views/examples/button_sticker_sheet.cc index a76791e..8e19bd6a 100644 --- a/ui/views/examples/button_sticker_sheet.cc +++ b/ui/views/examples/button_sticker_sheet.cc
@@ -43,41 +43,45 @@ return layout; } -View* MakePlainLabel(const std::string& text) { - return new Label(base::ASCIIToUTF16(text)); +std::unique_ptr<View> MakePlainLabel(const std::string& text) { + return std::make_unique<Label>(base::ASCIIToUTF16(text)); } // Add a row containing a label whose text is |label_text| and then all the // views in |views| to the supplied GridLayout, with padding between rows. +template <typename T> void AddLabelledRowToGridLayout(GridLayout* layout, const std::string& label_text, - std::vector<View*> views) { + std::vector<std::unique_ptr<T>> views) { const float kRowDoesNotResizeVertically = 0.0; const int kPaddingRowHeight = 8; layout->StartRow(kRowDoesNotResizeVertically, kStretchyGridColumnSetId); - layout->AddView(MakePlainLabel(label_text)); - for (auto* view : views) - layout->AddView(view); + layout->AddView(MakePlainLabel(label_text).get()); + for (auto& view : views) + layout->AddView(view.release()); // This gets added extraneously after the last row, but it doesn't hurt and // means there's no need to keep track of whether to add it or not. layout->AddPaddingRow(kRowDoesNotResizeVertically, kPaddingRowHeight); } // Constructs a pair of MdTextButtons in the specified |state| with the -// specified |listener|, and returns them in |*primary| and |*secondary|. The -// button in |*primary| is a call-to-action button, and the button in -// |*secondary| is a regular button. -void MakeButtonsInState(MdTextButton** primary, - MdTextButton** secondary, - ButtonListener* listener, - Button::ButtonState state) { +// specified |listener|, and returns them in |primary| and |secondary|. The +// button in |primary| is a call-to-action button, and the button in +// |secondary| is a regular button. +std::vector<std::unique_ptr<MdTextButton>> MakeButtonsInState( + ButtonListener* listener, + Button::ButtonState state) { + std::vector<std::unique_ptr<MdTextButton>> buttons; const base::string16 button_text = base::ASCIIToUTF16("Button"); - *primary = MdTextButton::Create(listener, button_text).release(); - (*primary)->SetProminent(true); - (*primary)->SetState(state); + auto primary = MdTextButton::Create(listener, button_text); + primary->SetProminent(true); + primary->SetState(state); + buttons.push_back(std::move(primary)); - *secondary = MdTextButton::Create(listener, button_text).release(); - (*secondary)->SetState(state); + auto secondary = MdTextButton::Create(listener, button_text); + secondary->SetState(state); + buttons.push_back(std::move(secondary)); + return buttons; } } // namespace @@ -91,23 +95,21 @@ GridLayout* layout = MakeStretchyGridLayout(container, 3); // The title row has an empty row label. - AddLabelledRowToGridLayout( - layout, std::string(), - {MakePlainLabel("Primary"), MakePlainLabel("Secondary")}); + std::vector<std::unique_ptr<View>> plainLabel; + plainLabel.push_back(MakePlainLabel("Primary")); + plainLabel.push_back(MakePlainLabel("Secondary")); + AddLabelledRowToGridLayout(layout, std::string(), std::move(plainLabel)); - MdTextButton* primary = nullptr; - MdTextButton* secondary = nullptr; - - MakeButtonsInState(&primary, &secondary, this, Button::STATE_NORMAL); - AddLabelledRowToGridLayout(layout, "Default", {primary, secondary}); - MakeButtonsInState(&primary, &secondary, this, Button::STATE_NORMAL); - AddLabelledRowToGridLayout(layout, "Normal", {primary, secondary}); - MakeButtonsInState(&primary, &secondary, this, Button::STATE_HOVERED); - AddLabelledRowToGridLayout(layout, "Hovered", {primary, secondary}); - MakeButtonsInState(&primary, &secondary, this, Button::STATE_PRESSED); - AddLabelledRowToGridLayout(layout, "Pressed", {primary, secondary}); - MakeButtonsInState(&primary, &secondary, this, Button::STATE_DISABLED); - AddLabelledRowToGridLayout(layout, "Disabled", {primary, secondary}); + AddLabelledRowToGridLayout(layout, "Default", + MakeButtonsInState(this, Button::STATE_NORMAL)); + AddLabelledRowToGridLayout(layout, "Normal", + MakeButtonsInState(this, Button::STATE_NORMAL)); + AddLabelledRowToGridLayout(layout, "Hovered", + MakeButtonsInState(this, Button::STATE_HOVERED)); + AddLabelledRowToGridLayout(layout, "Pressed", + MakeButtonsInState(this, Button::STATE_PRESSED)); + AddLabelledRowToGridLayout(layout, "Disabled", + MakeButtonsInState(this, Button::STATE_DISABLED)); } void ButtonStickerSheet::ButtonPressed(Button* button, const ui::Event& event) {