diff --git a/DEPS b/DEPS index 649d355..197a0f29 100644 --- a/DEPS +++ b/DEPS
@@ -142,11 +142,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': '1d105080c423e6c8bbb15da5544a4ff28a8b8570', + 'skia_revision': 'e192c4ce5a33829325ded5a03587605d892829b6', # 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': '626056db5ef19ce5197a87e9459ff0fef520c331', + 'v8_revision': 'f77a9153efb855ae59cfb17c3c4bd32f51c34857', # 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. @@ -154,7 +154,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': '4c292b876132697736f103b1ac7f41f044f88a5b', + 'angle_revision': 'a1b6761e6e3c55bb058ccd413d962a0a4ccfe12b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -261,7 +261,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'spv_tools_revision': '37e8f7994644151f425efa5b408d105713d2cd21', + 'spv_tools_revision': 'b8ab80843f67479b1b0c096138e62ec78145f05b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -277,7 +277,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': 'c6d2d8e8fbd89f43c08c9b38b8df2bfff625ef2a', + 'dawn_revision': '35716c204d2caebe01417bfec3750f5f63000229', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -806,7 +806,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '28f766851ebb223e99ea2b45e8abe795923b1046', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'ca227ecc2bfd7582675b735b8ff81477cce26cac', 'condition': 'checkout_linux', }, @@ -1359,7 +1359,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '91350f8ecf9ab2922ee062c114e4a759f24bd8d0', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '668ce0c7fa8f261dacdba45149d10a23f772a9b6', + Var('webrtc_git') + '/src.git' + '@' + '86f8b3bd5d29e790ae24e0c285fa501805529d62', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1400,7 +1400,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@da80246d0fbe8ff119654aed9f66612825f46900', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@25cf5a641d73fce8890b99b3fd6d4069e497f5bf', 'condition': 'checkout_src_internal', },
diff --git a/base/BUILD.gn b/base/BUILD.gn index eb30009..d76b55d 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -759,10 +759,14 @@ "task/promise/dependent_list.h", "task/promise/finally_executor.cc", "task/promise/finally_executor.h", + "task/promise/helpers.cc", "task/promise/helpers.h", "task/promise/no_op_promise_executor.cc", - "task/promise/no_op_promise_executor.h", + "task/promise/post_task_executor.h", "task/promise/promise.h", + "task/promise/promise.h", + "task/promise/promise_executor.cc", + "task/promise/promise_executor.h", "task/promise/promise_result.h", "task/promise/then_and_catch_executor.cc", "task/promise/then_and_catch_executor.h", @@ -2658,6 +2662,7 @@ "task/promise/abstract_promise_unittest.cc", "task/promise/dependent_list_unittest.cc", "task/promise/helpers_unittest.cc", + "task/promise/post_task_executor_unittest.cc", "task/promise/promise_unittest.cc", "task/scoped_set_task_priority_for_current_thread_unittest.cc", "task/sequence_manager/atomic_flag_set_unittest.cc",
diff --git a/base/callback_internal.h b/base/callback_internal.h index 390461c..777397d 100644 --- a/base/callback_internal.h +++ b/base/callback_internal.h
@@ -19,9 +19,12 @@ namespace internal { +class BindStateBase; class FinallyExecutorCommon; class ThenAndCatchExecutorCommon; -class BindStateBase; + +template <typename ReturnType> +class PostTaskExecutor; template <typename Functor, typename... BoundArgs> struct BindState; @@ -140,6 +143,9 @@ friend class FinallyExecutorCommon; friend class ThenAndCatchExecutorCommon; + template <typename ReturnType> + friend class PostTaskExecutor; + using InvokeFuncStorage = BindStateBase::InvokeFuncStorage; // Returns true if this callback equals |other|. |other| may be null.
diff --git a/base/task/promise/abstract_promise.cc b/base/task/promise/abstract_promise.cc index 71541ef..fa3893e5 100644 --- a/base/task/promise/abstract_promise.cc +++ b/base/task/promise/abstract_promise.cc
@@ -39,7 +39,7 @@ if (dependents_.IsCanceled()) return true; - const Executor* executor = GetExecutor(); + const PromiseExecutor* executor = GetExecutor(); return executor && executor->IsCancelled(); } @@ -147,12 +147,12 @@ void AbstractPromise::DoubleMoveDetector::CheckForDoubleMoveErrors( const base::Location& new_dependent_location, - Executor::ArgumentPassingType new_dependent_executor_type) { + PromiseExecutor::ArgumentPassingType new_dependent_executor_type) { switch (new_dependent_executor_type) { - case Executor::ArgumentPassingType::kNoCallback: + case PromiseExecutor::ArgumentPassingType::kNoCallback: return; - case Executor::ArgumentPassingType::kNormal: + case PromiseExecutor::ArgumentPassingType::kNormal: DCHECK(!dependent_move_only_promise_) << "Can't mix move only and non-move only " << callback_type_ << "callback arguments for the same " << callback_type_ @@ -163,7 +163,7 @@ std::make_unique<Location>(new_dependent_location); return; - case Executor::ArgumentPassingType::kMove: + case PromiseExecutor::ArgumentPassingType::kMove: DCHECK(!dependent_move_only_promise_ || *dependent_move_only_promise_ == new_dependent_location) << "Can't have multiple move only " << callback_type_ @@ -188,7 +188,7 @@ // Inherit |prerequisite|'s resolve ancestor if it doesn't have a resolve // callback. if (prerequisite->resolve_argument_passing_type_ == - Executor::ArgumentPassingType::kNoCallback) { + PromiseExecutor::ArgumentPassingType::kNoCallback) { ancestor_that_could_resolve_ = prerequisite->ancestor_that_could_resolve_; } @@ -203,7 +203,7 @@ if (!ancestor_that_could_reject_) { // Inherit |prerequisite|'s reject ancestor if it doesn't have a Catch. if (prerequisite->reject_argument_passing_type_ == - Executor::ArgumentPassingType::kNoCallback) { + PromiseExecutor::ArgumentPassingType::kNoCallback) { ancestor_that_could_reject_ = prerequisite->ancestor_that_could_reject_; } @@ -218,7 +218,7 @@ if (!must_catch_ancestor_that_could_reject_) { // Inherit |prerequisite|'s must catch ancestor if it doesn't have a Catch. if (prerequisite->reject_argument_passing_type_ == - Executor::ArgumentPassingType::kNoCallback) { + PromiseExecutor::ArgumentPassingType::kNoCallback) { must_catch_ancestor_that_could_reject_ = prerequisite->must_catch_ancestor_that_could_reject_; } @@ -269,20 +269,19 @@ } } -const AbstractPromise::Executor* AbstractPromise::GetExecutor() const { - return base::unique_any_cast<Executor>(&value_); +const PromiseExecutor* AbstractPromise::GetExecutor() const { + return base::unique_any_cast<PromiseExecutor>(&value_); } -AbstractPromise::Executor::PrerequisitePolicy -AbstractPromise::GetPrerequisitePolicy() { - Executor* executor = GetExecutor(); +PromiseExecutor::PrerequisitePolicy AbstractPromise::GetPrerequisitePolicy() { + PromiseExecutor* executor = GetExecutor(); if (!executor) { // If there's no executor it's because the promise has already run. We // can't run again however. The only circumstance in which we expect // GetPrerequisitePolicy() to be called after execution is when it was // resolved with a promise or we're already settled. DCHECK(IsSettled()); - return Executor::PrerequisitePolicy::kNever; + return PromiseExecutor::PrerequisitePolicy::kNever; } return executor->GetPrerequisitePolicy(); } @@ -294,7 +293,7 @@ } void AbstractPromise::Execute() { - const Executor* executor = GetExecutor(); + const PromiseExecutor* executor = GetExecutor(); DCHECK(executor || dependents_.IsCanceled()) << from_here_.ToString() << " value_ contains " << value_.type(); @@ -306,7 +305,7 @@ #if DCHECK_IS_ON() // Clear |must_catch_ancestor_that_could_reject_| if we can catch it. if (reject_argument_passing_type_ != - Executor::ArgumentPassingType::kNoCallback) { + PromiseExecutor::ArgumentPassingType::kNoCallback) { CheckedAutoLock lock(GetCheckedLock()); must_catch_ancestor_that_could_reject_ = nullptr; } @@ -340,18 +339,18 @@ DCHECK(resolved_prerequisite->IsResolved()); switch (GetPrerequisitePolicy()) { - case Executor::PrerequisitePolicy::kAll: + case PromiseExecutor::PrerequisitePolicy::kAll: if (prerequisites_->DecrementPrerequisiteCountAndCheckIfZero()) DispatchPromise(); break; - case Executor::PrerequisitePolicy::kAny: + case PromiseExecutor::PrerequisitePolicy::kAny: // PrerequisitePolicy::kAny should resolve immediately. if (prerequisites_->MarkPrerequisiteAsSettling(resolved_prerequisite)) DispatchPromise(); break; - case Executor::PrerequisitePolicy::kNever: + case PromiseExecutor::PrerequisitePolicy::kNever: break; } } @@ -372,12 +371,12 @@ bool AbstractPromise::OnPrerequisiteCancelled( AbstractPromise* canceled_prerequisite) { switch (GetPrerequisitePolicy()) { - case Executor::PrerequisitePolicy::kAll: + case PromiseExecutor::PrerequisitePolicy::kAll: // PrerequisitePolicy::kAll should cancel immediately. OnCanceled(); return false; - case Executor::PrerequisitePolicy::kAny: + case PromiseExecutor::PrerequisitePolicy::kAny: // PrerequisitePolicy::kAny should only cancel if all if it's // pre-requisites have been canceled. if (prerequisites_->DecrementPrerequisiteCountAndCheckIfZero()) { @@ -388,7 +387,7 @@ } return true; - case Executor::PrerequisitePolicy::kNever: + case PromiseExecutor::PrerequisitePolicy::kNever: // If we where resolved with a promise then we can't have had // PrerequisitePolicy::kAny or PrerequisitePolicy::kNever before the // executor was replaced with the curried promise, so pass on @@ -655,42 +654,5 @@ } } -AbstractPromise::Executor::~Executor() { - vtable_->destructor(storage_); -} - -AbstractPromise::Executor::PrerequisitePolicy -AbstractPromise::Executor::GetPrerequisitePolicy() const { - return vtable_->get_prerequisite_policy(storage_); -} - -bool AbstractPromise::Executor::IsCancelled() const { - return vtable_->is_cancelled(storage_); -} - -#if DCHECK_IS_ON() -AbstractPromise::Executor::ArgumentPassingType -AbstractPromise::Executor::ResolveArgumentPassingType() const { - return vtable_->resolve_argument_passing_type(storage_); -} - -AbstractPromise::Executor::ArgumentPassingType -AbstractPromise::Executor::RejectArgumentPassingType() const { - return vtable_->reject_argument_passing_type(storage_); -} - -bool AbstractPromise::Executor::CanResolve() const { - return vtable_->can_resolve(storage_); -} - -bool AbstractPromise::Executor::CanReject() const { - return vtable_->can_reject(storage_); -} -#endif - -void AbstractPromise::Executor::Execute(AbstractPromise* promise) { - return vtable_->execute(storage_, promise); -} - } // namespace internal } // namespace base
diff --git a/base/task/promise/abstract_promise.h b/base/task/promise/abstract_promise.h index 9d56465..0a4ef6a 100644 --- a/base/task/promise/abstract_promise.h +++ b/base/task/promise/abstract_promise.h
@@ -14,6 +14,7 @@ #include "base/no_destructor.h" #include "base/task/common/checked_lock.h" #include "base/task/promise/dependent_list.h" +#include "base/task/promise/promise_executor.h" #include "base/thread_annotations.h" namespace base { @@ -339,23 +340,18 @@ public: class AdjacencyList; - template <typename ConstructType, typename DerivedExecutorType> - struct ConstructWith {}; - - template <typename ConstructType, - typename DerivedExecutorType, - typename... ExecutorArgs> + template <typename ConstructType> static scoped_refptr<AbstractPromise> Create( - scoped_refptr<TaskRunner>&& task_runner, + const scoped_refptr<TaskRunner>& task_runner, const Location& from_here, std::unique_ptr<AdjacencyList> prerequisites, RejectPolicy reject_policy, - ConstructWith<ConstructType, DerivedExecutorType> tag, - ExecutorArgs&&... executor_args) { + ConstructType tag, + PromiseExecutor::Data&& executor_data) noexcept { scoped_refptr<AbstractPromise> promise = subtle::AdoptRefIfNeeded( - new internal::AbstractPromise( - std::move(task_runner), from_here, std::move(prerequisites), - reject_policy, tag, std::forward<ExecutorArgs>(executor_args)...), + new internal::AbstractPromise(task_runner, from_here, + std::move(prerequisites), reject_policy, + tag, std::move(executor_data)), AbstractPromise::kRefCountPreference); // It's important this is called after |promise| has been initialized // because otherwise it could trigger a scoped_refptr destructor on another @@ -364,6 +360,20 @@ return promise; } + template <typename ConstructType> + static scoped_refptr<AbstractPromise> CreateNoPrerequisitePromise( + const Location& from_here, + RejectPolicy reject_policy, + ConstructType tag, + PromiseExecutor::Data&& executor_data) noexcept { + scoped_refptr<AbstractPromise> promise = + subtle::AdoptRefIfNeeded(new internal::AbstractPromise( + nullptr, from_here, nullptr, reject_policy, + tag, std::move(executor_data)), + AbstractPromise::kRefCountPreference); + return promise; + } + AbstractPromise(const AbstractPromise&) = delete; AbstractPromise& operator=(const AbstractPromise&) = delete; @@ -439,165 +449,6 @@ "Use scoped_refptr<AbstractPromise> instead"); } - // Unresolved promises have an executor which invokes one of the callbacks - // associated with the promise. Once the callback has been invoked the - // Executor is destroyed. - // - // Ideally Executor would be a pure virtual class, but we want to store these - // inline to reduce the number of memory allocations (small object - // optimization). The problem is even though placement new returns the same - // address it was allocated at, you have to use the returned pointer. Casting - // the buffer to the derived class is undefined behavior. STL implementations - // usually store an extra pointer, but there we have opted for implementing - // our own VTable to save a little bit of memory. - class BASE_EXPORT Executor { - public: - // Constructs |Derived| in place. - template <typename Derived, typename... Args> - explicit Executor(in_place_type_t<Derived>, Args&&... args) { - static_assert(sizeof(Derived) <= MaxSize, "Derived is too big"); - static_assert(sizeof(Executor) <= sizeof(AnyInternal::InlineAlloc), - "Executor is too big"); - vtable_ = &VTableHelper<Derived>::vtable_; - new (storage_) Derived(std::forward<Args>(args)...); - } - - ~Executor(); - - // Controls whether or not a promise should wait for its prerequisites - // before becoming eligible for execution. - enum class PrerequisitePolicy : uint8_t { - // Wait for all prerequisites to resolve (or any to reject) before - // becoming eligible for execution. If any prerequisites are canceled it - // will be canceled too. - kAll, - - // Wait for any prerequisite to resolve or reject before becoming eligible - // for execution. If all prerequisites are canceled it will be canceled - // too. - kAny, - - // Never become eligible for execution. Cancellation is ignored. - kNever, - }; - - // Returns the associated PrerequisitePolicy. - PrerequisitePolicy GetPrerequisitePolicy() const; - - // NB if there is both a resolve and a reject executor we require them to - // be both canceled at the same time. - bool IsCancelled() const; - - // Describes an executor callback. - enum class ArgumentPassingType : uint8_t { - // No callback. E.g. the RejectArgumentPassingType in a promise with a - // resolve callback but no reject callback. - kNoCallback, - - // Executor callback argument passed by value or by reference. - kNormal, - - // Executor callback argument passed by r-value reference. - kMove, - }; - -#if DCHECK_IS_ON() - // Returns details of the resolve and reject executor callbacks if any. This - // data is used to diagnose double moves and missing catches. - ArgumentPassingType ResolveArgumentPassingType() const; - ArgumentPassingType RejectArgumentPassingType() const; - bool CanResolve() const; - bool CanReject() const; -#endif - - // Invokes the associate callback for |promise|. If the callback was - // cancelled it should call |promise->OnCanceled()|. If the callback - // resolved it should store the resolve result via |promise->emplace()| and - // call |promise->OnResolved()|. If the callback was rejected it should - // store the reject result in |promise->state()| and call - // |promise->OnResolved()|. - // Caution the Executor will be destructed when |promise->state()| is - // written to. - void Execute(AbstractPromise* promise); - - private: - static constexpr size_t MaxSize = sizeof(void*) * 2; - - struct VTable { - void (*destructor)(void* self); - PrerequisitePolicy (*get_prerequisite_policy)(const void* self); - bool (*is_cancelled)(const void* self); -#if DCHECK_IS_ON() - ArgumentPassingType (*resolve_argument_passing_type)(const void* self); - ArgumentPassingType (*reject_argument_passing_type)(const void* self); - bool (*can_resolve)(const void* self); - bool (*can_reject)(const void* self); -#endif - void (*execute)(void* self, AbstractPromise* promise); - - private: - DISALLOW_COPY_AND_ASSIGN(VTable); - }; - - template <typename DerivedType> - struct VTableHelper { - VTableHelper(const VTableHelper& other) = delete; - VTableHelper& operator=(const VTableHelper& other) = delete; - - static void Destructor(void* self) { - static_cast<DerivedType*>(self)->~DerivedType(); - } - - static PrerequisitePolicy GetPrerequisitePolicy(const void* self) { - return static_cast<const DerivedType*>(self)->GetPrerequisitePolicy(); - } - - static bool IsCancelled(const void* self) { - return static_cast<const DerivedType*>(self)->IsCancelled(); - } - -#if DCHECK_IS_ON() - static ArgumentPassingType ResolveArgumentPassingType(const void* self) { - return static_cast<const DerivedType*>(self) - ->ResolveArgumentPassingType(); - } - - static ArgumentPassingType RejectArgumentPassingType(const void* self) { - return static_cast<const DerivedType*>(self) - ->RejectArgumentPassingType(); - } - - static bool CanResolve(const void* self) { - return static_cast<const DerivedType*>(self)->CanResolve(); - } - - static bool CanReject(const void* self) { - return static_cast<const DerivedType*>(self)->CanReject(); - } -#endif - - static void Execute(void* self, AbstractPromise* promise) { - return static_cast<DerivedType*>(self)->Execute(promise); - } - - static constexpr VTable vtable_ = { - &VTableHelper::Destructor, - &VTableHelper::GetPrerequisitePolicy, - &VTableHelper::IsCancelled, -#if DCHECK_IS_ON() - &VTableHelper::ResolveArgumentPassingType, - &VTableHelper::RejectArgumentPassingType, - &VTableHelper::CanResolve, - &VTableHelper::CanReject, -#endif - &VTableHelper::Execute, - }; - }; - - const VTable* vtable_; - char storage_[MaxSize]; - }; - // Signals that this promise was cancelled. If executor hasn't run yet, this // will prevent it from running and cancels any dependent promises unless they // have PrerequisitePolicy::kAny, in which case they will only be canceled if @@ -693,20 +544,16 @@ private: friend base::RefCountedThreadSafe<AbstractPromise>; - template <typename ConstructType, - typename DerivedExecutorType, - typename... ExecutorArgs> - AbstractPromise(scoped_refptr<TaskRunner>&& task_runner, + template <typename ConstructType> + AbstractPromise(const scoped_refptr<TaskRunner>& task_runner, const Location& from_here, std::unique_ptr<AdjacencyList> prerequisites, RejectPolicy reject_policy, - ConstructWith<ConstructType, DerivedExecutorType>, - ExecutorArgs&&... executor_args) noexcept - : task_runner_(std::move(task_runner)), + ConstructType tag, + PromiseExecutor::Data&& executor_data) noexcept + : task_runner_(task_runner), from_here_(std::move(from_here)), - value_(in_place_type_t<Executor>(), - in_place_type_t<DerivedExecutorType>(), - std::forward<ExecutorArgs>(executor_args)...), + value_(in_place_type_t<PromiseExecutor>(), std::move(executor_data)), #if DCHECK_IS_ON() reject_policy_(reject_policy), resolve_argument_passing_type_( @@ -716,7 +563,7 @@ executor_can_resolve_(GetExecutor()->CanResolve()), executor_can_reject_(GetExecutor()->CanReject()), #endif - dependents_(ConstructType()), + dependents_(tag), prerequisites_(std::move(prerequisites)) { #if DCHECK_IS_ON() { @@ -742,17 +589,17 @@ // Returns the curried promise if there is one or null otherwise. AbstractPromise* GetCurriedPromise(); - // Returns the associated Executor if there is one. - const Executor* GetExecutor() const; + // Returns the associated PromiseExecutor if there is one. + const PromiseExecutor* GetExecutor() const; - Executor* GetExecutor() { - return const_cast<Executor*>( + PromiseExecutor* GetExecutor() { + return const_cast<PromiseExecutor*>( const_cast<const AbstractPromise*>(this)->GetExecutor()); } // With the exception of curried promises, this may only be called before the // executor has run. - Executor::PrerequisitePolicy GetPrerequisitePolicy(); + PromiseExecutor::PrerequisitePolicy GetPrerequisitePolicy(); void AddAsDependentForAllPrerequisites(); @@ -835,8 +682,8 @@ // Cached because we need to access these values after the Executor they came // from has gone away. - const Executor::ArgumentPassingType resolve_argument_passing_type_; - const Executor::ArgumentPassingType reject_argument_passing_type_; + const PromiseExecutor::ArgumentPassingType resolve_argument_passing_type_; + const PromiseExecutor::ArgumentPassingType reject_argument_passing_type_; const bool executor_can_resolve_; const bool executor_can_reject_; @@ -874,7 +721,7 @@ void CheckForDoubleMoveErrors( const base::Location& new_dependent_location, - Executor::ArgumentPassingType new_dependent_executor_type); + PromiseExecutor::ArgumentPassingType new_dependent_executor_type); private: const Location from_here_; @@ -914,11 +761,6 @@ std::unique_ptr<AdjacencyList> prerequisites_; }; -// static -template <typename T> -const AbstractPromise::Executor::VTable - AbstractPromise::Executor::VTableHelper<T>::vtable_; - } // namespace internal } // namespace base
diff --git a/base/task/promise/abstract_promise_unittest.cc b/base/task/promise/abstract_promise_unittest.cc index e48caa22..ebee591e 100644 --- a/base/task/promise/abstract_promise_unittest.cc +++ b/base/task/promise/abstract_promise_unittest.cc
@@ -27,10 +27,9 @@ using testing::ElementsAre; using ArgumentPassingType = - base::internal::AbstractPromise::Executor::ArgumentPassingType; + base::internal::PromiseExecutor::ArgumentPassingType; -using PrerequisitePolicy = - base::internal::AbstractPromise::Executor::PrerequisitePolicy; +using PrerequisitePolicy = base::internal::PromiseExecutor::PrerequisitePolicy; namespace base { namespace internal { @@ -119,7 +118,7 @@ std::unique_ptr<AbstractPromise::AdjacencyList> prerequisites; PrerequisitePolicy prerequisite_policy = - AbstractPromise::Executor::PrerequisitePolicy::kAll; + PromiseExecutor::PrerequisitePolicy::kAll; bool executor_can_resolve = true; @@ -199,17 +198,18 @@ } operator scoped_refptr<AbstractPromise>() { - return AbstractPromise::Create( - std::move(settings.task_runner), settings.from_here, - std::move(settings.prerequisites), settings.reject_policy, - AbstractPromise::ConstructWith<DependentList::ConstructUnresolved, - TestExecutor>(), - settings.prerequisite_policy, + PromiseExecutor::Data executor_data( + in_place_type_t<TestExecutor>(), settings.prerequisite_policy, #if DCHECK_IS_ON() settings.resolve_executor_type, settings.reject_executor_type, settings.executor_can_resolve, settings.executor_can_reject, #endif std::move(settings.callback)); + + return AbstractPromise::Create( + settings.task_runner, settings.from_here, + std::move(settings.prerequisites), settings.reject_policy, + DependentList::ConstructUnresolved(), std::move(executor_data)); } private:
diff --git a/base/task/promise/all_container_executor.h b/base/task/promise/all_container_executor.h index 400d0b8..e7e95d4 100644 --- a/base/task/promise/all_container_executor.h +++ b/base/task/promise/all_container_executor.h
@@ -20,8 +20,8 @@ public: bool IsCancelled() const { return false; } - AbstractPromise::Executor::PrerequisitePolicy GetPrerequisitePolicy() const { - return AbstractPromise::Executor::PrerequisitePolicy::kAll; + PromiseExecutor::PrerequisitePolicy GetPrerequisitePolicy() const { + return PromiseExecutor::PrerequisitePolicy::kAll; } struct VoidResolveType {}; @@ -46,13 +46,11 @@ } #if DCHECK_IS_ON() - AbstractPromise::Executor::ArgumentPassingType ResolveArgumentPassingType() - const { + PromiseExecutor::ArgumentPassingType ResolveArgumentPassingType() const { return UseMoveSemantics<ResolveType>::argument_passing_type; } - AbstractPromise::Executor::ArgumentPassingType RejectArgumentPassingType() - const { + PromiseExecutor::ArgumentPassingType RejectArgumentPassingType() const { return UseMoveSemantics<RejectType>::argument_passing_type; } @@ -107,17 +105,22 @@ static PromiseType All(const Location& from_here, const Container& promises) { size_t i = 0; std::vector<DependentList::Node> prerequisite_list(promises.size()); + // TODO(alexclarke): Move construction of this list and AbstractPromise out + // of line to reduce template bloat. for (auto& promise : promises) { prerequisite_list[i++].SetPrerequisite(promise.abstract_promise_.get()); } + + internal::PromiseExecutor::Data executor_data( + (in_place_type_t< + AllContainerPromiseExecutor<ResolveType, RejectType>>())); + return PromiseType(AbstractPromise::Create( nullptr, from_here, std::make_unique<AbstractPromise::AdjacencyList>( std::move(prerequisite_list)), - RejectPolicy::kMustCatchRejection, - AbstractPromise::ConstructWith< - DependentList::ConstructUnresolved, - AllContainerPromiseExecutor<ResolveType, RejectType>>())); + RejectPolicy::kMustCatchRejection, DependentList::ConstructUnresolved(), + std::move(executor_data))); } };
diff --git a/base/task/promise/all_tuple_executor.h b/base/task/promise/all_tuple_executor.h index b28c6c7..455c2272 100644 --- a/base/task/promise/all_tuple_executor.h +++ b/base/task/promise/all_tuple_executor.h
@@ -56,8 +56,8 @@ bool IsCancelled() const { return false; } - AbstractPromise::Executor::PrerequisitePolicy GetPrerequisitePolicy() const { - return AbstractPromise::Executor::PrerequisitePolicy::kAll; + PromiseExecutor::PrerequisitePolicy GetPrerequisitePolicy() const { + return PromiseExecutor::PrerequisitePolicy::kAll; } void Execute(AbstractPromise* promise) { @@ -77,13 +77,11 @@ } #if DCHECK_IS_ON() - AbstractPromise::Executor::ArgumentPassingType ResolveArgumentPassingType() - const { + PromiseExecutor::ArgumentPassingType ResolveArgumentPassingType() const { return UseMoveSemantics<ResolveTuple>::argument_passing_type; } - AbstractPromise::Executor::ArgumentPassingType RejectArgumentPassingType() - const { + PromiseExecutor::ArgumentPassingType RejectArgumentPassingType() const { return UseMoveSemantics<RejectType>::argument_passing_type; }
diff --git a/base/task/promise/finally_executor.h b/base/task/promise/finally_executor.h index ec47b74..6dcffd8 100644 --- a/base/task/promise/finally_executor.h +++ b/base/task/promise/finally_executor.h
@@ -14,10 +14,10 @@ // Exists to reduce template bloat. class BASE_EXPORT FinallyExecutorCommon { public: - explicit FinallyExecutorCommon(CallbackBase&& callback); + explicit FinallyExecutorCommon(CallbackBase&& callback) noexcept; ~FinallyExecutorCommon(); - // AbstractPromise::Executor: + // PromiseExecutor: bool IsCancelled() const; CallbackBase callback_; @@ -31,19 +31,15 @@ public: using CallbackReturnT = typename CallbackTraits<CallbackT>::ReturnType; - explicit FinallyExecutor(CallbackT&& callback) - : common_(std::move(callback)) { - static_assert(sizeof(CallbackBase) == sizeof(CallbackT), - "We assume it's possible to cast from CallbackBase to " - "CallbackT"); - } + explicit FinallyExecutor(CallbackBase&& callback) noexcept + : common_(std::move(callback)) {} ~FinallyExecutor() = default; bool IsCancelled() const { return common_.IsCancelled(); } - AbstractPromise::Executor::PrerequisitePolicy GetPrerequisitePolicy() const { - return AbstractPromise::Executor::PrerequisitePolicy::kAll; + PromiseExecutor::PrerequisitePolicy GetPrerequisitePolicy() const { + return PromiseExecutor::PrerequisitePolicy::kAll; } void Execute(AbstractPromise* promise) { @@ -62,14 +58,12 @@ } #if DCHECK_IS_ON() - AbstractPromise::Executor::ArgumentPassingType ResolveArgumentPassingType() - const { - return AbstractPromise::Executor::ArgumentPassingType::kNormal; + PromiseExecutor::ArgumentPassingType ResolveArgumentPassingType() const { + return PromiseExecutor::ArgumentPassingType::kNormal; } - AbstractPromise::Executor::ArgumentPassingType RejectArgumentPassingType() - const { - return AbstractPromise::Executor::ArgumentPassingType::kNormal; + PromiseExecutor::ArgumentPassingType RejectArgumentPassingType() const { + return PromiseExecutor::ArgumentPassingType::kNormal; } bool CanResolve() const {
diff --git a/base/task/promise/helpers.cc b/base/task/promise/helpers.cc new file mode 100644 index 0000000..5008363 --- /dev/null +++ b/base/task/promise/helpers.cc
@@ -0,0 +1,64 @@ +// 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 "base/task/promise/helpers.h" + +#include "base/bind_helpers.h" +#include "base/task/promise/no_op_promise_executor.h" +#include "base/threading/sequenced_task_runner_handle.h" + +namespace base { +namespace internal { + +PromiseHolder::PromiseHolder(scoped_refptr<internal::AbstractPromise> promise) + : promise_(std::move(promise)) {} + +PromiseHolder::~PromiseHolder() { + // Detect if the promise was not executed and if so cancel to ensure memory + // is released. + if (promise_) + promise_->OnCanceled(); +} + +PromiseHolder::PromiseHolder(PromiseHolder&& other) + : promise_(std::move(other.promise_)) {} + +scoped_refptr<internal::AbstractPromise> PromiseHolder::Unwrap() const { + return std::move(promise_); +} + +scoped_refptr<TaskRunner> GetCurrentSequence() { + return SequencedTaskRunnerHandle::Get(); +} + +DoNothing ToCallbackBase(DoNothing task) { + return task; +} + +scoped_refptr<AbstractPromise> ConstructAbstractPromiseWithSinglePrerequisite( + const scoped_refptr<TaskRunner>& task_runner, + const Location& from_here, + AbstractPromise* prerequsite, + internal::PromiseExecutor::Data&& executor_data) { + return internal::AbstractPromise::Create( + task_runner, from_here, + std::make_unique<AbstractPromise::AdjacencyList>(prerequsite), + RejectPolicy::kMustCatchRejection, + internal::DependentList::ConstructUnresolved(), std::move(executor_data)); +} + +scoped_refptr<AbstractPromise> ConstructManualPromiseResolverPromise( + const Location& from_here, + RejectPolicy reject_policy, + bool can_resolve, + bool can_reject) { + return internal::AbstractPromise::CreateNoPrerequisitePromise( + from_here, reject_policy, internal::DependentList::ConstructUnresolved(), + internal::PromiseExecutor::Data( + in_place_type_t<internal::NoOpPromiseExecutor>(), can_resolve, + can_reject)); +} + +} // namespace internal +} // namespace base
diff --git a/base/task/promise/helpers.h b/base/task/promise/helpers.h index a428992a..9a14be9 100644 --- a/base/task/promise/helpers.h +++ b/base/task/promise/helpers.h
@@ -15,11 +15,23 @@ #include "base/task/promise/promise_result.h" namespace base { +class DoNothing; + namespace internal { +// A wrapper around SequencedTaskRunnerHandle::Get(). This file is included by +// base/task_runner.h which means we can't include anything that depends on +// that! +scoped_refptr<TaskRunner> BASE_EXPORT GetCurrentSequence(); + template <typename T> using ToNonVoidT = std::conditional_t<std::is_void<T>::value, Void, T>; +// Tag dispatch helper for PostTaskExecutor and ThenAndCatchExecutor. +struct CouldResolveOrReject {}; +struct CanOnlyResolve {}; +struct CanOnlyReject {}; + // PromiseCallbackTraits computes the resolve and reject types of a Promise // from the return type of a resolve or reject callback. // @@ -35,6 +47,7 @@ struct PromiseCallbackTraits { using ResolveType = T; using RejectType = NoReject; + using TagType = CanOnlyResolve; static constexpr bool could_resolve = true; static constexpr bool could_reject = false; }; @@ -43,6 +56,7 @@ struct PromiseCallbackTraits<Resolved<T>> { using ResolveType = T; using RejectType = NoReject; + using TagType = CanOnlyResolve; static constexpr bool could_resolve = true; static constexpr bool could_reject = false; }; @@ -51,6 +65,7 @@ struct PromiseCallbackTraits<Rejected<T>> { using ResolveType = NoResolve; using RejectType = T; + using TagType = CanOnlyReject; static constexpr bool could_resolve = false; static constexpr bool could_reject = true; }; @@ -59,6 +74,7 @@ struct PromiseCallbackTraits<Promise<NoResolve, Reject>> { using ResolveType = NoResolve; using RejectType = Reject; + using TagType = CanOnlyReject; static constexpr bool could_resolve = false; static constexpr bool could_reject = true; }; @@ -67,6 +83,7 @@ struct PromiseCallbackTraits<Promise<Resolve, NoReject>> { using ResolveType = Resolve; using RejectType = NoReject; + using TagType = CanOnlyResolve; static constexpr bool could_resolve = true; static constexpr bool could_reject = false; }; @@ -75,6 +92,7 @@ struct PromiseCallbackTraits<Promise<Resolve, Reject>> { using ResolveType = Resolve; using RejectType = Reject; + using TagType = CouldResolveOrReject; static constexpr bool could_resolve = true; static constexpr bool could_reject = true; }; @@ -83,6 +101,7 @@ struct PromiseCallbackTraits<PromiseResult<NoResolve, Reject>> { using ResolveType = NoResolve; using RejectType = Reject; + using TagType = CanOnlyReject; static constexpr bool could_resolve = false; static constexpr bool could_reject = true; }; @@ -91,6 +110,7 @@ struct PromiseCallbackTraits<PromiseResult<Resolve, NoReject>> { using ResolveType = Resolve; using RejectType = NoReject; + using TagType = CanOnlyResolve; static constexpr bool could_resolve = true; static constexpr bool could_reject = false; }; @@ -99,6 +119,7 @@ struct PromiseCallbackTraits<PromiseResult<Resolve, Reject>> { using ResolveType = Resolve; using RejectType = Reject; + using TagType = CouldResolveOrReject; static constexpr bool could_resolve = true; static constexpr bool could_reject = true; }; @@ -136,11 +157,9 @@ static_assert(!std::is_rvalue_reference<T>::value, "Promise<T&&> not supported"); - static constexpr AbstractPromise::Executor::ArgumentPassingType - argument_passing_type = - UseMove<T>() - ? AbstractPromise::Executor::ArgumentPassingType::kMove - : AbstractPromise::Executor::ArgumentPassingType::kNormal; + static constexpr PromiseExecutor::ArgumentPassingType argument_passing_type = + UseMove<T>() ? PromiseExecutor::ArgumentPassingType::kMove + : PromiseExecutor::ArgumentPassingType::kNormal; }; // A std::tuple is deemed to need move semantics if any of it's members need @@ -148,11 +167,10 @@ template <typename... Ts> struct UseMoveSemantics<std::tuple<Ts...>> : public std::integral_constant<bool, any_of({UseMove<Ts>()...})> { - static constexpr AbstractPromise::Executor::ArgumentPassingType - argument_passing_type = - any_of({UseMove<Ts>()...}) - ? AbstractPromise::Executor::ArgumentPassingType::kMove - : AbstractPromise::Executor::ArgumentPassingType::kNormal; + static constexpr PromiseExecutor::ArgumentPassingType argument_passing_type = + any_of({UseMove<Ts>()...}) + ? PromiseExecutor::ArgumentPassingType::kMove + : PromiseExecutor::ArgumentPassingType::kNormal; }; // CallbackTraits extracts properties relevant to Promises from a callback. @@ -179,9 +197,8 @@ using ArgType = void; using ReturnType = T; using SignatureType = T(); - static constexpr AbstractPromise::Executor::ArgumentPassingType - argument_passing_type = - AbstractPromise::Executor::ArgumentPassingType::kNormal; + static constexpr PromiseExecutor::ArgumentPassingType argument_passing_type = + PromiseExecutor::ArgumentPassingType::kNormal; }; template <typename T, typename Arg> @@ -191,8 +208,8 @@ using ArgType = Arg; using ReturnType = T; using SignatureType = T(Arg); - static constexpr AbstractPromise::Executor::ArgumentPassingType - argument_passing_type = UseMoveSemantics<Arg>::argument_passing_type; + static constexpr PromiseExecutor::ArgumentPassingType argument_passing_type = + UseMoveSemantics<Arg>::argument_passing_type; }; template <typename T, typename... Args> @@ -205,11 +222,21 @@ using SignatureType = T(Args...); // If any arguments need move semantics, treat as if they all do. - static constexpr AbstractPromise::Executor::ArgumentPassingType - argument_passing_type = - any_of({UseMoveSemantics<Args>::value...}) - ? AbstractPromise::Executor::ArgumentPassingType::kMove - : AbstractPromise::Executor::ArgumentPassingType::kNormal; + static constexpr PromiseExecutor::ArgumentPassingType argument_passing_type = + any_of({UseMoveSemantics<Args>::value...}) + ? PromiseExecutor::ArgumentPassingType::kMove + : PromiseExecutor::ArgumentPassingType::kNormal; +}; + +template <> +struct CallbackTraits<DoNothing> { + using ResolveType = void; + using RejectType = NoReject; + using ArgType = void; + using ReturnType = void; + using SignatureType = void(); + static constexpr PromiseExecutor::ArgumentPassingType argument_passing_type = + PromiseExecutor::ArgumentPassingType::kNormal; }; // Adaptors for OnceCallback and RepeatingCallback @@ -553,49 +580,77 @@ } }; +// For use with base::Bind*. Cancels the promise if the callback was not run by +// the time the callback is deleted. +class BASE_EXPORT PromiseHolder { + public: + explicit PromiseHolder(scoped_refptr<internal::AbstractPromise> promise); + + ~PromiseHolder(); + + PromiseHolder(PromiseHolder&& other); + + scoped_refptr<internal::AbstractPromise> Unwrap() const; + + private: + mutable scoped_refptr<internal::AbstractPromise> promise_; +}; + +} // namespace internal + +template <> +struct BindUnwrapTraits<internal::PromiseHolder> { + static scoped_refptr<internal::AbstractPromise> Unwrap( + const internal::PromiseHolder& o) { + return o.Unwrap(); + } +}; + +namespace internal { + // Used by ManualPromiseResolver<> to generate callbacks. template <typename T, typename... Args> class PromiseCallbackHelper { public: - using Callback = base::OnceCallback<void(Args&&...)>; - using RepeatingCallback = base::RepeatingCallback<void(Args&&...)>; + using Callback = base::OnceCallback<void(Args...)>; + using RepeatingCallback = base::RepeatingCallback<void(Args...)>; static Callback GetResolveCallback(scoped_refptr<AbstractPromise>& promise) { return base::BindOnce( - [](scoped_refptr<AbstractPromise> promise, Args&&... args) { + [](scoped_refptr<AbstractPromise> promise, Args... args) { promise->emplace(Resolved<T>{std::forward<Args>(args)...}); promise->OnResolved(); }, - promise); + PromiseHolder(promise)); } static RepeatingCallback GetRepeatingResolveCallback( scoped_refptr<AbstractPromise>& promise) { return base::BindRepeating( - [](scoped_refptr<AbstractPromise> promise, Args&&... args) { + [](scoped_refptr<AbstractPromise> promise, Args... args) { promise->emplace(Resolved<T>{std::forward<Args>(args)...}); promise->OnResolved(); }, - promise); + PromiseHolder(promise)); } static Callback GetRejectCallback(scoped_refptr<AbstractPromise>& promise) { return base::BindOnce( - [](scoped_refptr<AbstractPromise> promise, Args&&... args) { + [](scoped_refptr<AbstractPromise> promise, Args... args) { promise->emplace(Rejected<T>{std::forward<Args>(args)...}); promise->OnRejected(); }, - promise); + PromiseHolder(promise)); } static RepeatingCallback GetRepeatingRejectCallback( scoped_refptr<AbstractPromise>& promise) { return base::BindRepeating( - [](scoped_refptr<AbstractPromise> promise, Args&&... args) { + [](scoped_refptr<AbstractPromise> promise, Args... args) { promise->emplace(Rejected<T>{std::forward<Args>(args)...}); promise->OnRejected(); }, - promise); + PromiseHolder(promise)); } }; @@ -605,13 +660,13 @@ template <typename PromiseType, typename CallbackArgType> struct IsValidPromiseArg { static constexpr bool value = - std::is_same<PromiseType, std::decay_t<CallbackArgType>>::value; + std::is_convertible<PromiseType, std::decay_t<CallbackArgType>>::value; }; template <typename PromiseType, typename CallbackArgType> struct IsValidPromiseArg<PromiseType&, CallbackArgType> { static constexpr bool value = - std::is_same<PromiseType&, CallbackArgType>::value; + std::is_convertible<PromiseType&, CallbackArgType>::value; }; // This template helps assign the reject value from a prerequisite into the @@ -626,6 +681,41 @@ // TODO(alexclarke): Specalize AllPromiseRejectHelper for variants. +// To reduce template bloat executors hold CallbackBase. These functions convert +// various types to CallbackBase. +DoNothing BASE_EXPORT ToCallbackBase(DoNothing task); + +template <typename CallbackT> +CallbackBase&& ToCallbackBase(CallbackT&& task) { + static_assert(sizeof(CallbackBase) == sizeof(CallbackT), + "We assume it's possible to cast from CallbackBase to " + "CallbackT"); + return static_cast<CallbackBase&&>(task); +} + +template <typename CallbackT> +CallbackBase&& ToCallbackBase(const CallbackT&& task) { + static_assert(sizeof(CallbackBase) == sizeof(CallbackT), + "We assume it's possible to cast from CallbackBase to " + "CallbackT"); + return static_cast<CallbackBase&&>(const_cast<CallbackT&&>(task)); +} + +// Helps reduce template bloat by moving AbstractPromise construction out of +// line. +scoped_refptr<AbstractPromise> BASE_EXPORT +ConstructAbstractPromiseWithSinglePrerequisite( + const scoped_refptr<TaskRunner>& task_runner, + const Location& from_here, + AbstractPromise* prerequsite, + internal::PromiseExecutor::Data&& executor_data) noexcept; + +scoped_refptr<AbstractPromise> BASE_EXPORT +ConstructManualPromiseResolverPromise(const Location& from_here, + RejectPolicy reject_policy, + bool can_resolve, + bool can_reject); + } // namespace internal } // namespace base
diff --git a/base/task/promise/helpers_unittest.cc b/base/task/promise/helpers_unittest.cc index edaecce..a8fe61d 100644 --- a/base/task/promise/helpers_unittest.cc +++ b/base/task/promise/helpers_unittest.cc
@@ -6,8 +6,10 @@ #include "base/bind.h" #include "base/task/promise/promise.h" +#include "base/task_runner.h" #include "base/test/bind_test_util.h" #include "base/test/do_nothing_promise.h" +#include "base/test/gtest_util.h" #include "testing/gtest/include/gtest/gtest.h" namespace base { @@ -280,5 +282,125 @@ EXPECT_EQ(result->value().type(), TypeId::From<Resolved<void>>()); } +TEST(PromiseCallbackHelper, GetResolveCallback) { + PromiseCallbackHelper<int, int> helper; + scoped_refptr<AbstractPromise> promise = + DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); + + OnceCallback<void(int)> resolve_cb = helper.GetResolveCallback(promise); + + std::move(resolve_cb).Run(1234); + + EXPECT_EQ(unique_any_cast<Resolved<int>>(promise->value()).value, 1234); +} + +TEST(PromiseCallbackHelper, GetResolveReferenceCallback) { + int foo = 123; + PromiseCallbackHelper<int&, int&> helper; + scoped_refptr<AbstractPromise> promise = + DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); + + OnceCallback<void(int&)> resolve_cb = helper.GetResolveCallback(promise); + + std::move(resolve_cb).Run(foo); + + EXPECT_EQ(&unique_any_cast<Resolved<int&>>(promise->value()).value, &foo); +} + +TEST(PromiseCallbackHelper, GetRejectCallback) { + PromiseCallbackHelper<int, int> helper; + scoped_refptr<AbstractPromise> promise = + DoNothingPromiseBuilder(FROM_HERE).SetCanReject(true).SetRejectPolicy( + RejectPolicy::kCatchNotRequired); + + OnceCallback<void(int)> reject_cb = helper.GetRejectCallback(promise); + + std::move(reject_cb).Run(1234); + + EXPECT_EQ(unique_any_cast<Rejected<int>>(promise->value()).value, 1234); +} + +TEST(PromiseCallbackHelper, GetRejectReferenceCallback) { + int foo = 123; + PromiseCallbackHelper<int&, int&> helper; + scoped_refptr<AbstractPromise> promise = + DoNothingPromiseBuilder(FROM_HERE).SetCanReject(true).SetRejectPolicy( + RejectPolicy::kCatchNotRequired); + + OnceCallback<void(int&)> reject_cb = helper.GetRejectCallback(promise); + + std::move(reject_cb).Run(foo); + + EXPECT_EQ(&unique_any_cast<Rejected<int&>>(promise->value()).value, &foo); +} + +TEST(PromiseCallbackHelper, GetRepeatingResolveCallback) { + PromiseCallbackHelper<int, int> helper; + scoped_refptr<AbstractPromise> promise = + DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); + + RepeatingCallback<void(int)> resolve_cb = + helper.GetRepeatingResolveCallback(promise); + + resolve_cb.Run(1234); + + EXPECT_EQ(unique_any_cast<Resolved<int>>(promise->value()).value, 1234); + + // Can't run |resolve_cb| more than once. + EXPECT_DCHECK_DEATH({ resolve_cb.Run(1234); }); +} + +TEST(PromiseCallbackHelper, GetRepeatingResolveReferenceCallback) { + int foo = 123; + PromiseCallbackHelper<int&, int&> helper; + scoped_refptr<AbstractPromise> promise = + DoNothingPromiseBuilder(FROM_HERE).SetCanResolve(true); + + RepeatingCallback<void(int&)> resolve_cb = + helper.GetRepeatingResolveCallback(promise); + + resolve_cb.Run(foo); + + EXPECT_EQ(&unique_any_cast<Resolved<int&>>(promise->value()).value, &foo); + + // Can't run |resolve_cb| more than once. + EXPECT_DCHECK_DEATH({ resolve_cb.Run(foo); }); +} + +TEST(PromiseCallbackHelper, GetRepeatingRejectCallback) { + PromiseCallbackHelper<int, int> helper; + scoped_refptr<AbstractPromise> promise = + DoNothingPromiseBuilder(FROM_HERE).SetCanReject(true).SetRejectPolicy( + RejectPolicy::kCatchNotRequired); + + RepeatingCallback<void(int)> reject_cb = + helper.GetRepeatingRejectCallback(promise); + + reject_cb.Run(1234); + + EXPECT_EQ(unique_any_cast<Rejected<int>>(promise->value()).value, 1234); + + // Can't run |reject_cb| more than once. + EXPECT_DCHECK_DEATH({ reject_cb.Run(1234); }); +} + +TEST(PromiseCallbackHelper, GetRepeatingRejectReferenceCallback) { + int foo = 123; + PromiseCallbackHelper<int&, int&> helper; + scoped_refptr<AbstractPromise> promise = + DoNothingPromiseBuilder(FROM_HERE).SetCanReject(true).SetRejectPolicy( + RejectPolicy::kCatchNotRequired); + + RepeatingCallback<void(int&)> reject_cb = + helper.GetRepeatingRejectCallback(promise); + + reject_cb.Run(foo); + + EXPECT_EQ(&unique_any_cast<Rejected<int&>>(promise->value()).value, &foo); + + // Can't run |reject_cb| more than once. + EXPECT_DCHECK_DEATH({ reject_cb.Run(foo); }); +} + } // namespace internal } // namespace base
diff --git a/base/task/promise/no_op_promise_executor.cc b/base/task/promise/no_op_promise_executor.cc index 36d5d47..a74cde6 100644 --- a/base/task/promise/no_op_promise_executor.cc +++ b/base/task/promise/no_op_promise_executor.cc
@@ -18,9 +18,9 @@ NoOpPromiseExecutor::~NoOpPromiseExecutor() {} -AbstractPromise::Executor::PrerequisitePolicy -NoOpPromiseExecutor::GetPrerequisitePolicy() const { - return AbstractPromise::Executor::PrerequisitePolicy::kNever; +PromiseExecutor::PrerequisitePolicy NoOpPromiseExecutor::GetPrerequisitePolicy() + const { + return PromiseExecutor::PrerequisitePolicy::kNever; } bool NoOpPromiseExecutor::IsCancelled() const { @@ -28,14 +28,14 @@ } #if DCHECK_IS_ON() -AbstractPromise::Executor::ArgumentPassingType +PromiseExecutor::ArgumentPassingType NoOpPromiseExecutor::ResolveArgumentPassingType() const { - return AbstractPromise::Executor::ArgumentPassingType::kNoCallback; + return PromiseExecutor::ArgumentPassingType::kNoCallback; } -AbstractPromise::Executor::ArgumentPassingType +PromiseExecutor::ArgumentPassingType NoOpPromiseExecutor::RejectArgumentPassingType() const { - return AbstractPromise::Executor::ArgumentPassingType::kNoCallback; + return PromiseExecutor::ArgumentPassingType::kNoCallback; } bool NoOpPromiseExecutor::CanResolve() const { @@ -55,12 +55,10 @@ bool can_resolve, bool can_reject, RejectPolicy reject_policy) { - return internal::AbstractPromise::Create( - nullptr, from_here, nullptr, reject_policy, - internal::AbstractPromise::ConstructWith< - internal::DependentList::ConstructUnresolved, - internal::NoOpPromiseExecutor>(), - can_resolve, can_reject); + return AbstractPromise::CreateNoPrerequisitePromise( + from_here, reject_policy, DependentList::ConstructUnresolved(), + PromiseExecutor::Data(in_place_type_t<NoOpPromiseExecutor>(), can_resolve, + can_reject)); } } // namespace internal
diff --git a/base/task/promise/no_op_promise_executor.h b/base/task/promise/no_op_promise_executor.h index d65dbc3..e3e03a7 100644 --- a/base/task/promise/no_op_promise_executor.h +++ b/base/task/promise/no_op_promise_executor.h
@@ -24,14 +24,12 @@ bool can_reject, RejectPolicy reject_policy); - AbstractPromise::Executor::PrerequisitePolicy GetPrerequisitePolicy() const; + PromiseExecutor::PrerequisitePolicy GetPrerequisitePolicy() const; bool IsCancelled() const; #if DCHECK_IS_ON() - AbstractPromise::Executor::ArgumentPassingType ResolveArgumentPassingType() - const; - AbstractPromise::Executor::ArgumentPassingType RejectArgumentPassingType() - const; + PromiseExecutor::ArgumentPassingType ResolveArgumentPassingType() const; + PromiseExecutor::ArgumentPassingType RejectArgumentPassingType() const; bool CanResolve() const; bool CanReject() const; #endif
diff --git a/base/task/promise/post_task_executor.h b/base/task/promise/post_task_executor.h new file mode 100644 index 0000000..0be6ce2 --- /dev/null +++ b/base/task/promise/post_task_executor.h
@@ -0,0 +1,95 @@ +// 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 BASE_TASK_PROMISE_POST_TASK_EXECUTOR_H_ +#define BASE_TASK_PROMISE_POST_TASK_EXECUTOR_H_ + +#include "base/bind_helpers.h" +#include "base/macros.h" +#include "base/task/promise/abstract_promise.h" +#include "base/task/promise/helpers.h" + +namespace base { +namespace internal { + +// PromiseExecutor for use by PostTask. +template <typename ReturnType> +class PostTaskExecutor { + public: + // Extract properties from |ReturnType|. + using CallbackTraits = PromiseCallbackTraits<ReturnType>; + using ReturnedPromiseResolveT = typename CallbackTraits::ResolveType; + using ReturnedPromiseRejectT = typename CallbackTraits::RejectType; + using ResolveStorage = Resolved<ReturnedPromiseResolveT>; + using RejectStorage = Rejected<ReturnedPromiseRejectT>; + + explicit PostTaskExecutor(CallbackBase&& task) noexcept + : task_(std::move(task)) {} + + explicit PostTaskExecutor(DoNothing task) noexcept : task_(task.Once()) {} + + PromiseExecutor::PrerequisitePolicy GetPrerequisitePolicy() const { + return PromiseExecutor::PrerequisitePolicy::kAll; + } + + bool IsCancelled() const { return task_.IsCancelled(); } + +#if DCHECK_IS_ON() + PromiseExecutor::ArgumentPassingType ResolveArgumentPassingType() const { + return PromiseExecutor::ArgumentPassingType::kNoCallback; + } + + PromiseExecutor::ArgumentPassingType RejectArgumentPassingType() const { + return PromiseExecutor::ArgumentPassingType::kNoCallback; + } + + bool CanResolve() const { return CallbackTraits::could_resolve; } + + bool CanReject() const { return CallbackTraits::could_reject; } +#endif + + NOINLINE void Execute(AbstractPromise* promise) { + static_assert(sizeof(CallbackBase) == sizeof(OnceCallback<ReturnType()>), + "We assume it's possible to cast from CallbackBase to " + "OnceCallback<ReturnType()>"); + OnceCallback<ReturnType()>* task = + static_cast<OnceCallback<ReturnType()>*>(&task_); + internal::RunHelper<OnceCallback<ReturnType()>, void, ResolveStorage, + RejectStorage>::Run(std::move(*task), nullptr, promise); + + using CheckResultTagType = + typename internal::PromiseCallbackTraits<ReturnType>::TagType; + + CheckResultType(promise, CheckResultTagType()); + } + + private: + static void CheckResultType(AbstractPromise* promise, CouldResolveOrReject) { + if (promise->IsResolvedWithPromise() || + promise->value().type() == TypeId::From<ResolveStorage>()) { + promise->OnResolved(); + } else { + DCHECK_EQ(promise->value().type(), TypeId::From<RejectStorage>()) + << " See " << promise->from_here().ToString(); + promise->OnRejected(); + } + } + + static void CheckResultType(AbstractPromise* promise, CanOnlyResolve) { + promise->OnResolved(); + } + + static void CheckResultType(AbstractPromise* promise, CanOnlyReject) { + promise->OnRejected(); + } + + CallbackBase task_; + + DISALLOW_COPY_AND_ASSIGN(PostTaskExecutor); +}; + +} // namespace internal +} // namespace base + +#endif // BASE_TASK_PROMISE_POST_TASK_EXECUTOR_H_
diff --git a/base/task/promise/post_task_executor_unittest.cc b/base/task/promise/post_task_executor_unittest.cc new file mode 100644 index 0000000..8e86aae --- /dev/null +++ b/base/task/promise/post_task_executor_unittest.cc
@@ -0,0 +1,68 @@ +// 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 "base/task/promise/post_task_executor.h" + +#include "base/bind.h" +#include "base/task/promise/abstract_promise.h" +#include "base/task/promise/helpers.h" +#include "base/task_runner.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace base { +namespace internal { + +class PostTaskExecutorTest : public testing::Test { + public: + template <typename CallbackT> + scoped_refptr<internal::AbstractPromise> CreatePostTaskPromise( + const Location& from_here, + CallbackT&& task) { + // Extract properties from |task| callback. + using CallbackTraits = CallbackTraits<std::decay_t<CallbackT>>; + + internal::PromiseExecutor::Data executor_data( + in_place_type_t< + internal::PostTaskExecutor<typename CallbackTraits::ReturnType>>(), + internal::ToCallbackBase(std::move(task))); + + return AbstractPromise::CreateNoPrerequisitePromise( + from_here, RejectPolicy::kMustCatchRejection, + internal::DependentList::ConstructUnresolved(), + std::move(executor_data)); + } +}; + +TEST_F(PostTaskExecutorTest, OnceClosure) { + bool run = false; + + scoped_refptr<AbstractPromise> p = CreatePostTaskPromise( + FROM_HERE, BindOnce([](bool* run) { *run = true; }, &run)); + + p->Execute(); + + EXPECT_TRUE(run); +} + +TEST_F(PostTaskExecutorTest, RepeatingClosure) { + bool run = false; + + scoped_refptr<AbstractPromise> p = CreatePostTaskPromise( + FROM_HERE, BindRepeating([](bool* run) { *run = true; }, &run)); + + p->Execute(); + + EXPECT_TRUE(run); +} + +TEST_F(PostTaskExecutorTest, DoNothing) { + // Check it compiles and the executor doesn't crash when run. + scoped_refptr<AbstractPromise> p = + CreatePostTaskPromise(FROM_HERE, DoNothing()); + + p->Execute(); +} + +} // namespace internal +} // namespace base
diff --git a/base/task/promise/promise.h b/base/task/promise/promise.h index 0990708..4927bde 100644 --- a/base/task/promise/promise.h +++ b/base/task/promise/promise.h
@@ -6,7 +6,6 @@ #define BASE_TASK_PROMISE_PROMISE_H_ #include "base/run_loop.h" -#include "base/task/post_task.h" #include "base/task/promise/all_container_executor.h" #include "base/task/promise/all_tuple_executor.h" #include "base/task/promise/finally_executor.h" @@ -14,10 +13,14 @@ #include "base/task/promise/no_op_promise_executor.h" #include "base/task/promise/promise_result.h" #include "base/task/promise/then_and_catch_executor.h" -#include "base/threading/sequenced_task_runner_handle.h" +#include "base/task/task_traits.h" namespace base { +// We can't include post_task.h here so we forward declare it. +BASE_EXPORT scoped_refptr<TaskRunner> CreateTaskRunner( + const TaskTraits& traits); + // Inspired by ES6 promises, Promise<> is a PostTask based callback system for // asynchronous operations. An operation can resolve (succeed) with a value and // optionally reject (fail) with a different result. Interested parties can be @@ -48,22 +51,6 @@ scoped_refptr<internal::AbstractPromise> abstract_promise) noexcept : abstract_promise_(std::move(abstract_promise)) {} - // Constructs an unresolved promise for use by a ManualPromiseResolver<> and - // TaskRunner::PostPromise. - Promise(scoped_refptr<TaskRunner> task_runner, - const Location& location, - RejectPolicy reject_policy) - : abstract_promise_(internal::AbstractPromise::Create( - std::move(task_runner), - location, - nullptr, - reject_policy, - internal::AbstractPromise::ConstructWith< - internal::DependentList::ConstructUnresolved, - internal::NoOpPromiseExecutor>(), - /* can_resolve */ !std::is_same<ResolveType, NoResolve>::value, - /* can_reject */ !std::is_same<RejectType, NoReject>::value)) {} - NOINLINE ~Promise() = default; operator bool() const { return !!abstract_promise_; } @@ -134,11 +121,15 @@ // 2. Promise<Resolve, Reject> where the result is a curried promise. // // If a promise has multiple Catches they will be run in order of creation. + // + // |task_runner| is const-ref to avoid bloat due the destructor (which posts a + // task). template <typename RejectCb> - NOINLINE auto CatchOn(scoped_refptr<TaskRunner> task_runner, + NOINLINE auto CatchOn(const scoped_refptr<TaskRunner>& task_runner, const Location& from_here, - RejectCb&& on_reject) noexcept { + RejectCb on_reject) noexcept { DCHECK(abstract_promise_); + DCHECK(!on_reject.is_null()); // Extract properties from the |on_reject| callback. using RejectCallbackTraits = internal::CallbackTraits<RejectCb>; @@ -169,23 +160,18 @@ std::is_const<std::remove_reference_t<RejectCallbackArgT>>::value, "Google C++ Style: References in function parameters must be const."); - return Promise<ReturnedPromiseResolveT, - ReturnedPromiseRejectT>(internal::AbstractPromise::Create( - std::move(task_runner), from_here, - std::make_unique<internal::AbstractPromise::AdjacencyList>( - abstract_promise_.get()), - RejectPolicy::kMustCatchRejection, - internal::AbstractPromise::ConstructWith< - internal::DependentList::ConstructUnresolved, - internal::ThenAndCatchExecutor< - OnceClosure, // Never called. - OnceCallback<typename RejectCallbackTraits::SignatureType>, - internal::NoCallback, RejectType, - Resolved<ReturnedPromiseResolveT>, - Rejected<ReturnedPromiseRejectT>>>(), - OnceClosure(), - static_cast<OnceCallback<typename RejectCallbackTraits::SignatureType>>( - std::forward<RejectCb>(on_reject)))); + internal::PromiseExecutor::Data executor_data( + in_place_type_t<internal::ThenAndCatchExecutor< + OnceClosure, // Never called. + OnceCallback<typename RejectCallbackTraits::SignatureType>, + internal::NoCallback, RejectType, Resolved<ReturnedPromiseResolveT>, + Rejected<ReturnedPromiseRejectT>>>(), + OnceClosure(), internal::ToCallbackBase(std::move(on_reject))); + + return Promise<ReturnedPromiseResolveT, ReturnedPromiseRejectT>( + ConstructAbstractPromiseWithSinglePrerequisite( + task_runner, from_here, abstract_promise_.get(), + std::move(executor_data))); } template <typename RejectCb> @@ -198,7 +184,7 @@ template <typename RejectCb> auto CatchHere(const Location& from_here, RejectCb&& on_reject) noexcept { - return CatchOn(SequencedTaskRunnerHandle::Get(), from_here, + return CatchOn(internal::GetCurrentSequence(), from_here, std::forward<RejectCb>(on_reject)); } @@ -212,11 +198,15 @@ // 2. Promise<Resolve, Reject> where the result is a curried promise. // // If a promise has multiple Thens they will be run in order of creation. + // + // |task_runner| is const-ref to avoid bloat due the destructor (which posts a + // task). template <typename ResolveCb> - NOINLINE auto ThenOn(scoped_refptr<TaskRunner> task_runner, + NOINLINE auto ThenOn(const scoped_refptr<TaskRunner>& task_runner, const Location& from_here, - ResolveCb&& on_resolve) noexcept { + ResolveCb on_resolve) noexcept { DCHECK(abstract_promise_); + DCHECK(!on_resolve.is_null()); // Extract properties from the |on_resolve| callback. using ResolveCallbackTraits = @@ -246,20 +236,18 @@ std::is_const<std::remove_reference_t<ResolveCallbackArgT>>::value, "Google C++ Style: References in function parameters must be const."); + internal::PromiseExecutor::Data executor_data( + in_place_type_t<internal::ThenAndCatchExecutor< + OnceCallback<typename ResolveCallbackTraits::SignatureType>, + OnceClosure, ResolveType, internal::NoCallback, + Resolved<ReturnedPromiseResolveT>, + Rejected<ReturnedPromiseRejectT>>>(), + internal::ToCallbackBase(std::move(on_resolve)), OnceClosure()); + return Promise<ReturnedPromiseResolveT, ReturnedPromiseRejectT>( - internal::AbstractPromise::Create( - std::move(task_runner), from_here, - std::make_unique<internal::AbstractPromise::AdjacencyList>( - abstract_promise_.get()), - RejectPolicy::kMustCatchRejection, - internal::AbstractPromise::ConstructWith< - internal::DependentList::ConstructUnresolved, - internal::ThenAndCatchExecutor< - OnceCallback<typename ResolveCallbackTraits::SignatureType>, - OnceClosure, ResolveType, internal::NoCallback, - Resolved<ReturnedPromiseResolveT>, - Rejected<ReturnedPromiseRejectT>>>(), - std::forward<ResolveCb>(on_resolve), OnceClosure())); + ConstructAbstractPromiseWithSinglePrerequisite( + task_runner, from_here, abstract_promise_.get(), + std::move(executor_data))); } template <typename ResolveCb> @@ -272,7 +260,7 @@ template <typename ResolveCb> auto ThenHere(const Location& from_here, ResolveCb&& on_resolve) noexcept { - return ThenOn(SequencedTaskRunnerHandle::Get(), from_here, + return ThenOn(internal::GetCurrentSequence(), from_here, std::forward<ResolveCb>(on_resolve)); } @@ -293,12 +281,17 @@ // Note if either |on_resolve| or |on_reject| are canceled (due to weak // pointer invalidation), then the other must be canceled at the same time as // well. This restriction only applies to this form of ThenOn/ThenHere. + // + // |task_runner| is const-ref to avoid bloat due the destructor (which posts a + // task). template <typename ResolveCb, typename RejectCb> - NOINLINE auto ThenOn(scoped_refptr<TaskRunner> task_runner, + NOINLINE auto ThenOn(const scoped_refptr<TaskRunner>& task_runner, const Location& from_here, - ResolveCb&& on_resolve, - RejectCb&& on_reject) noexcept { + ResolveCb on_resolve, + RejectCb on_reject) noexcept { DCHECK(abstract_promise_); + DCHECK(!on_resolve.is_null()); + DCHECK(!on_reject.is_null()); // Extract properties from the |on_resolve| and |on_reject| callbacks. using ResolveCallbackTraits = internal::CallbackTraits<ResolveCb>; @@ -342,24 +335,19 @@ std::is_const<std::remove_reference_t<RejectCallbackArgT>>::value, "Google C++ Style: References in function parameters must be const."); - return Promise<ReturnedPromiseResolveT, - ReturnedPromiseRejectT>(internal::AbstractPromise::Create( - std::move(task_runner), from_here, - std::make_unique<internal::AbstractPromise::AdjacencyList>( - abstract_promise_.get()), - RejectPolicy::kMustCatchRejection, - internal::AbstractPromise::ConstructWith< - internal::DependentList::ConstructUnresolved, - internal::ThenAndCatchExecutor< - OnceCallback<typename ResolveCallbackTraits::SignatureType>, - OnceCallback<typename RejectCallbackTraits::SignatureType>, - ResolveType, RejectType, Resolved<ReturnedPromiseResolveT>, - Rejected<ReturnedPromiseRejectT>>>(), - static_cast< - OnceCallback<typename ResolveCallbackTraits::SignatureType>>( - std::forward<ResolveCb>(on_resolve)), - static_cast<OnceCallback<typename RejectCallbackTraits::SignatureType>>( - std::forward<RejectCb>(on_reject)))); + internal::PromiseExecutor::Data executor_data( + in_place_type_t<internal::ThenAndCatchExecutor< + OnceCallback<typename ResolveCallbackTraits::SignatureType>, + OnceCallback<typename RejectCallbackTraits::SignatureType>, + ResolveType, RejectType, Resolved<ReturnedPromiseResolveT>, + Rejected<ReturnedPromiseRejectT>>>(), + internal::ToCallbackBase(std::move(on_resolve)), + internal::ToCallbackBase(std::move(on_reject))); + + return Promise<ReturnedPromiseResolveT, ReturnedPromiseRejectT>( + ConstructAbstractPromiseWithSinglePrerequisite( + task_runner, from_here, abstract_promise_.get(), + std::move(executor_data))); } template <typename ResolveCb, typename RejectCb> @@ -376,7 +364,7 @@ auto ThenHere(const Location& from_here, ResolveCb&& on_resolve, RejectCb&& on_reject) noexcept { - return ThenOn(SequencedTaskRunnerHandle::Get(), from_here, + return ThenOn(internal::GetCurrentSequence(), from_here, std::forward<ResolveCb>(on_resolve), std::forward<RejectCb>(on_reject)); } @@ -387,10 +375,13 @@ // promises, this doesn't return a Promise that is resolved or rejected with // the parent's value if |finally_callback| returns void. (We could support // this if needed it but it seems unlikely to be used). + // + // |task_runner| is const-ref to avoid bloat due the destructor (which posts a + // task). template <typename FinallyCb> - NOINLINE auto FinallyOn(scoped_refptr<TaskRunner> task_runner, + NOINLINE auto FinallyOn(const scoped_refptr<TaskRunner>& task_runner, const Location& from_here, - FinallyCb&& finally_callback) noexcept { + FinallyCb finally_callback) noexcept { DCHECK(abstract_promise_); // Extract properties from |finally_callback| callback. @@ -402,19 +393,17 @@ static_assert(std::is_void<CallbackArgT>::value, "|finally_callback| callback must have no arguments"); + internal::PromiseExecutor::Data executor_data( + in_place_type_t<internal::FinallyExecutor< + OnceCallback<typename CallbackTraits::ReturnType()>, + Resolved<ReturnedPromiseResolveT>, + Rejected<ReturnedPromiseRejectT>>>(), + internal::ToCallbackBase(std::move(finally_callback))); + return Promise<ReturnedPromiseResolveT, ReturnedPromiseRejectT>( - internal::AbstractPromise::Create( - std::move(task_runner), from_here, - std::make_unique<internal::AbstractPromise::AdjacencyList>( - abstract_promise_.get()), - RejectPolicy::kMustCatchRejection, - internal::AbstractPromise::ConstructWith< - internal::DependentList::ConstructUnresolved, - internal::FinallyExecutor< - OnceCallback<typename CallbackTraits::ReturnType()>, - Resolved<ReturnedPromiseResolveT>, - Rejected<ReturnedPromiseRejectT>>>(), - std::forward<FinallyCb>(finally_callback))); + ConstructAbstractPromiseWithSinglePrerequisite( + task_runner, from_here, abstract_promise_.get(), + std::move(executor_data))); } template <typename FinallyCb> @@ -428,7 +417,7 @@ template <typename FinallyCb> auto FinallyHere(const Location& from_here, FinallyCb&& finally_callback) noexcept { - return FinallyOn(SequencedTaskRunnerHandle::Get(), from_here, + return FinallyOn(internal::GetCurrentSequence(), from_here, std::move(finally_callback)); } @@ -436,14 +425,16 @@ NOINLINE static Promise<ResolveType, RejectType> CreateResolved( const Location& from_here, Args&&... args) noexcept { + internal::PromiseExecutor::Data executor_data( + in_place_type_t<internal::NoOpPromiseExecutor>(), + /* can_resolve */ true, + /* can_reject */ false); + scoped_refptr<internal::AbstractPromise> promise( internal::AbstractPromise::Create( nullptr, from_here, nullptr, RejectPolicy::kMustCatchRejection, - internal::AbstractPromise::ConstructWith< - internal::DependentList::ConstructResolved, - internal::NoOpPromiseExecutor>(), - /* can_resolve */ true, - /* can_reject */ false)); + internal::DependentList::ConstructResolved(), + std::move(executor_data))); promise->emplace(in_place_type_t<Resolved<ResolveType>>(), std::forward<Args>(args)...); return Promise<ResolveType, RejectType>(std::move(promise)); @@ -453,14 +444,16 @@ NOINLINE static Promise<ResolveType, RejectType> CreateRejected( const Location& from_here, Args&&... args) noexcept { + internal::PromiseExecutor::Data executor_data( + in_place_type_t<internal::NoOpPromiseExecutor>(), + /* can_resolve */ false, + /* can_reject */ true); + scoped_refptr<internal::AbstractPromise> promise( internal::AbstractPromise::Create( nullptr, from_here, nullptr, RejectPolicy::kMustCatchRejection, - internal::AbstractPromise::ConstructWith< - internal::DependentList::ConstructRejected, - internal::NoOpPromiseExecutor>(), - /* can_resolve */ false, - /* can_reject */ true)); + internal::DependentList::ConstructResolved(), + std::move(executor_data))); promise->emplace(in_place_type_t<Rejected<RejectType>>(), std::forward<Args>(args)...); return Promise<ResolveType, RejectType>(std::move(promise)); @@ -511,8 +504,13 @@ ManualPromiseResolver( const Location& from_here, - RejectPolicy reject_policy = RejectPolicy::kMustCatchRejection) - : promise_(SequencedTaskRunnerHandle::Get(), from_here, reject_policy) {} + RejectPolicy reject_policy = RejectPolicy::kMustCatchRejection) { + promise_ = Promise<ResolveType, RejectType>( + internal::ConstructManualPromiseResolverPromise( + from_here, reject_policy, + /* can_resolve */ !std::is_same<ResolveType, NoResolve>::value, + /* can_reject */ !std::is_same<RejectType, NoReject>::value)); + } ~ManualPromiseResolver() = default; @@ -641,16 +639,19 @@ for (auto&& p : {promises.abstract_promise_...}) { prerequisite_list[i++].SetPrerequisite(p.get()); } + + internal::PromiseExecutor::Data executor_data( + (in_place_type_t<internal::AllTuplePromiseExecutor< + ReturnedPromiseResolveT, ReturnedPromiseRejectT>>())); + return Promise<ReturnedPromiseResolveT, ReturnedPromiseRejectT>( internal::AbstractPromise::Create( nullptr, from_here, std::make_unique<internal::AbstractPromise::AdjacencyList>( std::move(prerequisite_list)), RejectPolicy::kMustCatchRejection, - internal::AbstractPromise::ConstructWith< - internal::DependentList::ConstructUnresolved, - internal::AllTuplePromiseExecutor<ReturnedPromiseResolveT, - ReturnedPromiseRejectT>>())); + internal::DependentList::ConstructUnresolved(), + std::move(executor_data))); } template <typename Resolve, typename Reject>
diff --git a/base/task/promise/promise_executor.cc b/base/task/promise/promise_executor.cc new file mode 100644 index 0000000..5d8642f --- /dev/null +++ b/base/task/promise/promise_executor.cc
@@ -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. + +#include "base/task/promise/promise_executor.h" + +namespace base { +namespace internal { + +PromiseExecutor::~PromiseExecutor() { + if (data_.vtable_) + data_.vtable_->destructor(data_.storage_.array); + data_.vtable_ = nullptr; +} + +PromiseExecutor::PrerequisitePolicy PromiseExecutor::GetPrerequisitePolicy() + const { + return data_.vtable_->get_prerequisite_policy(data_.storage_.array); +} + +bool PromiseExecutor::IsCancelled() const { + return data_.vtable_->is_cancelled(data_.storage_.array); +} + +#if DCHECK_IS_ON() +PromiseExecutor::ArgumentPassingType +PromiseExecutor::ResolveArgumentPassingType() const { + return data_.vtable_->resolve_argument_passing_type(data_.storage_.array); +} + +PromiseExecutor::ArgumentPassingType +PromiseExecutor::RejectArgumentPassingType() const { + return data_.vtable_->reject_argument_passing_type(data_.storage_.array); +} + +bool PromiseExecutor::CanResolve() const { + return data_.vtable_->can_resolve(data_.storage_.array); +} + +bool PromiseExecutor::CanReject() const { + return data_.vtable_->can_reject(data_.storage_.array); +} +#endif + +void PromiseExecutor::Execute(AbstractPromise* promise) { + return data_.vtable_->execute(data_.storage_.array, promise); +} + +} // namespace internal +} // namespace base
diff --git a/base/task/promise/promise_executor.h b/base/task/promise/promise_executor.h new file mode 100644 index 0000000..f893a2c --- /dev/null +++ b/base/task/promise/promise_executor.h
@@ -0,0 +1,222 @@ +// 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 BASE_TASK_PROMISE_PROMISE_EXECUTOR_H_ +#define BASE_TASK_PROMISE_PROMISE_EXECUTOR_H_ + +#include "base/base_export.h" +#include "base/containers/unique_any.h" +#include "base/logging.h" + +namespace base { +namespace internal { +class AbstractPromise; + +// Unresolved promises have an executor which invokes one of the callbacks +// associated with the promise. Once the callback has been invoked the +// Executor is destroyed. +// +// Ideally Executor would be a pure virtual class, but we want to store these +// inline to reduce the number of memory allocations (small object +// optimization). The problem is even though placement new returns the same +// address it was allocated at, you have to use the returned pointer. Casting +// the buffer to the derived class is undefined behavior. STL implementations +// usually store an extra pointer, but there we have opted for implementing +// our own VTable to save a little bit of memory. +class BASE_EXPORT PromiseExecutor { + private: + static constexpr size_t MaxSize = sizeof(void*) * 2; + struct VTable; + + public: + // We could just construct Executor in place, but that means templates need + // to inline the AbstractPromise constructor which we'd like to avoid due to + // binary size concerns. Despite containing refcounted objects, Data is + // intended to be memcopied into the Executor and it deliberately does not + // have a destructor. The type erasure provided by Executor allows us to + // move the AbstractPromise construction out of line. + class Data { + public: + // Constructs |Derived| in place. + template <typename Derived, typename... Args> + explicit Data(in_place_type_t<Derived>, Args&&... args) { + static_assert(sizeof(Derived) <= MaxSize, "Derived is too big"); + static_assert(sizeof(PromiseExecutor) <= sizeof(AnyInternal::InlineAlloc), + "Executor is too big"); + vtable_ = &VTableHelper<Derived>::vtable_; + new (storage_.array) Derived(std::forward<Args>(args)...); + } + + Data(Data&& other) noexcept + : vtable_(other.vtable_), storage_(other.storage_) { +#if DCHECK_IS_ON() + other.vtable_ = nullptr; +#endif + } + + Data(const Data& other) = delete; + + ~Data() { DCHECK_EQ(vtable_, nullptr); } + + private: + friend class PromiseExecutor; + + const VTable* vtable_; + struct { + char array[MaxSize]; + } storage_; + }; + + // Caution it's an error to use |data| after this. + explicit PromiseExecutor(Data&& data) : data_(std::move(data)) {} + + PromiseExecutor(PromiseExecutor&& other) noexcept + : data_(std::move(other.data_)) { + other.data_.vtable_ = nullptr; + } + + PromiseExecutor(const PromiseExecutor& other) = delete; + + ~PromiseExecutor(); + + PromiseExecutor& operator=(const PromiseExecutor& other) = delete; + + // Controls whether or not a promise should wait for its prerequisites + // before becoming eligible for execution. + enum class PrerequisitePolicy : uint8_t { + // Wait for all prerequisites to resolve (or any to reject) before + // becoming eligible for execution. If any prerequisites are canceled it + // will be canceled too. + kAll, + + // Wait for any prerequisite to resolve or reject before becoming eligible + // for execution. If all prerequisites are canceled it will be canceled + // too. + kAny, + + // Never become eligible for execution. Cancellation is ignored. + kNever, + }; + + // Returns the associated PrerequisitePolicy. + PrerequisitePolicy GetPrerequisitePolicy() const; + + // NB if there is both a resolve and a reject executor we require them to + // be both canceled at the same time. + bool IsCancelled() const; + + // Describes an executor callback. + enum class ArgumentPassingType : uint8_t { + // No callback. E.g. the RejectArgumentPassingType in a promise with a + // resolve callback but no reject callback. + kNoCallback, + + // Executor callback argument passed by value or by reference. + kNormal, + + // Executor callback argument passed by r-value reference. + kMove, + }; + +#if DCHECK_IS_ON() + // Returns details of the resolve and reject executor callbacks if any. This + // data is used to diagnose double moves and missing catches. + ArgumentPassingType ResolveArgumentPassingType() const; + ArgumentPassingType RejectArgumentPassingType() const; + bool CanResolve() const; + bool CanReject() const; +#endif + + // Invokes the associate callback for |promise|. If the callback was + // cancelled it should call |promise->OnCanceled()|. If the callback + // resolved it should store the resolve result via |promise->emplace()| and + // call |promise->OnResolved()|. If the callback was rejected it should + // store the reject result in |promise->state()| and call + // |promise->OnResolved()|. + // Caution the Executor will be destructed when |promise->state()| is + // written to. + void Execute(AbstractPromise* promise); + + private: + struct VTable { + void (*destructor)(void* self); + PrerequisitePolicy (*get_prerequisite_policy)(const void* self); + bool (*is_cancelled)(const void* self); +#if DCHECK_IS_ON() + ArgumentPassingType (*resolve_argument_passing_type)(const void* self); + ArgumentPassingType (*reject_argument_passing_type)(const void* self); + bool (*can_resolve)(const void* self); + bool (*can_reject)(const void* self); +#endif + void (*execute)(void* self, AbstractPromise* promise); + + private: + DISALLOW_COPY_AND_ASSIGN(VTable); + }; + + template <typename DerivedType> + struct VTableHelper { + VTableHelper(const VTableHelper& other) = delete; + VTableHelper& operator=(const VTableHelper& other) = delete; + + static void Destructor(void* self) { + static_cast<DerivedType*>(self)->~DerivedType(); + } + + static PrerequisitePolicy GetPrerequisitePolicy(const void* self) { + return static_cast<const DerivedType*>(self)->GetPrerequisitePolicy(); + } + + static bool IsCancelled(const void* self) { + return static_cast<const DerivedType*>(self)->IsCancelled(); + } + +#if DCHECK_IS_ON() + static ArgumentPassingType ResolveArgumentPassingType(const void* self) { + return static_cast<const DerivedType*>(self) + ->ResolveArgumentPassingType(); + } + + static ArgumentPassingType RejectArgumentPassingType(const void* self) { + return static_cast<const DerivedType*>(self)->RejectArgumentPassingType(); + } + + static bool CanResolve(const void* self) { + return static_cast<const DerivedType*>(self)->CanResolve(); + } + + static bool CanReject(const void* self) { + return static_cast<const DerivedType*>(self)->CanReject(); + } +#endif + + static void Execute(void* self, AbstractPromise* promise) { + return static_cast<DerivedType*>(self)->Execute(promise); + } + + static constexpr VTable vtable_ = { + &VTableHelper::Destructor, + &VTableHelper::GetPrerequisitePolicy, + &VTableHelper::IsCancelled, +#if DCHECK_IS_ON() + &VTableHelper::ResolveArgumentPassingType, + &VTableHelper::RejectArgumentPassingType, + &VTableHelper::CanResolve, + &VTableHelper::CanReject, +#endif + &VTableHelper::Execute, + }; + }; + + Data data_; +}; + +// static +template <typename T> +const PromiseExecutor::VTable PromiseExecutor::VTableHelper<T>::vtable_; + +} // namespace internal +} // namespace base + +#endif // BASE_TASK_PROMISE_PROMISE_EXECUTOR_H_
diff --git a/base/task/promise/promise_unittest.cc b/base/task/promise/promise_unittest.cc index 93468247..a892f16 100644 --- a/base/task/promise/promise_unittest.cc +++ b/base/task/promise/promise_unittest.cc
@@ -9,11 +9,13 @@ #include "base/bind.h" #include "base/run_loop.h" +#include "base/task/post_task.h" #include "base/test/bind_test_util.h" #include "base/test/do_nothing_promise.h" #include "base/test/gtest_util.h" #include "base/test/scoped_task_environment.h" #include "base/test/test_mock_time_task_runner.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "base/threading/thread.h" #include "base/threading/thread_task_runner_handle.h" #include "base/values.h" @@ -132,6 +134,10 @@ TEST_F(PromiseTest, GetResolveCallbackMultipleArgs) { ManualPromiseResolver<std::tuple<int, bool, float>> p(FROM_HERE); + static_assert( + std::is_same<OnceCallback<void(int, bool, float)>, + decltype(p.GetResolveCallback<int, bool, float>())>::value, + ""); p.GetResolveCallback<int, bool, float>().Run(123, true, 1.5f); RunLoop run_loop; @@ -146,6 +152,24 @@ run_loop.Run(); } +TEST_F(PromiseTest, ManualPromiseResolverCallbackLifetimeCanOutliveParent) { + OnceCallback<void(int)> resolve_cb; + + RunLoop run_loop; + { + ManualPromiseResolver<int> p(FROM_HERE); + resolve_cb = p.GetResolveCallback(); + + p.promise().ThenHere(FROM_HERE, BindLambdaForTesting([&](int result) { + EXPECT_EQ(123, result); + run_loop.Quit(); + })); + } + + std::move(resolve_cb).Run(123); + run_loop.Run(); +} + TEST_F(PromiseTest, ResolveWithTuple) { ManualPromiseResolver<void> p(FROM_HERE); p.Resolve(); @@ -1112,10 +1136,11 @@ promise_resolver->promise())) .ThenHere(FROM_HERE, base::BindOnce([](int v) { EXPECT_EQ(v, 42); })) .ThenHere(FROM_HERE, run_loop.QuitClosure()); - base::PostTaskWithTraits(FROM_HERE, {}, base::BindLambdaForTesting([&]() { - promise_resolver->Resolve(42); - promise_resolver.reset(); - })); + PostTaskWithTraits(FROM_HERE, {ThreadPool()}, + base::BindLambdaForTesting([&]() { + promise_resolver->Resolve(42); + promise_resolver.reset(); + })); run_loop.Run(); scoped_task_environment_.RunUntilIdle(); } @@ -1650,7 +1675,7 @@ #if DCHECK_IS_ON() ManualPromiseResolver<void, void> promise_resolver( FROM_HERE, RejectPolicy::kCatchNotRequired); - RepeatingCallback<void(void)> resolve = + RepeatingCallback<void()> resolve = promise_resolver.GetRepeatingResolveCallback(); resolve.Run(); @@ -1663,7 +1688,7 @@ #if DCHECK_IS_ON() ManualPromiseResolver<void, void> promise_resolver( FROM_HERE, RejectPolicy::kCatchNotRequired); - RepeatingCallback<void(void)> resolve = + RepeatingCallback<void()> resolve = promise_resolver.GetRepeatingRejectCallback(); resolve.Run();
diff --git a/base/task/promise/promise_unittest.nc b/base/task/promise/promise_unittest.nc index 261a87f2..dca01e0 100644 --- a/base/task/promise/promise_unittest.nc +++ b/base/task/promise/promise_unittest.nc
@@ -5,6 +5,7 @@ // This is a "No Compile Test" suite. // http://dev.chromium.org/developers/testing/no-compile-tests +#include "base/task_runner.h" #include "base/task/promise/promise.h" #include "base/task/promise/promise_result.h" @@ -23,7 +24,7 @@ #elif defined(NCTEST_METHOD_RESOLVE_CALLBACK_TYPE_MISSMATCH) // [r"fatal error: static_assert failed .*\"|on_resolve| callback must accept Promise::ResolveType or void\."] void WontCompile() { Promise<int, void> p; - p.ThenHere(FROM_HERE, BindOnce([](bool) { })); + p.ThenHere(FROM_HERE, BindOnce([](std::string) { })); } #elif defined(NCTEST_METHOD_REJECT_CALLBACK_TYPE_MISSMATCH) // [r"fatal error: static_assert failed .*\"|on_reject| callback must accept Promise::ResolveType or void\."] void WontCompile() {
diff --git a/base/task/promise/then_and_catch_executor.cc b/base/task/promise/then_and_catch_executor.cc index 003eb574..b30f29c 100644 --- a/base/task/promise/then_and_catch_executor.cc +++ b/base/task/promise/then_and_catch_executor.cc
@@ -7,14 +7,6 @@ namespace base { namespace internal { -ThenAndCatchExecutorCommon::ThenAndCatchExecutorCommon( - internal::CallbackBase&& resolve_executor, - internal::CallbackBase&& reject_executor) - : resolve_callback_(std::move(resolve_executor)), - reject_callback_(std::move(reject_executor)) {} - -ThenAndCatchExecutorCommon::~ThenAndCatchExecutorCommon() = default; - bool ThenAndCatchExecutorCommon::IsCancelled() const { if (!resolve_callback_.is_null()) { // If there is both a resolve and a reject executor they must be canceled @@ -26,9 +18,9 @@ return reject_callback_.IsCancelled(); } -AbstractPromise::Executor::PrerequisitePolicy +PromiseExecutor::PrerequisitePolicy ThenAndCatchExecutorCommon::GetPrerequisitePolicy() const { - return AbstractPromise::Executor::PrerequisitePolicy::kAll; + return PromiseExecutor::PrerequisitePolicy::kAll; } void ThenAndCatchExecutorCommon::Execute(AbstractPromise* promise,
diff --git a/base/task/promise/then_and_catch_executor.h b/base/task/promise/then_and_catch_executor.h index 6cc7bb5..da9faf9 100644 --- a/base/task/promise/then_and_catch_executor.h +++ b/base/task/promise/then_and_catch_executor.h
@@ -17,14 +17,18 @@ // Exists to reduce template bloat. class BASE_EXPORT ThenAndCatchExecutorCommon { public: - ThenAndCatchExecutorCommon(CallbackBase&& resolve_callback, - CallbackBase&& reject_callback); + ThenAndCatchExecutorCommon(internal::CallbackBase&& resolve_executor, + internal::CallbackBase&& reject_executor) noexcept + : resolve_callback_(std::move(resolve_executor)), + reject_callback_(std::move(reject_executor)) { + DCHECK(!resolve_callback_.is_null() || !reject_callback_.is_null()); + } - ~ThenAndCatchExecutorCommon(); + ~ThenAndCatchExecutorCommon() = default; - // AbstractPromise::Executor: + // PromiseExecutor: bool IsCancelled() const; - AbstractPromise::Executor::PrerequisitePolicy GetPrerequisitePolicy() const; + PromiseExecutor::PrerequisitePolicy GetPrerequisitePolicy() const; using ExecuteCallback = void (*)(AbstractPromise* prerequisite, AbstractPromise* promise, @@ -47,28 +51,6 @@ // Tag signals no callback which is used to eliminate dead code. struct NoCallback {}; -struct CouldResolveOrReject {}; -struct CanOnlyResolve {}; -struct CanOnlyReject {}; - -template <bool can_resolve, bool can_reject> -struct CheckResultHelper; - -template <> -struct CheckResultHelper<true, false> { - using TagType = CanOnlyResolve; -}; - -template <> -struct CheckResultHelper<true, true> { - using TagType = CouldResolveOrReject; -}; - -template <> -struct CheckResultHelper<false, true> { - using TagType = CanOnlyReject; -}; - template <typename ResolveOnceCallback, typename RejectOnceCallback, typename ArgResolve, @@ -86,20 +68,13 @@ using PrerequisiteCouldReject = std::integral_constant<bool, !std::is_same<ArgReject, NoCallback>::value>; - ThenAndCatchExecutor(ResolveOnceCallback&& resolve_callback, - RejectOnceCallback&& reject_callback) - : common_(std::move(resolve_callback), std::move(reject_callback)) { - static_assert(sizeof(CallbackBase) == sizeof(ResolveOnceCallback), - "We assume it's possible to cast from CallbackBase to " - "ResolveOnceCallback"); - static_assert(sizeof(CallbackBase) == sizeof(RejectOnceCallback), - "We assume it's possible to cast from CallbackBase to " - "RejectOnceCallback"); - } + ThenAndCatchExecutor(CallbackBase&& resolve_callback, + CallbackBase&& reject_callback) noexcept + : common_(std::move(resolve_callback), std::move(reject_callback)) {} bool IsCancelled() const { return common_.IsCancelled(); } - AbstractPromise::Executor::PrerequisitePolicy GetPrerequisitePolicy() const { + PromiseExecutor::PrerequisitePolicy GetPrerequisitePolicy() const { return common_.GetPrerequisitePolicy(); } @@ -110,17 +85,15 @@ } #if DCHECK_IS_ON() - AbstractPromise::Executor::ArgumentPassingType ResolveArgumentPassingType() - const { + PromiseExecutor::ArgumentPassingType ResolveArgumentPassingType() const { return common_.resolve_callback_.is_null() - ? AbstractPromise::Executor::ArgumentPassingType::kNoCallback + ? PromiseExecutor::ArgumentPassingType::kNoCallback : CallbackTraits<ResolveOnceCallback>::argument_passing_type; } - AbstractPromise::Executor::ArgumentPassingType RejectArgumentPassingType() - const { + PromiseExecutor::ArgumentPassingType RejectArgumentPassingType() const { return common_.reject_callback_.is_null() - ? AbstractPromise::Executor::ArgumentPassingType::kNoCallback + ? PromiseExecutor::ArgumentPassingType::kNoCallback : CallbackTraits<RejectOnceCallback>::argument_passing_type; } @@ -164,9 +137,8 @@ RejectStorage>::Run(std::move(*resolve_callback), prerequisite, promise); - using CheckResultTagType = typename CheckResultHelper< - PromiseCallbackTraits<ResolveReturnT>::could_resolve, - PromiseCallbackTraits<ResolveReturnT>::could_reject>::TagType; + using CheckResultTagType = + typename PromiseCallbackTraits<ResolveReturnT>::TagType; CheckResultType(promise, CheckResultTagType()); } @@ -188,9 +160,8 @@ RejectStorage>::Run(std::move(*reject_callback), prerequisite, promise); - using CheckResultTagType = typename CheckResultHelper< - PromiseCallbackTraits<RejectReturnT>::could_resolve, - PromiseCallbackTraits<RejectReturnT>::could_reject>::TagType; + using CheckResultTagType = + typename PromiseCallbackTraits<RejectReturnT>::TagType; CheckResultType(promise, CheckResultTagType()); }
diff --git a/base/task_runner.cc b/base/task_runner.cc index d8644a9..e2787f3d 100644 --- a/base/task_runner.cc +++ b/base/task_runner.cc
@@ -10,6 +10,7 @@ #include "base/compiler_specific.h" #include "base/logging.h" #include "base/task/promise/abstract_promise.h" +#include "base/task/promise/helpers.h" #include "base/threading/post_task_and_reply_impl.h" namespace base { @@ -40,40 +41,8 @@ return destination_->PostTask(from_here, std::move(task)); } -// TODO(alexclarke): Remove this when TaskRunner::PostPromiseInternal becomes -// pure virtual. -class PromiseHolder { - public: - explicit PromiseHolder(scoped_refptr<internal::AbstractPromise> promise) - : promise_(std::move(promise)) {} - - ~PromiseHolder() { - // Detect if the promise was not executed and if so cancel to ensure memory - // is released. - if (promise_) - promise_->OnCanceled(); - } - - PromiseHolder(PromiseHolder&& other) : promise_(std::move(other.promise_)) {} - - scoped_refptr<internal::AbstractPromise> Unwrap() const { - return std::move(promise_); - } - - private: - mutable scoped_refptr<internal::AbstractPromise> promise_; -}; - } // namespace -template <> -struct BindUnwrapTraits<PromiseHolder> { - static scoped_refptr<internal::AbstractPromise> Unwrap( - const PromiseHolder& o) { - return o.Unwrap(); - } -}; - bool TaskRunner::PostTask(const Location& from_here, OnceClosure task) { return PostDelayedTask(from_here, std::move(task), base::TimeDelta()); } @@ -88,10 +57,10 @@ bool TaskRunner::PostPromiseInternal( const scoped_refptr<internal::AbstractPromise>& promise, base::TimeDelta delay) { - return PostDelayedTask( - promise->from_here(), - BindOnce(&internal::AbstractPromise::Execute, PromiseHolder(promise)), - delay); + return PostDelayedTask(promise->from_here(), + BindOnce(&internal::AbstractPromise::Execute, + internal::PromiseHolder(promise)), + delay); } TaskRunner::TaskRunner() = default;
diff --git a/base/win/windows_version.cc b/base/win/windows_version.cc index eefb923..ce52ad64 100644 --- a/base/win/windows_version.cc +++ b/base/win/windows_version.cc
@@ -23,9 +23,8 @@ #error VS 2017 Update 3.2 or higher is required #endif -#if !defined(NTDDI_WIN10_RS5) -// Windows 10 October 2018 SDK is required to build Chrome. -#error October 2018 SDK (10.0.17763.0) or higher required. +#if !defined(NTDDI_WIN10_19H1) +#error Windows 10.0.18362.0 SDK or higher required. #endif namespace {
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index eea5766..96d0bd7 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -2529,6 +2529,11 @@ outputs = [ _final_pathmap_path, ] + + # The monochrome_apk_checker test needs pathmap when run on swarming. + data = [ + _final_pathmap_path, + ] } _final_deps += [ ":$_copy_pathmap_target" ] }
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index a238ecd..c6c0e415 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -8908803685201779008 \ No newline at end of file +8908519668143306512 \ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index b072669..6655c00 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -8908803680395747664 \ No newline at end of file +8908521448671558320 \ No newline at end of file
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc index 6db4fc0..eaa7ae5 100644 --- a/cc/layers/layer.cc +++ b/cc/layers/layer.cc
@@ -1274,6 +1274,7 @@ return; offset_to_transform_parent_ = offset; SetNeedsPushProperties(); + SetSubtreePropertyChanged(); } void Layer::InvalidatePropertyTreesIndices() {
diff --git a/cc/layers/layer.h b/cc/layers/layer.h index 8eee1adb..0001ccf9 100644 --- a/cc/layers/layer.h +++ b/cc/layers/layer.h
@@ -778,6 +778,9 @@ // layer's subtree, including itself. This causes the layer's subtree to be // considered damaged and re-displayed to the user. void SetSubtreePropertyChanged(); + void ClearSubtreePropertyChangedForTesting() { + subtree_property_changed_ = false; + } bool subtree_property_changed() const { return subtree_property_changed_; } // Internal to property tree construction. Returns ElementListType::ACTIVE
diff --git a/chrome/VERSION b/chrome/VERSION index d49a780..2164731 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=77 MINOR=0 -BUILD=3845 +BUILD=3848 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sharing/click_to_call/ClickToCallMessageHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/sharing/click_to_call/ClickToCallMessageHandler.java index c591e56..95e235f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sharing/click_to_call/ClickToCallMessageHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sharing/click_to_call/ClickToCallMessageHandler.java
@@ -10,7 +10,9 @@ import android.content.Context; import android.content.Intent; import android.content.res.Resources; +import android.net.Uri; import android.support.v4.app.NotificationCompat; +import android.text.TextUtils; import org.chromium.base.ContextUtils; import org.chromium.base.annotations.CalledByNative; @@ -32,12 +34,21 @@ private static final String EXTRA_PHONE_NUMBER = "ClickToCallMessageHandler.EXTRA_PHONE_NUMBER"; /** - * Handles the tapping of a notification by firing the call intent. + * Handles the tapping of a notification by opening the dialer with the + * phone number specified in the notification. */ public static final class TapReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - // TODO(mvanouwerkerk): fire the call intent. + String phoneNumber = intent.getStringExtra(EXTRA_PHONE_NUMBER); + final Intent dialIntent; + if (!TextUtils.isEmpty(phoneNumber)) { + dialIntent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phoneNumber)); + } else { + dialIntent = new Intent(Intent.ACTION_DIAL); + } + dialIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + ContextUtils.getApplicationContext().startActivity(dialIntent); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java index 9aa9a836..c2a67b6f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java
@@ -26,12 +26,10 @@ import org.chromium.base.annotations.NativeMethods; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordUserAction; -import org.chromium.base.task.PostTask; import org.chromium.components.signin.AccountIdProvider; import org.chromium.components.signin.AccountManagerFacade; import org.chromium.components.signin.AccountTrackerService; import org.chromium.components.signin.ChromeSigninController; -import org.chromium.content_public.browser.UiThreadTaskTraits; import java.util.ArrayList; import java.util.List; @@ -334,7 +332,8 @@ } private void notifySignInAllowedChanged() { - PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> { + // TODO(crbug.com/981470) Use PostTask and CurrentThread traits. + ThreadUtils.postOnUiThread(() -> { for (SignInAllowedObserver observer : mSignInAllowedObservers) { observer.onSignInAllowedChanged(); } @@ -518,13 +517,15 @@ mCallbacksWaitingForPendingOperation.add(runnable); return; } - PostTask.postTask(UiThreadTaskTraits.DEFAULT, runnable); + // TODO(crbug.com/981470) Use PostTask and CurrentThread traits + ThreadUtils.postOnUiThread(runnable); } private void notifyCallbacksWaitingForOperation() { ThreadUtils.assertOnUiThread(); for (Runnable callback : mCallbacksWaitingForPendingOperation) { - PostTask.postTask(UiThreadTaskTraits.DEFAULT, callback); + // TODO(crbug.com/981470) Use PostTask and CurrentThread traits. + ThreadUtils.postOnUiThread(callback); } mCallbacksWaitingForPendingOperation.clear(); } @@ -658,7 +659,8 @@ assert mSignOutState != null; if (mSignOutState.mCallback != null) { - PostTask.postTask(UiThreadTaskTraits.DEFAULT, mSignOutState.mCallback); + // TODO(crbug.com/981470) Use PostTask and CurrentThread traits. + ThreadUtils.postOnUiThread(mSignOutState.mCallback); } mSignOutState = null; notifyCallbacksWaitingForOperation();
diff --git a/chrome/android/monochrome/scripts/monochrome_apk_checker.py b/chrome/android/monochrome/scripts/monochrome_apk_checker.py index 42d0151..b74fcec 100755 --- a/chrome/android/monochrome/scripts/monochrome_apk_checker.py +++ b/chrome/android/monochrome/scripts/monochrome_apk_checker.py
@@ -132,16 +132,19 @@ apk_entries = [] with closing(StringIO.StringIO(content)) as f: for line in f: - match = ZIP_ENTRY.match(line) - if match: - apk_entries.append(APKEntry(match.group('name'), - match.group('crc'), - match.group('cmpr') == 0)) + match = ZIP_ENTRY.match(line) + if match: + apk_entries.append( + APKEntry( + match.group('name'), match.group('crc'), + match.group('cmpr') == 0)) return apk_entries def VerifySameFile(monochrome_dict, apk, changes): - """ Verify files from apk are same as those in monochrome except files - in changes + """Verify apk file content matches same files in monochrome. + + Verify files from apk are same as those in monochrome except files + in changes. """ diff = [] for a in apk: @@ -155,8 +158,10 @@ def VerifyUncompressed(monochrome, apk): - """ Verify files not being compressed in apk are also uncompressed in - Monochrome APK + """Verify uncompressed files in apk are a subset of those in monochrome. + + Verify files not being compressed in apk are also uncompressed in + Monochrome APK. """ uncompressed = [i.filename for i in apk if i.uncompressed ] monochrome_uncompressed = [i.filename for i in monochrome if i.uncompressed] @@ -166,8 +171,8 @@ '\n'.join(compressed)) def SuperSetOf(monochrome, apk): - """ Verify Monochrome is super set of apk. - """ + """Verify Monochrome is super set of apk.""" + def exists_in_some_form(f): if f in monochrome: return True @@ -183,7 +188,7 @@ missing_files = [f for f in apk if not exists_in_some_form(f)] if len(missing_files): - raise Exception("The following files are missing in Monochrome:\n %s" % + raise Exception('The following files are missing in Monochrome:\n %s' % '\n'.join(missing_files)) @@ -192,6 +197,30 @@ if not specific.search(i.filename) ] +def LoadPathmap(pathmap_path): + """Load the pathmap of obfuscated resource paths. + + Returns: A dict mapping from obfuscated paths to original paths or an + empty dict if passed a None |pathmap_path|. + """ + if pathmap_path is None: + return {} + + pathmap = {} + with open(pathmap_path, 'r') as f: + for line in f: + line = line.strip() + if line.startswith('#') or line == '': + continue + original, renamed = line.split(' -> ') + pathmap[renamed] = original + return pathmap + + +def DeobfuscateFilename(obfuscated_filename, pathmap): + return pathmap.get(obfuscated_filename, obfuscated_filename) + + def ParseArgs(args): """Parses command line options. @@ -200,43 +229,56 @@ """ parser = argparse.ArgumentParser(prog='monochrome_apk_checker') - parser.add_argument('--monochrome-apk', - required=True, - help='The monochrome APK path') + parser.add_argument( + '--monochrome-apk', required=True, help='The monochrome APK path.') + parser.add_argument( + '--monochrome-pathmap', help='The monochrome APK resources pathmap path.') parser.add_argument('--chrome-apk', required=True, help='The chrome APK path.') + parser.add_argument( + '--chrome-pathmap', help='The chrome APK resources pathmap path.') parser.add_argument('--system-webview-apk', required=True, help='The system webview APK path.') + parser.add_argument( + '--system-webview-pathmap', + help='The system webview APK resources pathmap path.') return parser.parse_args(args) def main(): options = ParseArgs(sys.argv[1:]) monochrome = DumpAPK(options.monochrome_apk) - monochrome_files = [f.filename for f in monochrome] - monochrome_dict = dict([(i.filename, i) for i in monochrome]) + monochrome_pathmap = LoadPathmap(options.monochrome_pathmap) + monochrome_files = [ + DeobfuscateFilename(f.filename, monochrome_pathmap) for f in monochrome + ] + monochrome_dict = dict([(DeobfuscateFilename(i.filename, monochrome_pathmap), + i) for i in monochrome]) chrome = RemoveSpecific(DumpAPK(options.chrome_apk), CHROME_SPECIFIC) if len(chrome) == 0: - raise Exception("Chrome should have common files with Monochrome") + raise Exception('Chrome should have common files with Monochrome') webview = RemoveSpecific(DumpAPK(options.system_webview_apk), WEBVIEW_SPECIFIC) if len(webview) == 0: - raise Exception("WebView should have common files with Monochrome") + raise Exception('WebView should have common files with Monochrome') - def check_apk(apk): - apk_files = [f.filename for f in apk] + def check_apk(apk, pathmap): + apk_files = [DeobfuscateFilename(f.filename, pathmap) for f in apk] SuperSetOf(monochrome_files, apk_files) VerifyUncompressed(monochrome, apk) VerifySameFile(monochrome_dict, chrome, CHROME_CHANGES) VerifySameFile(monochrome_dict, webview, WEBVIEW_CHANGES) - check_apk(chrome) - check_apk(webview) + chrome_pathmap = LoadPathmap(options.chrome_pathmap) + check_apk(chrome, chrome_pathmap) + + webview_pathmap = LoadPathmap(options.system_webview_pathmap) + check_apk(webview, webview_pathmap) if __name__ == '__main__': sys.exit(main())
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index d8c8fa6..0276344ac 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-77.0.3844.0_rc-r1-merged.afdo.bz2 \ No newline at end of file +chromeos-chrome-amd64-77.0.3846.0_rc-r1-merged.afdo.bz2 \ No newline at end of file
diff --git a/chrome/app/app_management_strings.grdp b/chrome/app/app_management_strings.grdp index c352a3b..3de0d886 100644 --- a/chrome/app/app_management_strings.grdp +++ b/chrome/app/app_management_strings.grdp
@@ -49,8 +49,8 @@ <message name="IDS_APP_MANAGEMENT_PERMISSIONS" desc="Label for permissions section in the app settings page."> Permissions </message> - <message name="IDS_APP_MANAGEMENT_MORE_PERMISSIONS" desc="Label for a link to more permissions for an app."> - More permissions + <message name="IDS_APP_MANAGEMENT_MORE_SETTINGS" desc="Label for a link to more settings and permissions for an app."> + More settings and permissions </message> <message name="IDS_APP_MANAGEMENT_THIS_APP_CAN" desc="Label for permissions that a Chrome app can use."> This app can:
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index bdacbcf..62122c3 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -3301,6 +3301,7 @@ "serial/serial_chooser_context.h", "serial/serial_chooser_context_factory.cc", "serial/serial_chooser_context_factory.h", + "sharing/click_to_call/click_to_call_constants.h", "sharing/click_to_call/click_to_call_sharing_dialog_controller.cc", "sharing/click_to_call/click_to_call_sharing_dialog_controller.h", "sharing/sharing_dialog_controller.cc",
diff --git a/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl_unittest.cc b/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl_unittest.cc index 6c0b8da3..53dbe99a 100644 --- a/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl_unittest.cc +++ b/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl_unittest.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl.h" #include <memory> +#include <string> #include <tuple> #include <utility> #include <vector> @@ -197,8 +198,9 @@ auto test_pwa_delegate = std::make_unique<TestPwaDelegate>(fake_cookie_manager_.get()); test_pwa_delegate_ = test_pwa_delegate.get(); + test_pending_app_manager_ = - std::make_unique<web_app::TestPendingAppManager>(); + std::make_unique<web_app::TestPendingAppManager>(&test_app_registrar_); setup_controller_ = base::WrapUnique(new AndroidSmsAppSetupControllerImpl( &profile_, test_pending_app_manager_.get(), host_content_settings_map_)); @@ -430,6 +432,7 @@ TestingProfile profile_; HostContentSettingsMap* host_content_settings_map_; std::unique_ptr<FakeCookieManager> fake_cookie_manager_; + web_app::TestAppRegistrar test_app_registrar_; std::unique_ptr<web_app::TestPendingAppManager> test_pending_app_manager_; TestPwaDelegate* test_pwa_delegate_; std::unique_ptr<AndroidSmsAppSetupController> setup_controller_;
diff --git a/chrome/browser/chromeos/extensions/default_web_app_ids.h b/chrome/browser/chromeos/extensions/default_web_app_ids.h index 196ba26..d403c77 100644 --- a/chrome/browser/chromeos/extensions/default_web_app_ids.h +++ b/chrome/browser/chromeos/extensions/default_web_app_ids.h
@@ -16,8 +16,8 @@ constexpr char kShowtimeAppId[] = "eoccpgmpiempcflglfokeengliildkag"; // Generated as -// web_app::GenerateAppIdFromURL(GURL("https://canvas.apps.chrome/index.html)). -constexpr char kCanvasAppId[] = "memejfanofdmelnjmboefinndljpifdm"; +// web_app::GenerateAppIdFromURL(GURL("https://canvas.apps.chrome/")). +constexpr char kCanvasAppId[] = "ieailfmhaghpphfffooibmlghaeopach"; } // namespace default_web_apps } // namespace chromeos
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc index 371bd94..0967c77 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -531,10 +531,8 @@ TestCase("openQuickView").TabletMode(), TestCase("openQuickViewAudio"), TestCase("openQuickViewImage"), -// QuickView image EXIF test fails on MSAN, crbug.com/973397 -#if !defined(MEMORY_SANITIZER) TestCase("openQuickViewImageExif"), -#endif + TestCase("openQuickViewImageRaw"), TestCase("openQuickViewVideo"), // QuickView PDF test fails on MSAN, crbug.com/768070 #if !defined(MEMORY_SANITIZER)
diff --git a/chrome/browser/chromeos/policy/upload_job_unittest.cc b/chrome/browser/chromeos/policy/upload_job_unittest.cc index 61f2b3c9..b644fcd 100644 --- a/chrome/browser/chromeos/policy/upload_job_unittest.cc +++ b/chrome/browser/chromeos/policy/upload_job_unittest.cc
@@ -66,8 +66,7 @@ class FakeOAuth2AccessTokenManagerWithCaching : public FakeOAuth2AccessTokenManager { public: - FakeOAuth2AccessTokenManagerWithCaching( - OAuth2TokenService* token_service, + explicit FakeOAuth2AccessTokenManagerWithCaching( OAuth2AccessTokenManager::Delegate* delegate); ~FakeOAuth2AccessTokenManagerWithCaching() override; @@ -99,9 +98,8 @@ FakeOAuth2AccessTokenManagerWithCaching:: FakeOAuth2AccessTokenManagerWithCaching( - OAuth2TokenService* token_service, OAuth2AccessTokenManager::Delegate* delegate) - : FakeOAuth2AccessTokenManager(token_service, delegate) {} + : FakeOAuth2AccessTokenManager(delegate) {} FakeOAuth2AccessTokenManagerWithCaching:: ~FakeOAuth2AccessTokenManagerWithCaching() = default; @@ -167,7 +165,6 @@ content::TestBrowserThreadBundle::IO_MAINLOOP) { oauth2_service_.OverrideAccessTokenManagerForTesting( std::make_unique<FakeOAuth2AccessTokenManagerWithCaching>( - &oauth2_service_ /* OAuth2TokenService* */, &oauth2_service_ /* OAuth2AccessTokenManager::Delegate* */)); access_token_manager_ = static_cast<FakeOAuth2AccessTokenManagerWithCaching*>(
diff --git a/chrome/browser/chromeos/settings/device_oauth2_token_service.cc b/chrome/browser/chromeos/settings/device_oauth2_token_service.cc index 1c321a1..6a37baa 100644 --- a/chrome/browser/chromeos/settings/device_oauth2_token_service.cc +++ b/chrome/browser/chromeos/settings/device_oauth2_token_service.cc
@@ -149,7 +149,7 @@ continue; if (token_is_valid) { - OAuth2TokenService::FetchOAuth2Token( + GetAccessTokenManager()->FetchOAuth2Token( scoped_request->request.get(), scoped_request->request->GetAccountId(), GetDeviceDelegate()->GetURLLoaderFactory(), scoped_request->client_id,
diff --git a/chrome/browser/resources/app_management/arc_permission_view.html b/chrome/browser/resources/app_management/arc_permission_view.html index 5df2176..a760a4ea 100644 --- a/chrome/browser/resources/app_management/arc_permission_view.html +++ b/chrome/browser/resources/app_management/arc_permission_view.html
@@ -51,7 +51,7 @@ </app-management-permission-item> <div class="subpermission-row separated-row clickable" on-click="onClickNativeSettingsButton_"> - <div class="header-text">$i18n{morePermissions}</div> + <div class="header-text">$i18n{moreSettings}</div> <div class="permission-row-controls"> <cr-icon-button class="native-settings-icon icon-external" tabindex="0">
diff --git a/chrome/browser/resources/app_management/browser_proxy.js b/chrome/browser/resources/app_management/browser_proxy.js index a82975b..a5f06fe 100644 --- a/chrome/browser/resources/app_management/browser_proxy.js +++ b/chrome/browser/resources/app_management/browser_proxy.js
@@ -60,6 +60,8 @@ { title: 'Chrome App', type: AppType.kExtension, + description: + 'A Chrome App installed from the Chrome Web Store.', }, ), app_management.FakePageHandler.createApp( @@ -74,6 +76,7 @@ { title: 'Chrome App, OEM installed', type: AppType.kExtension, + description: 'A Chrome App installed by an OEM.', installSource: InstallSource.kOem, }, ),
diff --git a/chrome/browser/resources/app_management/chrome_app_permission_view.html b/chrome/browser/resources/app_management/chrome_app_permission_view.html index 32124a0..322bf4beb 100644 --- a/chrome/browser/resources/app_management/chrome_app_permission_view.html +++ b/chrome/browser/resources/app_management/chrome_app_permission_view.html
@@ -64,12 +64,9 @@ based on the app. --> <div id="more-settings" class="subpermission-row separated-row clickable" - on-click="onClickExtensionsSettingsButton_"> - <div id="more-settings" - class="subpermission-row separated-row clickable" on-click="onClickExtensionsSettingsButton_" hidden$="[[app_.hideMoreSettings]]"> - <div class="header-text">More settings</div> + <div class="header-text">$i18n{moreSettings}</div> <cr-icon-button class="native-settings-icon icon-external" tabindex="0"> </cr-icon-button>
diff --git a/chrome/browser/resources/app_management/pwa_permission_view.html b/chrome/browser/resources/app_management/pwa_permission_view.html index 2d73d954..adbdc55 100644 --- a/chrome/browser/resources/app_management/pwa_permission_view.html +++ b/chrome/browser/resources/app_management/pwa_permission_view.html
@@ -44,7 +44,7 @@ </app-management-permission-item> <div class="subpermission-row separated-row clickable" on-click="onClickSiteSettingsButton_"> - <div class="header-text">$i18n{morePermissions}</div> + <div class="header-text">$i18n{moreSettings}</div> <div class="permission-row-controls"> <cr-icon-button class="native-settings-icon icon-external" tabindex="0">
diff --git a/chrome/browser/sharing/click_to_call/click_to_call_constants.h b/chrome/browser/sharing/click_to_call/click_to_call_constants.h new file mode 100644 index 0000000..e1304af --- /dev/null +++ b/chrome/browser/sharing/click_to_call/click_to_call_constants.h
@@ -0,0 +1,15 @@ +// 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_CLICK_TO_CALL_CLICK_TO_CALL_CONSTANTS_H_ +#define CHROME_BROWSER_SHARING_CLICK_TO_CALL_CLICK_TO_CALL_CONSTANTS_H_ + +#include "base/time/time.h" + +// Time limit for click to call message expiration. +// TODO(yasmo): Confirm this value with the team. +constexpr base::TimeDelta kSharingClickToCallMessageTTL = + base::TimeDelta::FromMinutes(10); + +#endif // CHROME_BROWSER_SHARING_CLICK_TO_CALL_CLICK_TO_CALL_CONSTANTS_H_
diff --git a/chrome/browser/sharing/click_to_call/click_to_call_sharing_dialog_controller.cc b/chrome/browser/sharing/click_to_call/click_to_call_sharing_dialog_controller.cc index fcd2ffb..3b6c9b8c 100644 --- a/chrome/browser/sharing/click_to_call/click_to_call_sharing_dialog_controller.cc +++ b/chrome/browser/sharing/click_to_call/click_to_call_sharing_dialog_controller.cc
@@ -6,6 +6,7 @@ #include "base/strings/strcat.h" #include "chrome/browser/external_protocol/external_protocol_handler.h" +#include "chrome/browser/sharing/click_to_call/click_to_call_constants.h" #include "chrome/browser/sharing/sharing_device_info.h" #include "chrome/browser/sharing/sharing_service.h" #include "chrome/browser/shell_integration.h" @@ -17,9 +18,6 @@ using SharingMessage = chrome_browser_sharing::SharingMessage; using App = ClickToCallSharingDialogController::App; -constexpr base::TimeDelta - ClickToCallSharingDialogController::kMessageExpiration; - ClickToCallSharingDialogController::ClickToCallSharingDialogController( content::WebContents* web_contents, SharingService* sharing_service, @@ -62,8 +60,8 @@ sharing_message.mutable_click_to_call_message()->set_phone_number( phone_number_); sharing_service_->SendMessageToDevice( - device.guid(), ClickToCallSharingDialogController::kMessageExpiration, - std::move(sharing_message), std::move(callback)); + device.guid(), kSharingClickToCallMessageTTL, std::move(sharing_message), + std::move(callback)); } void ClickToCallSharingDialogController::OnAppChosen(App app) {
diff --git a/chrome/browser/sharing/click_to_call/click_to_call_sharing_dialog_controller.h b/chrome/browser/sharing/click_to_call/click_to_call_sharing_dialog_controller.h index 9bfe1f0..7882ccb 100644 --- a/chrome/browser/sharing/click_to_call/click_to_call_sharing_dialog_controller.h +++ b/chrome/browser/sharing/click_to_call/click_to_call_sharing_dialog_controller.h
@@ -21,10 +21,6 @@ class ClickToCallSharingDialogController : public SharingDialogController { public: - // TODO(yasmo): Confirm this value with the team. - static constexpr base::TimeDelta kMessageExpiration = - base::TimeDelta::FromMinutes(10); - ClickToCallSharingDialogController(content::WebContents* web_contents, SharingService* sharing_service, std::string phone_number);
diff --git a/chrome/browser/sharing/click_to_call/click_to_call_sharing_dialog_controller_unittest.cc b/chrome/browser/sharing/click_to_call/click_to_call_sharing_dialog_controller_unittest.cc index 40191d22..b084191 100644 --- a/chrome/browser/sharing/click_to_call/click_to_call_sharing_dialog_controller_unittest.cc +++ b/chrome/browser/sharing/click_to_call/click_to_call_sharing_dialog_controller_unittest.cc
@@ -8,6 +8,7 @@ #include "base/guid.h" #include "base/memory/ptr_util.h" +#include "chrome/browser/sharing/click_to_call/click_to_call_constants.h" #include "chrome/browser/sharing/fake_local_device_info_provider.h" #include "chrome/browser/sharing/sharing_device_info.h" #include "chrome/browser/sharing/sharing_fcm_handler.h" @@ -86,11 +87,10 @@ sharing_message.mutable_click_to_call_message()->set_phone_number( kPhoneNumber); SharingService::SendMessageCallback callback; - EXPECT_CALL(mock_sharing_service_, - SendMessageToDevice( - Eq(kReceiverGuid), - Eq(ClickToCallSharingDialogController::kMessageExpiration), - ProtoEquals(sharing_message), _)); + EXPECT_CALL( + mock_sharing_service_, + SendMessageToDevice(Eq(kReceiverGuid), Eq(kSharingClickToCallMessageTTL), + ProtoEquals(sharing_message), _)); click_to_call_sharing_dialog_controller_.OnDeviceChosen(sharing_device_info, std::move(callback)); }
diff --git a/chrome/browser/signin/identity_manager_factory.cc b/chrome/browser/signin/identity_manager_factory.cc index 073420fd..a537aba3 100644 --- a/chrome/browser/signin/identity_manager_factory.cc +++ b/chrome/browser/signin/identity_manager_factory.cc
@@ -21,6 +21,7 @@ #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/public/identity_manager/identity_manager.h" #include "components/signin/public/identity_manager/identity_manager_builder.h" +#include "content/public/browser/network_service_instance.h" #if !defined(OS_ANDROID) #include "chrome/browser/web_data_service_factory.h" @@ -102,10 +103,13 @@ params.account_tracker_service = BuildAccountTrackerService(profile); params.image_decoder = std::make_unique<ImageDecoderImpl>(); params.local_state = g_browser_process->local_state(); + params.network_connection_tracker = content::GetNetworkConnectionTracker(); params.pref_service = profile->GetPrefs(); params.signin_client = ChromeSigninClientFactory::GetForProfile(profile); params.token_service = ProfileOAuth2TokenServiceBuilder::BuildInstanceFor( - context, params.account_tracker_service.get()); + context, params.pref_service, params.account_tracker_service.get(), + params.network_connection_tracker, params.account_consistency, + params.signin_client); std::unique_ptr<identity::IdentityManager> identity_manager = identity::BuildIdentityManager(¶ms);
diff --git a/chrome/browser/signin/profile_oauth2_token_service_builder.cc b/chrome/browser/signin/profile_oauth2_token_service_builder.cc index 86dc82e..6403f5b0 100644 --- a/chrome/browser/signin/profile_oauth2_token_service_builder.cc +++ b/chrome/browser/signin/profile_oauth2_token_service_builder.cc
@@ -12,16 +12,15 @@ #include "base/callback.h" #include "build/build_config.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/signin/account_consistency_mode_manager.h" +#include "components/signin/core/browser/account_consistency_method.h" #include "components/signin/core/browser/device_id_helper.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" -#include "content/public/browser/network_service_instance.h" +#include "components/signin/core/browser/signin_client.h" #if defined(OS_ANDROID) #include "components/signin/core/browser/oauth2_token_service_delegate_android.h" #else #include "chrome/browser/content_settings/cookie_settings_factory.h" -#include "chrome/browser/signin/chrome_signin_client_factory.h" #include "chrome/browser/web_data_service_factory.h" #include "components/content_settings/core/browser/cookie_settings.h" #include "components/signin/core/browser/cookie_settings_util.h" @@ -45,8 +44,10 @@ #if defined(OS_CHROMEOS) std::unique_ptr<signin::ProfileOAuth2TokenServiceDelegateChromeOS> -CreateCrOsOAuthDelegate(Profile* profile, - AccountTrackerService* account_tracker_service) { +CreateCrOsOAuthDelegate( + Profile* profile, + AccountTrackerService* account_tracker_service, + network::NetworkConnectionTracker* network_connection_tracker) { chromeos::AccountManagerFactory* factory = g_browser_process->platform_part()->GetAccountManagerFactory(); DCHECK(factory); @@ -58,8 +59,8 @@ !chromeos::ProfileHelper::IsSigninProfile(profile) && !chromeos::ProfileHelper::IsLockScreenAppProfile(profile); return std::make_unique<signin::ProfileOAuth2TokenServiceDelegateChromeOS>( - account_tracker_service, content::GetNetworkConnectionTracker(), - account_manager, is_regular_profile); + account_tracker_service, network_connection_tracker, account_manager, + is_regular_profile); } #endif // defined(OS_CHROMEOS) @@ -85,9 +86,10 @@ std::unique_ptr<MutableProfileOAuth2TokenServiceDelegate> CreateMutableProfileOAuthDelegate( Profile* profile, - AccountTrackerService* account_tracker_service) { - signin::AccountConsistencyMethod account_consistency = - AccountConsistencyModeManager::GetMethodForProfile(profile); + AccountTrackerService* account_tracker_service, + signin::AccountConsistencyMethod account_consistency, + SigninClient* signin_client, + network::NetworkConnectionTracker* network_connection_tracker) { // When signin cookies are cleared on exit and Dice is enabled, all tokens // should also be cleared. bool revoke_all_tokens_on_load = @@ -96,8 +98,7 @@ CookieSettingsFactory::GetForProfile(profile).get()); return std::make_unique<MutableProfileOAuth2TokenServiceDelegate>( - ChromeSigninClientFactory::GetInstance()->GetForProfile(profile), - account_tracker_service, content::GetNetworkConnectionTracker(), + signin_client, account_tracker_service, network_connection_tracker, WebDataServiceFactory::GetTokenWebDataForProfile( profile, ServiceAccessType::EXPLICIT_ACCESS), account_consistency, revoke_all_tokens_on_load, @@ -113,7 +114,10 @@ std::unique_ptr<OAuth2TokenServiceDelegate> CreateOAuth2TokenServiceDelegate( Profile* profile, - AccountTrackerService* account_tracker_service) { + AccountTrackerService* account_tracker_service, + signin::AccountConsistencyMethod account_consistency, + SigninClient* signin_client, + network::NetworkConnectionTracker* network_connection_tracker) { #if defined(OS_ANDROID) return std::make_unique<OAuth2TokenServiceDelegateAndroid>( account_tracker_service); @@ -122,7 +126,8 @@ #if defined(OS_CHROMEOS) if (chromeos::switches::IsAccountManagerEnabled()) { - return CreateCrOsOAuthDelegate(profile, account_tracker_service); + return CreateCrOsOAuthDelegate(profile, account_tracker_service, + network_connection_tracker); } #endif // defined(OS_CHROMEOS) @@ -130,7 +135,9 @@ // 1. On all platforms other than Android and Chrome OS. // 2. On Chrome OS, if Account Manager has not been switched on yet // (chromeos::switches::IsAccountManagerEnabled). - return CreateMutableProfileOAuthDelegate(profile, account_tracker_service); + return CreateMutableProfileOAuthDelegate(profile, account_tracker_service, + account_consistency, signin_client, + network_connection_tracker); #endif // defined(OS_ANDROID) } @@ -141,7 +148,11 @@ std::unique_ptr<ProfileOAuth2TokenService> ProfileOAuth2TokenServiceBuilder::BuildInstanceFor( content::BrowserContext* context, - AccountTrackerService* account_tracker_service) { + PrefService* pref_service, + AccountTrackerService* account_tracker_service, + network::NetworkConnectionTracker* network_connection_tracker, + signin::AccountConsistencyMethod account_consistency, + SigninClient* signin_client) { Profile* profile = static_cast<Profile*>(context); // On ChromeOS the device ID is not managed by the token service. @@ -149,11 +160,12 @@ // Ensure the device ID is not empty. This is important for Dice, because the // device ID is needed on the network thread, but can only be generated on the // main thread. - std::string device_id = signin::GetSigninScopedDeviceId(profile->GetPrefs()); + std::string device_id = signin::GetSigninScopedDeviceId(pref_service); DCHECK(!device_id.empty()); #endif return std::make_unique<ProfileOAuth2TokenService>( - profile->GetPrefs(), - CreateOAuth2TokenServiceDelegate(profile, account_tracker_service)); + pref_service, CreateOAuth2TokenServiceDelegate( + profile, account_tracker_service, account_consistency, + signin_client, network_connection_tracker)); }
diff --git a/chrome/browser/signin/profile_oauth2_token_service_builder.h b/chrome/browser/signin/profile_oauth2_token_service_builder.h index e98ed992..43f4815 100644 --- a/chrome/browser/signin/profile_oauth2_token_service_builder.h +++ b/chrome/browser/signin/profile_oauth2_token_service_builder.h
@@ -7,20 +7,34 @@ #include <memory> +class AccountTrackerService; +class IdentityManagerFactory; +class PrefService; +class ProfileOAuth2TokenService; +class SigninClient; + +namespace signin { +enum class AccountConsistencyMethod; +} + namespace content { class BrowserContext; } -class AccountTrackerService; -class ProfileOAuth2TokenService; -class IdentityManagerFactory; +namespace network { +class NetworkConnectionTracker; +} class ProfileOAuth2TokenServiceBuilder { private: // Builds a ProfileOAuth2TokenService instance for use by IdentityManager. static std::unique_ptr<ProfileOAuth2TokenService> BuildInstanceFor( content::BrowserContext* context, - AccountTrackerService* account_tracker_service); + PrefService* pref_service, + AccountTrackerService* account_tracker_service, + network::NetworkConnectionTracker* network_connection_tracker, + signin::AccountConsistencyMethod account_consistency, + SigninClient* signin_client); friend IdentityManagerFactory; };
diff --git a/chrome/browser/themes/theme_service.cc b/chrome/browser/themes/theme_service.cc index fdb21f9..21d24c0 100644 --- a/chrome/browser/themes/theme_service.cc +++ b/chrome/browser/themes/theme_service.cc
@@ -680,16 +680,17 @@ if (!ready_) return; + base::Optional<std::string> previous_theme_id; + if (UsingExtensionTheme()) + previous_theme_id = GetThemeID(); + SwapThemeSupplier(nullptr); ClearThemePrefs(); - // There should be no more infobars. This may not be the case because of - // http://crbug.com/62154 - // RemoveUnusedThemes is called on a task because ClearAllThemeData() may - // be called as a result of OnExtensionUnloaded(). - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(&ThemeService::RemoveUnusedThemes, - weak_ptr_factory_.GetWeakPtr(), true)); + // Disable extension after modifying the prefs so that unloading the extension + // doesn't trigger |ClearAllThemeData| again. + if (previous_theme_id.has_value()) + DisableExtension(previous_theme_id.value()); } void ThemeService::FixInconsistentPreferencesIfNeeded() {}
diff --git a/chrome/browser/themes/theme_service_unittest.cc b/chrome/browser/themes/theme_service_unittest.cc index 7e7a889b..aede2c0 100644 --- a/chrome/browser/themes/theme_service_unittest.cc +++ b/chrome/browser/themes/theme_service_unittest.cc
@@ -206,15 +206,14 @@ ExtensionRegistry::DISABLED)); // 4) Disabling the current theme extension should revert to the default theme - // and uninstall any installed theme extensions. - theme_service->OnInfobarDestroyed(); + // and disable any installed theme extensions. EXPECT_FALSE(theme_service->UsingDefaultTheme()); service_->DisableExtension(extension2_id, extensions::disable_reason::DISABLE_USER_ACTION); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(theme_service->UsingDefaultTheme()); - EXPECT_FALSE(service_->GetInstalledExtension(extension1_id)); - EXPECT_FALSE(service_->GetInstalledExtension(extension2_id)); + EXPECT_FALSE(service_->IsExtensionEnabled(extension1_id)); + EXPECT_FALSE(service_->IsExtensionEnabled(extension2_id)); } // Test the ThemeService's behavior when a theme is upgraded. @@ -524,4 +523,19 @@ EXPECT_FALSE(service_->IsExtensionEnabled(extension1_id)); } +TEST_F(ThemeServiceTest, UseDefaultTheme_DisableExtensionTest) { + ThemeService* theme_service = + ThemeServiceFactory::GetForProfile(profile_.get()); + base::ScopedTempDir temp_dir1; + ASSERT_TRUE(temp_dir1.CreateUniqueTempDir()); + const std::string& extension1_id = + LoadUnpackedMinimalThemeAt(temp_dir1.GetPath()); + EXPECT_EQ(extension1_id, theme_service->GetThemeID()); + EXPECT_TRUE(service_->IsExtensionEnabled(extension1_id)); + + // Resetting to default theme should disable previous theme. + theme_service->UseDefaultTheme(); + EXPECT_FALSE(service_->IsExtensionEnabled(extension1_id)); +} + } // namespace theme_service_internal
diff --git a/chrome/browser/ui/app_list/app_launch_event_logger.cc b/chrome/browser/ui/app_list/app_launch_event_logger.cc index 40a7eba..dfc770894 100644 --- a/chrome/browser/ui/app_list/app_launch_event_logger.cc +++ b/chrome/browser/ui/app_list/app_launch_event_logger.cc
@@ -42,7 +42,7 @@ namespace { -constexpr unsigned int kNumRandomAppsToLog = 5; +constexpr unsigned int kNumRandomAppsToLog = 25; const char kArcScheme[] = "arc://"; const char kExtensionSchemeWithDelimiter[] = "chrome-extension://"; @@ -489,7 +489,7 @@ kTotalHoursBucketSizeMultiplier)) .Record(ukm::UkmRecorder::Get()); - // Log click data about the app clicked on and up to five other apps. This + // Log click data about the app clicked on and up to 25 other apps. This // represents the state of the data immediately before the click. const std::vector<std::string> apps_to_log = ChooseAppsToLog(app_launch_event.app_id());
diff --git a/chrome/browser/ui/app_list/app_launch_event_logger.h b/chrome/browser/ui/app_list/app_launch_event_logger.h index a134e31..dfd08f6 100644 --- a/chrome/browser/ui/app_list/app_launch_event_logger.h +++ b/chrome/browser/ui/app_list/app_launch_event_logger.h
@@ -42,7 +42,7 @@ // a hash of the package name, and for PWAs and bookmark apps the keys are the // urls associated with the PWA/bookmark. // At the time of app launch this class logs metrics about the app clicked on -// and another five apps that were not clicked on, chosen at random. +// and up to another 25 apps that were not clicked on, chosen at random. class AppLaunchEventLogger { public: AppLaunchEventLogger(); @@ -92,8 +92,8 @@ const std::string& app_id, const std::string& arc_package_name, const std::string& pwa_url); - // Chooses up to five random apps to log, plus the app clicked on. - // If there are fewer than five apps that can be logged on the device, logs + // Chooses up to 25 random apps to log, plus the app clicked on. + // If there are fewer than 25 apps that can be logged on the device, logs // every app once. std::vector<std::string> ChooseAppsToLog(const std::string clicked_app_id); // Records a UMA histogram of the app type clicked on.
diff --git a/chrome/browser/ui/startup/startup_browser_creator.cc b/chrome/browser/ui/startup/startup_browser_creator.cc index 55fcb0a..3498d72 100644 --- a/chrome/browser/ui/startup/startup_browser_creator.cc +++ b/chrome/browser/ui/startup/startup_browser_creator.cc
@@ -41,6 +41,7 @@ #include "chrome/browser/profiles/profile_attributes_entry.h" #include "chrome/browser/profiles/profile_attributes_storage.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/profiles/profiles_state.h" #include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" @@ -1011,6 +1012,17 @@ } #endif // defined(OS_WIN) +#if defined(OS_LINUX) || defined(OS_WIN) || defined(OS_MACOSX) + // If opening in Guest mode switch is provided, load the default profile so + // that last opened profile would not trigger a user management dialog. + if (command_line.HasSwitch(switches::kGuest)) { + PrefService* service = g_browser_process->local_state(); + DCHECK(service); + if (service->GetBoolean(prefs::kBrowserGuestModeEnabled)) + return profiles::GetDefaultProfileDir(user_data_dir); + } +#endif + if (command_line.HasSwitch(switches::kProfileDirectory)) { return user_data_dir.Append( command_line.GetSwitchValuePath(switches::kProfileDirectory));
diff --git a/chrome/browser/ui/webui/app_management/app_management_ui.cc b/chrome/browser/ui/webui/app_management/app_management_ui.cc index b1872df7..58a21d4 100644 --- a/chrome/browser/ui/webui/app_management/app_management_ui.cc +++ b/chrome/browser/ui/webui/app_management/app_management_ui.cc
@@ -40,7 +40,7 @@ {"location", IDS_APP_MANAGEMENT_LOCATION}, {"microphone", IDS_APP_MANAGEMENT_MICROPHONE}, {"moreApps", IDS_APP_MANAGEMENT_MORE_APPS}, - {"morePermissions", IDS_APP_MANAGEMENT_MORE_PERMISSIONS}, + {"moreSettings", IDS_APP_MANAGEMENT_MORE_SETTINGS}, {"noSearchResults", IDS_APP_MANAGEMENT_NO_RESULTS}, {"notifications", IDS_APP_MANAGEMENT_NOTIFICATIONS}, {"notificationSublabel", IDS_APP_MANAGEMENT_NOTIFICATIONS_SUBLABEL},
diff --git a/chrome/browser/web_applications/OWNERS b/chrome/browser/web_applications/OWNERS index 52802bc..d552597 100644 --- a/chrome/browser/web_applications/OWNERS +++ b/chrome/browser/web_applications/OWNERS
@@ -2,6 +2,8 @@ benwells@chromium.org calamity@chromium.org dominickn@chromium.org +ericwilligers@chromium.org +harrisjay@chromium.org loyso@chromium.org mgiuca@chromium.org nigeltao@chromium.org
diff --git a/chrome/browser/web_applications/bookmark_apps/bookmark_app_install_manager.cc b/chrome/browser/web_applications/bookmark_apps/bookmark_app_install_manager.cc index 15e1b8a..8098e72 100644 --- a/chrome/browser/web_applications/bookmark_apps/bookmark_app_install_manager.cc +++ b/chrome/browser/web_applications/bookmark_apps/bookmark_app_install_manager.cc
@@ -229,10 +229,8 @@ } // namespace -BookmarkAppInstallManager::BookmarkAppInstallManager( - Profile* profile, - web_app::InstallFinalizer* finalizer) - : InstallManager(profile), finalizer_(finalizer) { +BookmarkAppInstallManager::BookmarkAppInstallManager(Profile* profile) + : InstallManager(profile) { bookmark_app_helper_factory_ = base::BindRepeating( [](Profile* profile, std::unique_ptr<WebApplicationInfo> web_app_info, content::WebContents* web_contents, @@ -359,7 +357,7 @@ ExtensionSystem::Get(profile())->extension_service(); DCHECK(extension_service); - if (finalizer_->CanSkipAppUpdateForSync(app_id, *web_application_info)) + if (finalizer()->CanSkipAppUpdateForSync(app_id, *web_application_info)) return; #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/web_applications/bookmark_apps/bookmark_app_install_manager.h b/chrome/browser/web_applications/bookmark_apps/bookmark_app_install_manager.h index 84fbebe0..5a13d5d 100644 --- a/chrome/browser/web_applications/bookmark_apps/bookmark_app_install_manager.h +++ b/chrome/browser/web_applications/bookmark_apps/bookmark_app_install_manager.h
@@ -20,7 +20,6 @@ } namespace web_app { -class InstallFinalizer; class WebAppDataRetriever; } @@ -32,8 +31,7 @@ // crbug.com/915043. class BookmarkAppInstallManager final : public web_app::InstallManager { public: - BookmarkAppInstallManager(Profile* profile, - web_app::InstallFinalizer* finalizer); + explicit BookmarkAppInstallManager(Profile* profile); ~BookmarkAppInstallManager() override; // InstallManager: @@ -85,7 +83,6 @@ private: BookmarkAppHelperFactory bookmark_app_helper_factory_; DataRetrieverFactory data_retriever_factory_; - web_app::InstallFinalizer* finalizer_; DISALLOW_COPY_AND_ASSIGN(BookmarkAppInstallManager); };
diff --git a/chrome/browser/web_applications/bookmark_apps/bookmark_app_install_manager_unittest.cc b/chrome/browser/web_applications/bookmark_apps/bookmark_app_install_manager_unittest.cc index 2d248c6..6987b1a 100644 --- a/chrome/browser/web_applications/bookmark_apps/bookmark_app_install_manager_unittest.cc +++ b/chrome/browser/web_applications/bookmark_apps/bookmark_app_install_manager_unittest.cc
@@ -35,8 +35,8 @@ ChromeRenderViewHostTestHarness::SetUp(); install_finalizer_ = std::make_unique<web_app::TestInstallFinalizer>(); - install_manager_ = std::make_unique<BookmarkAppInstallManager>( - profile(), install_finalizer_.get()); + install_manager_ = std::make_unique<BookmarkAppInstallManager>(profile()); + install_manager_->SetSubsystems(nullptr, install_finalizer_.get()); extensions::TestExtensionSystem* test_extension_system = static_cast<extensions::TestExtensionSystem*>(
diff --git a/chrome/browser/web_applications/bookmark_apps/policy/web_app_policy_manager_unittest.cc b/chrome/browser/web_applications/bookmark_apps/policy/web_app_policy_manager_unittest.cc index dd8098b..4938a36 100644 --- a/chrome/browser/web_applications/bookmark_apps/policy/web_app_policy_manager_unittest.cc +++ b/chrome/browser/web_applications/bookmark_apps/policy/web_app_policy_manager_unittest.cc
@@ -159,27 +159,30 @@ class WebAppPolicyManagerTest : public ChromeRenderViewHostTestHarness { public: - WebAppPolicyManagerTest() - : test_web_app_provider_creator_( - base::BindOnce(&WebAppPolicyManagerTest::CreateWebAppProvider, - base::Unretained(this))) {} + WebAppPolicyManagerTest() {} ~WebAppPolicyManagerTest() override = default; - std::unique_ptr<KeyedService> CreateWebAppProvider(Profile* profile) { - auto provider = std::make_unique<TestWebAppProvider>(profile); - provider->Init(); + void SetUp() override { + ChromeRenderViewHostTestHarness::SetUp(); - auto test_pending_app_manager = std::make_unique<TestPendingAppManager>(); + DCHECK(profile()->AsTestingProfile()); + auto* provider = static_cast<web_app::TestWebAppProvider*>( + web_app::WebAppProvider::Get(profile())); + + auto test_app_registrar = std::make_unique<TestAppRegistrar>(); + test_app_registrar_ = test_app_registrar.get(); + provider->SetRegistrar(std::move(test_app_registrar)); + + auto test_pending_app_manager = + std::make_unique<TestPendingAppManager>(test_app_registrar_); test_pending_app_manager_ = test_pending_app_manager.get(); provider->SetPendingAppManager(std::move(test_pending_app_manager)); - auto web_app_policy_manager = std::make_unique<WebAppPolicyManager>( - profile, test_pending_app_manager_); + auto web_app_policy_manager = + std::make_unique<WebAppPolicyManager>(profile()); web_app_policy_manager_ = web_app_policy_manager.get(); provider->SetWebAppPolicyManager(std::move(web_app_policy_manager)); - - return provider; } void SimulatePreviouslyInstalledApp( @@ -196,7 +199,7 @@ WebAppPolicyManager* policy_manager() { return web_app_policy_manager_; } private: - TestWebAppProviderCreator test_web_app_provider_creator_; + TestAppRegistrar* test_app_registrar_ = nullptr; TestPendingAppManager* test_pending_app_manager_ = nullptr; WebAppPolicyManager* web_app_policy_manager_ = nullptr;
diff --git a/chrome/browser/web_applications/bookmark_apps/system_web_app_manager_browsertest.cc b/chrome/browser/web_applications/bookmark_apps/system_web_app_manager_browsertest.cc index d67a9de4..a7f70fe 100644 --- a/chrome/browser/web_applications/bookmark_apps/system_web_app_manager_browsertest.cc +++ b/chrome/browser/web_applications/bookmark_apps/system_web_app_manager_browsertest.cc
@@ -145,13 +145,11 @@ DCHECK(SystemWebAppManager::IsEnabled()); auto provider = std::make_unique<TestWebAppProvider>(profile); - // Create all real subsystems but do not start them: - provider->Init(); // Override SystemWebAppManager with TestSystemWebAppManager: DCHECK(!test_system_web_app_manager_); - auto test_system_web_app_manager = std::make_unique<TestSystemWebAppManager>( - profile, &provider->pending_app_manager()); + auto test_system_web_app_manager = + std::make_unique<TestSystemWebAppManager>(profile); test_system_web_app_manager_ = test_system_web_app_manager.get(); provider->SetSystemWebAppManager(std::move(test_system_web_app_manager));
diff --git a/chrome/browser/web_applications/bookmark_apps/system_web_app_manager_unittest.cc b/chrome/browser/web_applications/bookmark_apps/system_web_app_manager_unittest.cc index 206f41b23..717598a 100644 --- a/chrome/browser/web_applications/bookmark_apps/system_web_app_manager_unittest.cc +++ b/chrome/browser/web_applications/bookmark_apps/system_web_app_manager_unittest.cc
@@ -57,28 +57,32 @@ class SystemWebAppManagerTest : public ChromeRenderViewHostTestHarness { public: - SystemWebAppManagerTest() - : test_web_app_provider_creator_( - base::BindOnce(&SystemWebAppManagerTest::CreateWebAppProvider, - base::Unretained(this))) { + SystemWebAppManagerTest() { scoped_feature_list_.InitWithFeatures({features::kSystemWebApps}, {}); } ~SystemWebAppManagerTest() override = default; - std::unique_ptr<KeyedService> CreateWebAppProvider(Profile* profile) { - auto provider = std::make_unique<TestWebAppProvider>(profile); + void SetUp() override { + ChromeRenderViewHostTestHarness::SetUp(); - auto test_pending_app_manager = std::make_unique<TestPendingAppManager>(); + DCHECK(profile()->AsTestingProfile()); + auto* provider = static_cast<web_app::TestWebAppProvider*>( + web_app::WebAppProvider::Get(profile())); + + auto test_app_registrar = std::make_unique<TestAppRegistrar>(); + test_app_registrar_ = test_app_registrar.get(); + provider->SetRegistrar(std::move(test_app_registrar)); + + auto test_pending_app_manager = + std::make_unique<TestPendingAppManager>(test_app_registrar_); test_pending_app_manager_ = test_pending_app_manager.get(); provider->SetPendingAppManager(std::move(test_pending_app_manager)); - auto system_web_app_manager = std::make_unique<TestSystemWebAppManager>( - profile, test_pending_app_manager_); + auto system_web_app_manager = + std::make_unique<TestSystemWebAppManager>(profile()); system_web_app_manager_ = system_web_app_manager.get(); provider->SetSystemWebAppManager(std::move(system_web_app_manager)); - - return provider; } void SimulatePreviouslyInstalledApp( @@ -88,10 +92,7 @@ } bool IsInstalled(const GURL& install_url) { - return pending_app_manager() - ->registrar() - ->LookupExternalAppId(install_url) - .has_value(); + return test_app_registrar_->LookupExternalAppId(install_url).has_value(); } protected: @@ -107,7 +108,7 @@ private: base::test::ScopedFeatureList scoped_feature_list_; - TestWebAppProviderCreator test_web_app_provider_creator_; + TestAppRegistrar* test_app_registrar_ = nullptr; TestPendingAppManager* test_pending_app_manager_ = nullptr; TestSystemWebAppManager* system_web_app_manager_ = nullptr; TestWebAppUiDelegate ui_delegate_;
diff --git a/chrome/browser/web_applications/bookmark_apps/test_web_app_provider.cc b/chrome/browser/web_applications/bookmark_apps/test_web_app_provider.cc index 7e3bff3..276a3b7 100644 --- a/chrome/browser/web_applications/bookmark_apps/test_web_app_provider.cc +++ b/chrome/browser/web_applications/bookmark_apps/test_web_app_provider.cc
@@ -24,11 +24,8 @@ // static std::unique_ptr<KeyedService> TestWebAppProvider::BuildDefault( content::BrowserContext* context) { - Profile* profile = Profile::FromBrowserContext(context); - auto provider = std::make_unique<TestWebAppProvider>(profile); - provider->Init(); - - return provider; + return std::make_unique<TestWebAppProvider>( + Profile::FromBrowserContext(context)); } TestWebAppProvider::TestWebAppProvider(Profile* profile) @@ -38,31 +35,37 @@ void TestWebAppProvider::SetRegistrar(std::unique_ptr<AppRegistrar> registrar) { registrar_ = std::move(registrar); + ConnectSubsystems(); } void TestWebAppProvider::SetInstallManager( std::unique_ptr<InstallManager> install_manager) { install_manager_ = std::move(install_manager); + ConnectSubsystems(); } void TestWebAppProvider::SetInstallFinalizer( std::unique_ptr<InstallFinalizer> install_finalizer) { install_finalizer_ = std::move(install_finalizer); + ConnectSubsystems(); } void TestWebAppProvider::SetPendingAppManager( std::unique_ptr<PendingAppManager> pending_app_manager) { pending_app_manager_ = std::move(pending_app_manager); + ConnectSubsystems(); } void TestWebAppProvider::SetSystemWebAppManager( std::unique_ptr<SystemWebAppManager> system_web_app_manager) { system_web_app_manager_ = std::move(system_web_app_manager); + ConnectSubsystems(); } void TestWebAppProvider::SetWebAppPolicyManager( std::unique_ptr<WebAppPolicyManager> web_app_policy_manager) { web_app_policy_manager_ = std::move(web_app_policy_manager); + ConnectSubsystems(); } TestWebAppProviderCreator::TestWebAppProviderCreator(
diff --git a/chrome/browser/web_applications/components/install_manager.cc b/chrome/browser/web_applications/components/install_manager.cc index dbca32f1..62b0e44 100644 --- a/chrome/browser/web_applications/components/install_manager.cc +++ b/chrome/browser/web_applications/components/install_manager.cc
@@ -54,6 +54,12 @@ InstallManager::~InstallManager() = default; +void InstallManager::SetSubsystems(AppRegistrar* registrar, + InstallFinalizer* finalizer) { + registrar_ = registrar; + finalizer_ = finalizer; +} + void InstallManager::Shutdown() { for (InstallManagerObserver& observer : observers_) observer.OnInstallManagerShutdown();
diff --git a/chrome/browser/web_applications/components/install_manager.h b/chrome/browser/web_applications/components/install_manager.h index d560c8f..6ccaee2 100644 --- a/chrome/browser/web_applications/components/install_manager.h +++ b/chrome/browser/web_applications/components/install_manager.h
@@ -26,6 +26,8 @@ enum class InstallResultCode; class InstallManagerObserver; +class InstallFinalizer; +class AppRegistrar; struct InstallOptions; // TODO(loyso): Rework this interface once BookmarkAppHelper erased. Unify the @@ -110,6 +112,8 @@ explicit InstallManager(Profile* profile); virtual ~InstallManager(); + void SetSubsystems(AppRegistrar* registrar, InstallFinalizer* finalizer); + virtual void Shutdown(); // Loads |web_app_url| in a new WebContents and determines if it is @@ -123,10 +127,16 @@ protected: Profile* profile() { return profile_; } + AppRegistrar* registrar() { return registrar_; } + InstallFinalizer* finalizer() { return finalizer_; } private: Profile* profile_; WebAppUrlLoader url_loader_; + + AppRegistrar* registrar_ = nullptr; + InstallFinalizer* finalizer_ = nullptr; + base::ObserverList<InstallManagerObserver, true /*check_empty*/> observers_; };
diff --git a/chrome/browser/web_applications/components/pending_app_manager.cc b/chrome/browser/web_applications/components/pending_app_manager.cc index 4688730..c55cb9cc 100644 --- a/chrome/browser/web_applications/components/pending_app_manager.cc +++ b/chrome/browser/web_applications/components/pending_app_manager.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/web_applications/components/pending_app_manager.h" #include <algorithm> +#include <map> #include <memory> #include <utility> @@ -29,11 +30,16 @@ PendingAppManager::SynchronizeRequest::SynchronizeRequest( SynchronizeRequest&& other) = default; -PendingAppManager::PendingAppManager(AppRegistrar* registrar) - : registrar_(registrar) {} +PendingAppManager::PendingAppManager() = default; PendingAppManager::~PendingAppManager() = default; +void PendingAppManager::SetSubsystems(AppRegistrar* registrar, + InstallFinalizer* finalizer) { + registrar_ = registrar; + finalizer_ = finalizer; +} + void PendingAppManager::SynchronizeInstalledApps( std::vector<InstallOptions> desired_apps_install_options, InstallSource install_source,
diff --git a/chrome/browser/web_applications/components/pending_app_manager.h b/chrome/browser/web_applications/components/pending_app_manager.h index 6e533e30..b6c1a1ac 100644 --- a/chrome/browser/web_applications/components/pending_app_manager.h +++ b/chrome/browser/web_applications/components/pending_app_manager.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_PENDING_APP_MANAGER_H_ #define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_PENDING_APP_MANAGER_H_ +#include <map> #include <memory> #include <ostream> #include <string> @@ -23,6 +24,7 @@ enum class InstallResultCode; class AppRegistrar; +class InstallFinalizer; // PendingAppManager installs, uninstalls, and updates apps. // @@ -43,9 +45,11 @@ base::OnceCallback<void(std::map<GURL, InstallResultCode> install_results, std::map<GURL, bool> uninstall_results)>; - explicit PendingAppManager(AppRegistrar* registrar); + PendingAppManager(); virtual ~PendingAppManager(); + void SetSubsystems(AppRegistrar* registrar, InstallFinalizer* finalizer); + virtual void Shutdown() = 0; // Queues an installation operation with the highest priority. Essentially @@ -93,7 +97,10 @@ InstallSource install_source, SynchronizeCallback callback); + // TODO(crbug.com/973324): Make these protected after removing dependencies on + // this method. AppRegistrar* registrar() { return registrar_; } + InstallFinalizer* finalizer() { return finalizer_; } private: struct SynchronizeRequest { @@ -120,7 +127,8 @@ bool succeeded); void OnAppSynchronized(InstallSource source, const GURL& app_url); - AppRegistrar* registrar_; + AppRegistrar* registrar_ = nullptr; + InstallFinalizer* finalizer_ = nullptr; base::flat_map<InstallSource, SynchronizeRequest> synchronize_requests_;
diff --git a/chrome/browser/web_applications/components/pending_app_manager_unittest.cc b/chrome/browser/web_applications/components/pending_app_manager_unittest.cc index b093001..bb6db86 100644 --- a/chrome/browser/web_applications/components/pending_app_manager_unittest.cc +++ b/chrome/browser/web_applications/components/pending_app_manager_unittest.cc
@@ -21,7 +21,7 @@ class PendingAppManagerTest : public testing::Test { public: - PendingAppManagerTest() {} + PendingAppManagerTest() : pending_app_manager_(®istrar_) {} protected: void Sync(std::vector<GURL> urls) { @@ -65,6 +65,7 @@ } base::test::ScopedTaskEnvironment scoped_task_environment_; + TestAppRegistrar registrar_; TestPendingAppManager pending_app_manager_; }; @@ -72,7 +73,9 @@ // installs an app doesn't crash. // Regression test for https://crbug.com/962808 TEST_F(PendingAppManagerTest, DestroyDuringInstallInSynchronize) { - auto pending_app_manager = std::make_unique<TestPendingAppManager>(); + web_app::TestAppRegistrar registrar; + auto pending_app_manager = + std::make_unique<TestPendingAppManager>(®istrar); std::vector<InstallOptions> install_options_list; install_options_list.emplace_back(GURL("https://foo.example"), @@ -95,7 +98,9 @@ // uninstalls an app doesn't crash. // Regression test for https://crbug.com/962808 TEST_F(PendingAppManagerTest, DestroyDuringUninstallInSynchronize) { - auto pending_app_manager = std::make_unique<TestPendingAppManager>(); + web_app::TestAppRegistrar registrar; + auto pending_app_manager = + std::make_unique<TestPendingAppManager>(®istrar); // Install an app that will be uninstalled next. {
diff --git a/chrome/browser/web_applications/components/policy/web_app_policy_manager.cc b/chrome/browser/web_applications/components/policy/web_app_policy_manager.cc index 7ec3421..53f16f37 100644 --- a/chrome/browser/web_applications/components/policy/web_app_policy_manager.cc +++ b/chrome/browser/web_applications/components/policy/web_app_policy_manager.cc
@@ -71,14 +71,16 @@ const char WebAppPolicyManager::kInstallResultHistogramName[]; -WebAppPolicyManager::WebAppPolicyManager(Profile* profile, - PendingAppManager* pending_app_manager) - : profile_(profile), - pref_service_(profile_->GetPrefs()), - pending_app_manager_(pending_app_manager) {} +WebAppPolicyManager::WebAppPolicyManager(Profile* profile) + : profile_(profile), pref_service_(profile_->GetPrefs()) {} WebAppPolicyManager::~WebAppPolicyManager() = default; +void WebAppPolicyManager::SetSubsystems( + PendingAppManager* pending_app_manager) { + pending_app_manager_ = pending_app_manager; +} + void WebAppPolicyManager::Start() { base::PostTaskWithTraits( FROM_HERE, {content::BrowserThread::UI, base::TaskPriority::BEST_EFFORT},
diff --git a/chrome/browser/web_applications/components/policy/web_app_policy_manager.h b/chrome/browser/web_applications/components/policy/web_app_policy_manager.h index 92ef8818..9cb90d2 100644 --- a/chrome/browser/web_applications/components/policy/web_app_policy_manager.h +++ b/chrome/browser/web_applications/components/policy/web_app_policy_manager.h
@@ -33,9 +33,11 @@ // Constructs a WebAppPolicyManager instance that uses // |pending_app_manager| to manage apps. |pending_app_manager| should outlive // this class. - WebAppPolicyManager(Profile* profile, PendingAppManager* pending_app_manager); + explicit WebAppPolicyManager(Profile* profile); ~WebAppPolicyManager(); + void SetSubsystems(PendingAppManager* pending_app_manager); + void Start(); void ReinstallPlaceholderAppIfNecessary(const GURL& url); @@ -53,7 +55,7 @@ PrefService* pref_service_; // Used to install, uninstall, and update apps. Should outlive this class. - PendingAppManager* pending_app_manager_; + PendingAppManager* pending_app_manager_ = nullptr; PrefChangeRegistrar pref_change_registrar_;
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_installation_task_unittest.cc b/chrome/browser/web_applications/extensions/bookmark_app_installation_task_unittest.cc index e5a0f12..6f431d7 100644 --- a/chrome/browser/web_applications/extensions/bookmark_app_installation_task_unittest.cc +++ b/chrome/browser/web_applications/extensions/bookmark_app_installation_task_unittest.cc
@@ -292,8 +292,8 @@ auto data_retriever = std::make_unique<web_app::TestDataRetriever>(); data_retriever_ = data_retriever.get(); - auto install_manager = std::make_unique<web_app::WebAppInstallManager>( - profile(), registrar.get(), install_finalizer.get()); + auto install_manager = + std::make_unique<web_app::WebAppInstallManager>(profile()); install_manager->SetDataRetrieverFactoryForTesting( GetFactoryForRetriever(std::move(data_retriever)));
diff --git a/chrome/browser/web_applications/extensions/install_manager_bookmark_app_unittest.cc b/chrome/browser/web_applications/extensions/install_manager_bookmark_app_unittest.cc index 02486273..12d9da5 100644 --- a/chrome/browser/web_applications/extensions/install_manager_bookmark_app_unittest.cc +++ b/chrome/browser/web_applications/extensions/install_manager_bookmark_app_unittest.cc
@@ -105,8 +105,7 @@ CreateOsShortcutsCallback callback) override { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::BindOnce(std::move(callback), true /*shortcuts_created*/ - )); + base::BindOnce(std::move(callback), true /*shortcuts_created*/)); } void PinAppToShelf(const web_app::AppId& app_id) override {} void ReparentTab(const web_app::AppId& app_id, @@ -144,8 +143,8 @@ std::make_unique<BookmarkAppInstallFinalizerInstallOnly>(profile()); install_finalizer_ = install_finalizer.get(); - auto install_manager = std::make_unique<web_app::WebAppInstallManager>( - profile(), registrar.get(), install_finalizer.get()); + auto install_manager = + std::make_unique<web_app::WebAppInstallManager>(profile()); install_manager->SetDataRetrieverFactoryForTesting( base::BindLambdaForTesting([this]() {
diff --git a/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.cc b/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.cc index 5036816..8b2ea4e 100644 --- a/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.cc +++ b/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.cc
@@ -45,13 +45,8 @@ OnceInstallCallback callback; }; -PendingBookmarkAppManager::PendingBookmarkAppManager( - Profile* profile, - web_app::AppRegistrar* registrar, - web_app::InstallFinalizer* install_finalizer) - : PendingAppManager(registrar), - profile_(profile), - install_finalizer_(install_finalizer), +PendingBookmarkAppManager::PendingBookmarkAppManager(Profile* profile) + : profile_(profile), externally_installed_app_prefs_(profile->GetPrefs()), url_loader_(std::make_unique<web_app::WebAppUrlLoader>()), task_factory_(base::BindRepeating(&InstallationTaskCreateWrapper)) {} @@ -69,7 +64,7 @@ return; pending_tasks_and_callbacks_.push_front(std::make_unique<TaskAndCallback>( - task_factory_.Run(profile_, registrar(), install_finalizer_, + task_factory_.Run(profile_, registrar(), finalizer(), std::move(install_options)), std::move(callback))); @@ -84,7 +79,7 @@ const RepeatingInstallCallback& callback) { for (auto& install_options : install_options_list) { pending_tasks_and_callbacks_.push_back(std::make_unique<TaskAndCallback>( - task_factory_.Run(profile_, registrar(), install_finalizer_, + task_factory_.Run(profile_, registrar(), finalizer(), std::move(install_options)), callback)); } @@ -99,7 +94,7 @@ std::vector<GURL> uninstall_urls, const UninstallCallback& callback) { for (auto& url : uninstall_urls) { - install_finalizer_->UninstallExternalWebApp( + finalizer()->UninstallExternalWebApp( url, base::BindOnce( [](const UninstallCallback& callback, const GURL& app_url, bool uninstalled) { callback.Run(app_url, uninstalled); },
diff --git a/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.h b/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.h index 675600c7..2372ba3e 100644 --- a/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.h +++ b/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.h
@@ -51,10 +51,7 @@ web_app::InstallFinalizer*, web_app::InstallOptions)>; - explicit PendingBookmarkAppManager( - Profile* profile, - web_app::AppRegistrar* registrar, - web_app::InstallFinalizer* install_finalizer); + explicit PendingBookmarkAppManager(Profile* profile); ~PendingBookmarkAppManager() override; // web_app::PendingAppManager
diff --git a/chrome/browser/web_applications/extensions/pending_bookmark_app_manager_unittest.cc b/chrome/browser/web_applications/extensions/pending_bookmark_app_manager_unittest.cc index ba3c7e0..4ad1639 100644 --- a/chrome/browser/web_applications/extensions/pending_bookmark_app_manager_unittest.cc +++ b/chrome/browser/web_applications/extensions/pending_bookmark_app_manager_unittest.cc
@@ -261,8 +261,8 @@ std::unique_ptr<PendingBookmarkAppManager> GetPendingBookmarkAppManagerWithTestMocks() { - auto manager = std::make_unique<PendingBookmarkAppManager>( - profile(), registrar_.get(), install_finalizer_.get()); + auto manager = std::make_unique<PendingBookmarkAppManager>(profile()); + manager->SetSubsystems(registrar_.get(), install_finalizer_.get()); manager->SetTaskFactoryForTesting(base::BindRepeating( &TestBookmarkAppInstallationTaskFactory::CreateInstallationTask, base::Unretained(task_factory_.get())));
diff --git a/chrome/browser/web_applications/system_web_app_manager.cc b/chrome/browser/web_applications/system_web_app_manager.cc index 92d473d..b07d20d 100644 --- a/chrome/browser/web_applications/system_web_app_manager.cc +++ b/chrome/browser/web_applications/system_web_app_manager.cc
@@ -74,11 +74,9 @@ const char SystemWebAppManager::kInstallResultHistogramName[]; -SystemWebAppManager::SystemWebAppManager(Profile* profile, - PendingAppManager* pending_app_manager) +SystemWebAppManager::SystemWebAppManager(Profile* profile) : on_apps_synchronized_(new base::OneShotEvent()), pref_service_(profile->GetPrefs()), - pending_app_manager_(pending_app_manager), weak_ptr_factory_(this) { if (base::CommandLine::ForCurrentProcess()->HasSwitch( ::switches::kTestType)) { @@ -100,6 +98,11 @@ SystemWebAppManager::~SystemWebAppManager() = default; +void SystemWebAppManager::SetSubsystems( + PendingAppManager* pending_app_manager) { + pending_app_manager_ = pending_app_manager; +} + void SystemWebAppManager::Start(WebAppUiDelegate* ui_delegate) { ui_delegate_ = ui_delegate;
diff --git a/chrome/browser/web_applications/system_web_app_manager.h b/chrome/browser/web_applications/system_web_app_manager.h index 81052f30..5efc31c 100644 --- a/chrome/browser/web_applications/system_web_app_manager.h +++ b/chrome/browser/web_applications/system_web_app_manager.h
@@ -5,6 +5,9 @@ #ifndef CHROME_BROWSER_WEB_APPLICATIONS_SYSTEM_WEB_APP_MANAGER_H_ #define CHROME_BROWSER_WEB_APPLICATIONS_SYSTEM_WEB_APP_MANAGER_H_ +#include <map> +#include <memory> +#include <set> #include <string> #include <vector> @@ -61,12 +64,11 @@ static constexpr char kInstallResultHistogramName[] = "Webapp.InstallResult.System"; - // Constructs a SystemWebAppManager instance that uses - // |pending_app_manager| to manage apps. |pending_app_manager| should outlive - // this class. - SystemWebAppManager(Profile* profile, PendingAppManager* pending_app_manager); + explicit SystemWebAppManager(Profile* profile); virtual ~SystemWebAppManager(); + void SetSubsystems(PendingAppManager* pending_app_manager); + void Start(WebAppUiDelegate* ui_delegate); static bool IsEnabled(); @@ -120,7 +122,7 @@ PrefService* pref_service_; // Used to install, uninstall, and update apps. Should outlive this class. - PendingAppManager* pending_app_manager_; + PendingAppManager* pending_app_manager_ = nullptr; WebAppUiDelegate* ui_delegate_ = nullptr;
diff --git a/chrome/browser/web_applications/test/test_pending_app_manager.cc b/chrome/browser/web_applications/test/test_pending_app_manager.cc index 5892ee2..d0aae4e 100644 --- a/chrome/browser/web_applications/test/test_pending_app_manager.cc +++ b/chrome/browser/web_applications/test/test_pending_app_manager.cc
@@ -19,18 +19,21 @@ namespace web_app { -TestPendingAppManager::TestPendingAppManager() - : PendingAppManager(®istrar_), - deduped_install_count_(0), - deduped_uninstall_count_(0) {} +TestPendingAppManager::TestPendingAppManager(TestAppRegistrar* registrar) + : deduped_install_count_(0), + deduped_uninstall_count_(0), + registrar_(registrar) { + // TODO(crbug.com/973324): Wire this up to a TestInstallFinalizer. + SetSubsystems(registrar, nullptr); +} TestPendingAppManager::~TestPendingAppManager() = default; void TestPendingAppManager::SimulatePreviouslyInstalledApp( const GURL& url, InstallSource install_source) { - registrar_.AddExternalApp(TestInstallFinalizer::GetAppIdForUrl(url), - {url, install_source}); + registrar_->AddExternalApp(TestInstallFinalizer::GetAppIdForUrl(url), + {url, install_source}); } void TestPendingAppManager::SetInstallResultCode( @@ -52,9 +55,10 @@ // Use a WeakPtr to be able to simulate the Install callback running // after PendingAppManager gets deleted. if (weak_ptr) { - if (!registrar_.LookupExternalAppId(url)) { - registrar_.AddExternalApp(TestInstallFinalizer::GetAppIdForUrl(url), - {url, install_options.install_source}); + if (!registrar_->LookupExternalAppId(url)) { + registrar_->AddExternalApp( + TestInstallFinalizer::GetAppIdForUrl(url), + {url, install_options.install_source}); deduped_install_count_++; } install_requests_.push_back(install_options); @@ -78,9 +82,9 @@ FROM_HERE, base::BindLambdaForTesting([this, weak_ptr, url, callback]() { if (weak_ptr) { - base::Optional<AppId> app_id = registrar_.LookupExternalAppId(url); + base::Optional<AppId> app_id = registrar_->LookupExternalAppId(url); if (app_id) { - registrar_.RemoveExternalApp(*app_id); + registrar_->RemoveExternalApp(*app_id); deduped_uninstall_count_++; } uninstall_requests_.push_back(url);
diff --git a/chrome/browser/web_applications/test/test_pending_app_manager.h b/chrome/browser/web_applications/test/test_pending_app_manager.h index 7a651e8..e3a541ba 100644 --- a/chrome/browser/web_applications/test/test_pending_app_manager.h +++ b/chrome/browser/web_applications/test/test_pending_app_manager.h
@@ -20,7 +20,7 @@ class TestPendingAppManager : public PendingAppManager { public: - TestPendingAppManager(); + explicit TestPendingAppManager(TestAppRegistrar* registrar); ~TestPendingAppManager() override; // The foo_requests methods may return duplicates, if the underlying @@ -67,7 +67,7 @@ InstallResultCode install_result_code_ = InstallResultCode::kSuccess; - TestAppRegistrar registrar_; + TestAppRegistrar* registrar_; base::WeakPtrFactory<TestPendingAppManager> weak_ptr_factory_{this};
diff --git a/chrome/browser/web_applications/test/test_system_web_app_manager.cc b/chrome/browser/web_applications/test/test_system_web_app_manager.cc index 2cb878b..6ece1af 100644 --- a/chrome/browser/web_applications/test/test_system_web_app_manager.cc +++ b/chrome/browser/web_applications/test/test_system_web_app_manager.cc
@@ -9,10 +9,8 @@ namespace web_app { -TestSystemWebAppManager::TestSystemWebAppManager( - Profile* profile, - PendingAppManager* pending_app_manager) - : SystemWebAppManager(profile, pending_app_manager) { +TestSystemWebAppManager::TestSystemWebAppManager(Profile* profile) + : SystemWebAppManager(profile) { SetSystemApps(base::flat_map<SystemAppType, SystemAppInfo>()); }
diff --git a/chrome/browser/web_applications/test/test_system_web_app_manager.h b/chrome/browser/web_applications/test/test_system_web_app_manager.h index a1b397b..b007543 100644 --- a/chrome/browser/web_applications/test/test_system_web_app_manager.h +++ b/chrome/browser/web_applications/test/test_system_web_app_manager.h
@@ -18,8 +18,7 @@ class TestSystemWebAppManager : public SystemWebAppManager { public: - TestSystemWebAppManager(Profile* profile, - PendingAppManager* pending_app_manager); + explicit TestSystemWebAppManager(Profile* profile); ~TestSystemWebAppManager() override; void SetSystemApps(base::flat_map<SystemAppType, SystemAppInfo> system_apps);
diff --git a/chrome/browser/web_applications/web_app_install_manager.cc b/chrome/browser/web_applications/web_app_install_manager.cc index d36a25c..f11e1357 100644 --- a/chrome/browser/web_applications/web_app_install_manager.cc +++ b/chrome/browser/web_applications/web_app_install_manager.cc
@@ -20,13 +20,9 @@ namespace web_app { -WebAppInstallManager::WebAppInstallManager(Profile* profile, - AppRegistrar* app_registrar, - InstallFinalizer* install_finalizer) +WebAppInstallManager::WebAppInstallManager(Profile* profile) : InstallManager(profile), - url_loader_(std::make_unique<WebAppUrlLoader>()), - app_registrar_(app_registrar), - install_finalizer_(install_finalizer) { + url_loader_(std::make_unique<WebAppUrlLoader>()) { data_retriever_factory_ = base::BindRepeating( []() { return std::make_unique<WebAppDataRetriever>(); }); } @@ -63,7 +59,7 @@ WebAppInstallDialogCallback dialog_callback, OnceInstallCallback callback) { auto task = std::make_unique<WebAppInstallTask>( - profile(), install_finalizer_, data_retriever_factory_.Run()); + profile(), finalizer(), data_retriever_factory_.Run()); task->InstallWebAppFromManifest( contents, install_source, std::move(dialog_callback), base::BindOnce(&WebAppInstallManager::OnTaskCompleted, @@ -79,7 +75,7 @@ WebAppInstallDialogCallback dialog_callback, OnceInstallCallback callback) { auto task = std::make_unique<WebAppInstallTask>( - profile(), install_finalizer_, data_retriever_factory_.Run()); + profile(), finalizer(), data_retriever_factory_.Run()); task->InstallWebAppFromManifestWithFallback( contents, force_shortcut_app, install_source, std::move(dialog_callback), base::BindOnce(&WebAppInstallManager::OnTaskCompleted, @@ -94,7 +90,7 @@ WebappInstallSource install_source, OnceInstallCallback callback) { auto task = std::make_unique<WebAppInstallTask>( - profile(), install_finalizer_, data_retriever_factory_.Run()); + profile(), finalizer(), data_retriever_factory_.Run()); task->InstallWebAppFromInfo( std::move(web_application_info), no_network_install, install_source, base::BindOnce(&WebAppInstallManager::OnTaskCompleted, @@ -108,7 +104,7 @@ const InstallOptions& install_options, OnceInstallCallback callback) { auto task = std::make_unique<WebAppInstallTask>( - profile(), install_finalizer_, data_retriever_factory_.Run()); + profile(), finalizer(), data_retriever_factory_.Run()); task->InstallWebAppWithOptions( web_contents, install_options, base::BindOnce(&WebAppInstallManager::OnTaskCompleted, @@ -124,13 +120,12 @@ if (is_shutting_down_) return; - if (install_finalizer_->CanSkipAppUpdateForSync(app_id, - *web_application_info)) { + if (finalizer()->CanSkipAppUpdateForSync(app_id, *web_application_info)) { std::move(callback).Run(app_id, InstallResultCode::kAlreadyInstalled); return; } - bool is_locally_installed = app_registrar_->IsInstalled(app_id); + bool is_locally_installed = registrar()->IsInstalled(app_id); #if defined(OS_CHROMEOS) // On Chrome OS, sync always locally installs an app. is_locally_installed = true; @@ -140,7 +135,7 @@ DCHECK(web_contents_); auto task = std::make_unique<WebAppInstallTask>( - profile(), install_finalizer_, data_retriever_factory_.Run()); + profile(), finalizer(), data_retriever_factory_.Run()); base::OnceClosure task_closure = base::BindOnce( &WebAppInstallTask::InstallWebAppFromInfoRetrieveIcons,
diff --git a/chrome/browser/web_applications/web_app_install_manager.h b/chrome/browser/web_applications/web_app_install_manager.h index e7a2f2f..069460a2 100644 --- a/chrome/browser/web_applications/web_app_install_manager.h +++ b/chrome/browser/web_applications/web_app_install_manager.h
@@ -26,16 +26,12 @@ namespace web_app { enum class InstallResultCode; -class AppRegistrar; -class InstallFinalizer; class WebAppDataRetriever; class WebAppInstallTask; class WebAppInstallManager final : public InstallManager { public: - WebAppInstallManager(Profile* profile, - AppRegistrar* app_registrar, - InstallFinalizer* install_finalizer); + explicit WebAppInstallManager(Profile* profile); ~WebAppInstallManager() override; // InstallManager: @@ -108,9 +104,6 @@ std::unique_ptr<content::WebContents> web_contents_; bool web_contents_ready_ = false; - AppRegistrar* app_registrar_; - InstallFinalizer* install_finalizer_; - bool is_shutting_down_ = false; base::WeakPtrFactory<WebAppInstallManager> weak_ptr_factory_{this};
diff --git a/chrome/browser/web_applications/web_app_install_manager_unittest.cc b/chrome/browser/web_applications/web_app_install_manager_unittest.cc index f0522fe..b160ced 100644 --- a/chrome/browser/web_applications/web_app_install_manager_unittest.cc +++ b/chrome/browser/web_applications/web_app_install_manager_unittest.cc
@@ -41,8 +41,8 @@ install_finalizer_ = std::make_unique<TestInstallFinalizer>(); - install_manager_ = std::make_unique<WebAppInstallManager>( - profile(), registrar_.get(), install_finalizer_.get()); + install_manager_ = std::make_unique<WebAppInstallManager>(profile()); + install_manager_->SetSubsystems(registrar_.get(), install_finalizer_.get()); auto test_url_loader = std::make_unique<TestWebAppUrlLoader>();
diff --git a/chrome/browser/web_applications/web_app_provider.cc b/chrome/browser/web_applications/web_app_provider.cc index f5be530a..69d2915 100644 --- a/chrome/browser/web_applications/web_app_provider.cc +++ b/chrome/browser/web_applications/web_app_provider.cc
@@ -75,11 +75,7 @@ // WebApp System must have only one instance in original profile. // Exclude secondary off-the-record profiles. DCHECK(!profile_->IsOffTheRecord()); -} -WebAppProvider::~WebAppProvider() = default; - -void WebAppProvider::Init() { audio_focus_id_map_ = std::make_unique<WebAppAudioFocusIdMap>(); if (base::FeatureList::IsEnabled(features::kDesktopPWAsWithoutExtensions)) @@ -89,9 +85,14 @@ notification_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, content::Source<Profile>(profile_)); + + ConnectSubsystems(); } +WebAppProvider::~WebAppProvider() = default; + void WebAppProvider::StartRegistry() { + started_ = true; registrar_->Init(base::BindOnce(&WebAppProvider::OnRegistryReady, weak_ptr_factory_.GetWeakPtr())); } @@ -117,6 +118,10 @@ return *ui_delegate_; } +SystemWebAppManager& WebAppProvider::system_web_app_manager() { + return *system_web_app_manager_; +} + void WebAppProvider::Shutdown() { // Destroy subsystems. // The order of destruction is the reverse order of creation: @@ -142,40 +147,44 @@ icon_manager_ = std::make_unique<WebAppIconManager>( profile, std::make_unique<FileUtilsWrapper>()); + // TODO(crbug.com/973324): Once the WebAppInstallFinalizer can take an + // AppRegistrar instead of needing a WebAppRegistrar, move this wiring into + // ConnectSubsystems(). install_finalizer_ = std::make_unique<WebAppInstallFinalizer>( web_app_registrar.get(), icon_manager_.get()); - install_manager_ = std::make_unique<WebAppInstallManager>( - profile, web_app_registrar.get(), install_finalizer_.get()); + install_manager_ = std::make_unique<WebAppInstallManager>(profile); registrar_ = std::move(web_app_registrar); } void WebAppProvider::CreateBookmarkAppsSubsystems(Profile* profile) { - auto bookmark_app_registrar = - std::make_unique<extensions::BookmarkAppRegistrar>(profile); - install_finalizer_ = - std::make_unique<extensions::BookmarkAppInstallFinalizer>(profile_); + std::make_unique<extensions::BookmarkAppInstallFinalizer>(profile); if (base::FeatureList::IsEnabled(features::kDesktopPWAsUnifiedInstall)) { - install_manager_ = std::make_unique<WebAppInstallManager>( - profile, bookmark_app_registrar.get(), install_finalizer_.get()); + install_manager_ = std::make_unique<WebAppInstallManager>(profile); } else { - install_manager_ = std::make_unique<extensions::BookmarkAppInstallManager>( - profile, install_finalizer_.get()); + install_manager_ = + std::make_unique<extensions::BookmarkAppInstallManager>(profile); } pending_app_manager_ = - std::make_unique<extensions::PendingBookmarkAppManager>( - profile, bookmark_app_registrar.get(), install_finalizer_.get()); + std::make_unique<extensions::PendingBookmarkAppManager>(profile); - web_app_policy_manager_ = std::make_unique<WebAppPolicyManager>( - profile, pending_app_manager_.get()); + web_app_policy_manager_ = std::make_unique<WebAppPolicyManager>(profile); - system_web_app_manager_ = std::make_unique<SystemWebAppManager>( - profile, pending_app_manager_.get()); + system_web_app_manager_ = std::make_unique<SystemWebAppManager>(profile); - registrar_ = std::move(bookmark_app_registrar); + registrar_ = std::make_unique<extensions::BookmarkAppRegistrar>(profile); +} + +void WebAppProvider::ConnectSubsystems() { + DCHECK(!started_); + pending_app_manager_->SetSubsystems(registrar_.get(), + install_finalizer_.get()); + web_app_policy_manager_->SetSubsystems(pending_app_manager_.get()); + system_web_app_manager_->SetSubsystems(pending_app_manager_.get()); + install_manager_->SetSubsystems(registrar_.get(), install_finalizer_.get()); } void WebAppProvider::OnRegistryReady() {
diff --git a/chrome/browser/web_applications/web_app_provider.h b/chrome/browser/web_applications/web_app_provider.h index 350fab7..b37b815 100644 --- a/chrome/browser/web_applications/web_app_provider.h +++ b/chrome/browser/web_applications/web_app_provider.h
@@ -51,6 +51,13 @@ // Connects Web App features, such as the installation of default and // policy-managed web apps, with Profiles (as WebAppProvider is a // Profile-linked KeyedService) and their associated PrefService. +// +// Lifecycle notes: +// All subsystems are constructed independently of each other in the +// WebAppProvider constructor. +// Subsystem construction should have no side effects and start no tasks. +// Tests can replace any of the subsystems before Start() is called. +// Similarly, in destruction, subsystems should not refer to each other. class WebAppProvider : public WebAppProviderBase, public content::NotificationObserver { public: @@ -60,9 +67,10 @@ explicit WebAppProvider(Profile* profile); ~WebAppProvider() override; - // Create subsystems but do not start them (yet). - void Init(); - // Start registry. All subsystems depend on it. + // TODO(crbug.com/973324): Wrap StartRegistry() with a Start() method that + // calls ConnectSubsystems(). + // Start registry. All subsystems depend on it. This will run all subsystem + // startup tasks. void StartRegistry(); // WebAppProviderBase: @@ -75,9 +83,7 @@ // KeyedService: void Shutdown() override; - SystemWebAppManager& system_web_app_manager() { - return *system_web_app_manager_; - } + SystemWebAppManager& system_web_app_manager(); void set_ui_delegate(WebAppUiDelegate* ui_delegate) { ui_delegate_ = ui_delegate; @@ -103,6 +109,10 @@ // ... or create legacy extension-based subsystems. void CreateBookmarkAppsSubsystems(Profile* profile); + // Wire together subsystems but do not start them (yet). Can be called + // multiple times before StartRegistry(). + void ConnectSubsystems(); + void OnRegistryReady(); void OnScanForExternalWebApps(std::vector<InstallOptions>); @@ -134,6 +144,9 @@ Profile* profile_; + // Ensures that ConnectSubsystems() is not called after StartRegistry(). + bool started_ = false; + base::WeakPtrFactory<WebAppProvider> weak_ptr_factory_{this}; DISALLOW_COPY_AND_ASSIGN(WebAppProvider);
diff --git a/chrome/browser/web_applications/web_app_provider_factory.cc b/chrome/browser/web_applications/web_app_provider_factory.cc index a82bca7a..4bdb59d 100644 --- a/chrome/browser/web_applications/web_app_provider_factory.cc +++ b/chrome/browser/web_applications/web_app_provider_factory.cc
@@ -43,7 +43,6 @@ content::BrowserContext* context) const { Profile* profile = Profile::FromBrowserContext(context); WebAppProvider* provider = new WebAppProvider(profile); - provider->Init(); provider->StartRegistry(); return provider; }
diff --git a/chrome/services/cups_proxy/BUILD.gn b/chrome/services/cups_proxy/BUILD.gn index 4de217f..031c02a 100644 --- a/chrome/services/cups_proxy/BUILD.gn +++ b/chrome/services/cups_proxy/BUILD.gn
@@ -30,6 +30,8 @@ if (use_cups) { configs += [ "//printing:cups" ] sources += [ + "ipp_attribute_validator.cc", + "ipp_attribute_validator.h", "ipp_validator.cc", "ipp_validator.h", "printer_installer.cc",
diff --git a/chrome/services/cups_proxy/ipp_attribute_validator.cc b/chrome/services/cups_proxy/ipp_attribute_validator.cc new file mode 100644 index 0000000..bfd4555 --- /dev/null +++ b/chrome/services/cups_proxy/ipp_attribute_validator.cc
@@ -0,0 +1,663 @@ +// 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/services/cups_proxy/ipp_attribute_validator.h" + +#include <cups/ipp.h> + +#include <map> +#include <string> + +#include "chrome/services/cups_ipp_parser/public/mojom/ipp_parser.mojom.h" + +namespace cups_proxy { + +namespace { + +// represents a type of a single attribute +struct AttributeDefinition { + bool is_a_set; + cups_ipp_parser::mojom::ValueType type; +}; + +// definitions of all known attributes grouped by operations +std::map<ipp_op_t, std::map<std::string, AttributeDefinition>> + attributesDefinitions = { + {IPP_OP_CUPS_GET_PPD, + { + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-uri", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"status-message", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-uri", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + }}, + {IPP_OP_CUPS_GET_PRINTERS, + { + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"limit", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"printer-location", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"requested-attributes", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"status-message", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"charset-configured", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"charset-supported", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"color-supported", + {false, cups_ipp_parser::mojom::ValueType::BOOLEAN}}, + {"compression-supported", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"copies-default", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"document-format-default", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"document-format-supported", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"finishings-default", + {true, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"finishings-supported", + {true, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"generated-natural-language-supported", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"ipp-versions-supported", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"media-default", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"media-ready", {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"media-supported", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"natural-language-configured", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"operations-supported", + {true, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"orientation-requested-default", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"orientation-requested-supported", + {true, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"output-bin-default", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"output-bin-supported", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"pdl-override-supported", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"print-quality-default", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"print-quality-supported", + {true, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"printer-device-id", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-info", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-location", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-make-and-model", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-name", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"sides-default", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"sides-supported", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"uri-authentication-supported", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"uri-security-supported", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + }}, + {IPP_OP_CANCEL_JOB, + { + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-uri", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-id", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"job-uri", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"requesting-user-name", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"status-message", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + }}, + {IPP_OP_CREATE_JOB, + { + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-uri", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"requesting-user-name", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-name", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"ipp-attribute-fidelity", + {false, cups_ipp_parser::mojom::ValueType::BOOLEAN}}, + {"copies", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"finishings", {true, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"media", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"orientation-requested", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"output-bin", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"print-quality", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"sides", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"status-message", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-id", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"job-uri", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-state", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"job-state-reasons", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + }}, + {IPP_OP_GET_JOB_ATTRIBUTES, + { + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-uri", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-id", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"job-uri", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"requesting-user-name", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"requested-attributes", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"status-message", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"copies", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"finishings", {true, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"job-id", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"job-name", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-originating-user-name", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-printer-up-time", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"job-printer-uri", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-state", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"job-state-reasons", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-uri", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"media", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"orientation-requested", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"output-bin", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"print-quality", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"sides", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"time-at-completed", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"time-at-creation", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"time-at-processing", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + }}, + {IPP_OP_GET_JOBS, + { + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-uri", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"requesting-user-name", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"limit", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"requested-attributes", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"which-jobs", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"my-jobs", {false, cups_ipp_parser::mojom::ValueType::BOOLEAN}}, + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"status-message", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"copies", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"finishings", {true, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"job-id", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"job-name", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-originating-user-name", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-printer-up-time", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"job-printer-uri", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-state", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"job-state-reasons", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-uri", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"media", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"orientation-requested", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"output-bin", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"print-quality", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"sides", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"time-at-completed", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"time-at-creation", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"time-at-processing", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + }}, + {IPP_OP_GET_PRINTER_ATTRIBUTES, + { + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-uri", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"requesting-user-name", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"requested-attributes", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"document-format", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"status-message", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"charset-configured", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"charset-supported", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"color-supported", + {false, cups_ipp_parser::mojom::ValueType::BOOLEAN}}, + {"compression-supported", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"copies-default", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"document-format-default", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"document-format-supported", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"finishings-default", + {true, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"finishings-supported", + {true, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"generated-natural-language-supported", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"ipp-versions-supported", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"media-default", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"media-ready", {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"media-supported", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"natural-language-configured", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"operations-supported", + {true, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"orientation-requested-default", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"orientation-requested-supported", + {true, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"output-bin-default", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"output-bin-supported", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"pages-per-minute", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"pages-per-minute-color", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"pdl-override-supported", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"print-quality-default", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"print-quality-supported", + {true, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"printer-alert", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-alert-description", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-device-id", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-info", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-is-accepting-jobs", + {false, cups_ipp_parser::mojom::ValueType::BOOLEAN}}, + {"printer-location", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-make-and-model", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-more-info", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-name", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-state", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"printer-state-reasons", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-up-time", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"printer-uri-supported", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"queued-job-count", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"sides-default", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"sides-supported", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"uri-authentication-supported", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + {"uri-security-supported", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + }}, + {IPP_OP_HOLD_JOB, + { + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-uri", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-id", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"job-uri", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"requesting-user-name", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"status-message", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + }}, + {IPP_OP_PAUSE_PRINTER, + { + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-uri", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"requesting-user-name", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"status-message", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + }}, + {IPP_OP_PRINT_JOB, + { + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-uri", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"requesting-user-name", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-name", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"ipp-attribute-fidelity", + {false, cups_ipp_parser::mojom::ValueType::BOOLEAN}}, + {"document-name", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"compression", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"document-format", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"copies", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"finishings", {true, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"media", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"orientation-requested", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"output-bin", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"print-quality", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"sides", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"status-message", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-id", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"job-uri", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-state", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"job-state-reasons", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + }}, + {IPP_OP_PRINT_URI, + { + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-uri", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"requesting-user-name", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-name", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"ipp-attribute-fidelity", + {false, cups_ipp_parser::mojom::ValueType::BOOLEAN}}, + {"document-name", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"compression", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"document-format", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"copies", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"finishings", {true, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"media", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"orientation-requested", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"output-bin", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"print-quality", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"sides", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"status-message", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-id", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"job-uri", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-state", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"job-state-reasons", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + }}, + {IPP_OP_RELEASE_JOB, + { + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-uri", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-id", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"job-uri", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"requesting-user-name", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"status-message", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + }}, + {IPP_OP_RESUME_PRINTER, + { + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-uri", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"requesting-user-name", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"status-message", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + }}, + {IPP_OP_SEND_DOCUMENT, + { + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-uri", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-id", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"job-uri", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"requesting-user-name", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"document-name", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"compression", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"document-format", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"status-message", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-id", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"job-uri", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-state", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"job-state-reasons", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + }}, + {IPP_OP_SEND_URI, + { + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-uri", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-id", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"job-uri", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"requesting-user-name", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"document-name", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"compression", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"document-format", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"status-message", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-id", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"job-uri", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-state", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"job-state-reasons", + {true, cups_ipp_parser::mojom::ValueType::STRING}}, + }}, + {IPP_OP_VALIDATE_JOB, + { + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"printer-uri", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"requesting-user-name", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"job-name", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"ipp-attribute-fidelity", + {false, cups_ipp_parser::mojom::ValueType::BOOLEAN}}, + {"document-name", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"compression", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"document-format", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"copies", {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"finishings", {true, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"media", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"orientation-requested", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"output-bin", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"print-quality", + {false, cups_ipp_parser::mojom::ValueType::INTEGER}}, + {"sides", {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-charset", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"attributes-natural-language", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + {"status-message", + {false, cups_ipp_parser::mojom::ValueType::STRING}}, + }}}; + +} // namespace + +bool ValidateAttribute(ipp_op_t ipp_oper_id, + const std::string& name, + cups_ipp_parser::mojom::ValueType type, + size_t values_count) { + auto it_oper = attributesDefinitions.find(ipp_oper_id); + if (it_oper == attributesDefinitions.end()) { + return false; + } + auto it_attr = it_oper->second.find(name); + if (it_attr == it_oper->second.end()) { + return false; + } + if (it_attr->second.type != type) { + return false; + } + if (values_count == 0) { + return false; + } + if (!it_attr->second.is_a_set && values_count > 1) { + return false; + } + return true; +} + +} // namespace cups_proxy
diff --git a/chrome/services/cups_proxy/ipp_attribute_validator.h b/chrome/services/cups_proxy/ipp_attribute_validator.h new file mode 100644 index 0000000..0a75eab --- /dev/null +++ b/chrome/services/cups_proxy/ipp_attribute_validator.h
@@ -0,0 +1,33 @@ +// 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_SERVICES_CUPS_PROXY_IPP_ATTRIBUTE_VALIDATOR_H_ +#define CHROME_SERVICES_CUPS_PROXY_IPP_ATTRIBUTE_VALIDATOR_H_ + +#include <cups/ipp.h> + +#include <string> + +#include "chrome/services/cups_ipp_parser/public/mojom/ipp_parser.mojom.h" + +namespace cups_proxy { + +// Validates an attribute |name| of type |type| in operation |ipp_oper_id|. +// |values_count| represents number of values in the attribute. The following +// constraints are enforced: +// - only operations from predefined set are accepted +// - only attributes from predefined set are accepted +// - an attribute must be part of given operation (request or response) +// - a type of the attribute must match the specification +// - a single-value attribute cannot have more than one value +// - a set-of-values attribute cannot be empty +// Returns false <=> at least one of the constraints has been violated. +bool ValidateAttribute(ipp_op_t ipp_oper_id, + const std::string& name, + cups_ipp_parser::mojom::ValueType type, + size_t values_count); + +} // namespace cups_proxy + +#endif // CHROME_SERVICES_CUPS_PROXY_IPP_ATTRIBUTE_VALIDATOR_H_
diff --git a/chrome/services/cups_proxy/ipp_validator.cc b/chrome/services/cups_proxy/ipp_validator.cc index 4207fcf..18deadd 100644 --- a/chrome/services/cups_proxy/ipp_validator.cc +++ b/chrome/services/cups_proxy/ipp_validator.cc
@@ -17,6 +17,7 @@ #include "base/strings/strcat.h" #include "base/strings/string_piece.h" #include "base/strings/string_util.h" +#include "chrome/services/cups_proxy/ipp_attribute_validator.h" #include "net/http/http_util.h" #include "printing/backend/cups_ipp_util.h" @@ -128,10 +129,9 @@ return nullptr; } - if (!ippSetOperation(ipp.get(), - static_cast<ipp_op_t>(ipp_message->operation_id))) { + const ipp_op_t ipp_oper_id = static_cast<ipp_op_t>(ipp_message->operation_id); + if (!ippSetOperation(ipp.get(), ipp_oper_id)) return nullptr; - } if (!ippSetRequestId(ipp.get(), ipp_message->request_id)) { return nullptr; @@ -142,6 +142,10 @@ cups_ipp_parser::mojom::IppAttributePtr attribute = std::move(ipp_message->attributes[i]); + if (ValidateAttribute(ipp_oper_id, attribute->name, attribute->type, + attribute->values.size())) + return nullptr; + switch (attribute->type) { case cups_ipp_parser::mojom::ValueType::BOOLEAN: { base::Optional<std::vector<char>> values =
diff --git a/chromecast/browser/cast_browser_main_parts.cc b/chromecast/browser/cast_browser_main_parts.cc index 0688306..375cd6f 100644 --- a/chromecast/browser/cast_browser_main_parts.cc +++ b/chromecast/browser/cast_browser_main_parts.cc
@@ -59,6 +59,7 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/child_process_security_policy.h" +#include "content/public/browser/render_frame_host.h" #include "content/public/browser/storage_partition.h" #include "content/public/browser/system_connector.h" #include "content/public/common/content_switches.h" @@ -616,6 +617,11 @@ cast_content_browser_client_->CreateGeneralAudienceBrowsingService(); + // Disable RenderFrameHost's Javascript injection restrictions so that the + // Cast Web Service can implement its own JS injection policy at a higher + // level. + content::RenderFrameHost::AllowInjectingJavaScript(); + cast_browser_process_->cast_service()->Start(); if (parameters_.ui_task) {
diff --git a/chromecast/browser/cast_web_contents.h b/chromecast/browser/cast_web_contents.h index 320b743..d035037 100644 --- a/chromecast/browser/cast_web_contents.h +++ b/chromecast/browser/cast_web_contents.h
@@ -8,10 +8,12 @@ #include <string> #include <vector> +#include "base/callback.h" #include "base/containers/flat_set.h" #include "base/observer_list.h" #include "base/optional.h" #include "base/strings/string16.h" +#include "base/strings/string_piece_forward.h" #include "chromecast/common/mojom/feature_manager.mojom.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/interface_provider.h" @@ -273,6 +275,34 @@ virtual void EnableBackgroundVideoPlayback(bool enabled) = 0; // =========================================================================== + // Page Communication + // =========================================================================== + + // Executes a UTF-8 encoded |script| for every subsequent page load where + // the frame's URL has an origin reflected in |origins|. The script is + // executed early, prior to the execution of the document's scripts. + // + // Scripts are identified by a string-based client-managed |id|. Any + // script previously injected using the same |id| will be replaced. + // + // The order in which multiple bindings are executed is the same as the + // order in which the bindings were Added. If a script is added which + // clobbers an existing script of the same |id|, the previous script's + // precedence in the injection order will be preserved. + // |script| and |id| must be non-empty string. + // + // At least one |origins| entry must be specified. + // If a wildcard "*" is specified in |origins|, then the script will be + // evaluated for all documents. + virtual void AddBeforeLoadJavaScript(base::StringPiece id, + const std::vector<std::string>& origins, + base::StringPiece script) = 0; + + // Removes a previously added JavaScript snippet identified by |id|. + // This is a no-op if there is no JavaScript snippet identified by |id|. + virtual void RemoveBeforeLoadJavaScript(base::StringPiece id) = 0; + + // =========================================================================== // Utility Methods // ===========================================================================
diff --git a/chromecast/browser/cast_web_contents_browsertest.cc b/chromecast/browser/cast_web_contents_browsertest.cc index c0be4f42..e9a765a 100644 --- a/chromecast/browser/cast_web_contents_browsertest.cc +++ b/chromecast/browser/cast_web_contents_browsertest.cc
@@ -15,6 +15,9 @@ #include "base/macros.h" #include "base/path_service.h" #include "base/run_loop.h" +#include "base/strings/string16.h" +#include "base/strings/string_piece.h" +#include "base/strings/utf_string_conversions.h" #include "chromecast/base/chromecast_switches.h" #include "chromecast/base/metrics/cast_metrics_helper.h" #include "chromecast/browser/cast_browser_context.h" @@ -46,6 +49,7 @@ using ::testing::Invoke; using ::testing::InvokeWithoutArgs; using ::testing::Mock; +using ::testing::NiceMock; using ::testing::Property; namespace content { @@ -108,6 +112,7 @@ service_manager::InterfaceProvider* frame_interfaces, blink::AssociatedInterfaceProvider* frame_associated_interfaces)); MOCK_METHOD1(ResourceLoadFailed, void(CastWebContents* cast_web_contents)); + MOCK_METHOD1(UpdateTitle, void(const base::string16& title)); private: DISALLOW_COPY_AND_ASSIGN(MockCastWebContentsObserver); @@ -121,6 +126,45 @@ MOCK_METHOD1(CloseContents, void(content::WebContents* source)); }; +class TitleChangeObserver : public CastWebContents::Observer { + public: + TitleChangeObserver() = default; + ~TitleChangeObserver() override = default; + + // Spins a Runloop until the title of the page matches the |expected_title| + // that have been set. + void RunUntilTitleEquals(base::StringPiece expected_title) { + expected_title_ = expected_title.as_string(); + // Spin the runloop until the expected conditions are met. + if (current_title_ != expected_title_) { + expected_title_ = expected_title.as_string(); + base::RunLoop run_loop; + quit_closure_ = run_loop.QuitClosure(); + run_loop.Run(); + } + } + + // CastWebContents::Observer implementation: + void UpdateTitle(const base::string16& title) override { + // Resumes execution of RunUntilTitleEquals() if |title| matches + // expectations. + std::string title_utf8 = base::UTF16ToUTF8(title); + current_title_ = title_utf8; + if (!quit_closure_.is_null() && current_title_ == expected_title_) { + DCHECK_EQ(current_title_, expected_title_); + std::move(quit_closure_).Run(); + } + } + + private: + std::string current_title_; + std::string expected_title_; + + base::OnceClosure quit_closure_; + + DISALLOW_COPY_AND_ASSIGN(TitleChangeObserver); +}; + } // namespace // ============================================================================= @@ -157,6 +201,7 @@ cast_web_contents_ = std::make_unique<CastWebContentsImpl>(web_contents_.get(), init_params); mock_cast_wc_observer_.Observe(cast_web_contents_.get()); + title_change_observer_.Observe(cast_web_contents_.get()); render_frames_.clear(); content::WebContentsObserver::Observe(web_contents_.get()); @@ -178,7 +223,8 @@ MockWebContentsDelegate mock_wc_delegate_; MockCastWebContentsDelegate mock_cast_wc_delegate_; - MockCastWebContentsObserver mock_cast_wc_observer_; + NiceMock<MockCastWebContentsObserver> mock_cast_wc_observer_; + TitleChangeObserver title_change_observer_; std::unique_ptr<content::WebContents> web_contents_; std::unique_ptr<CastWebContentsImpl> cast_web_contents_; @@ -603,6 +649,249 @@ run_loop->Run(); } +IN_PROC_BROWSER_TEST_F(CastWebContentsBrowserTest, ExecuteJavaScriptOnLoad) { + // =========================================================================== + // Test: Injecting script to change title should work. + // =========================================================================== + constexpr char kExpectedTitle[] = "hello"; + constexpr char kOriginalTitle[] = + "Welcome to Stan the Offline Dino's Homepage"; + + // The script should be able to run before HTML <script> tag starts running. + // The original title will be loaded first and then the injected script. Other + // scripts must run after the injected script. + EXPECT_CALL(mock_cast_wc_observer_, + UpdateTitle(base::ASCIIToUTF16(kExpectedTitle))); + EXPECT_CALL(mock_cast_wc_observer_, + UpdateTitle(base::ASCIIToUTF16(kOriginalTitle))); + constexpr char kBindingsId[] = "1234"; + + GURL gurl = content::GetFileUrlWithQuery( + GetTestDataFilePath("dynamic_title.html"), ""); + + cast_web_contents_->AddBeforeLoadJavaScript( + kBindingsId, {gurl.GetOrigin().spec()}, "stashed_title = 'hello';"); + + cast_web_contents_->LoadUrl(gurl); + title_change_observer_.RunUntilTitleEquals(kExpectedTitle); +} + +IN_PROC_BROWSER_TEST_F(CastWebContentsBrowserTest, + ExecuteJavaScriptUpdatedOnLoad) { + // =========================================================================== + // Test: Verify that this script replaces the previous script with same + // binding id, as opposed to being injected alongside it. (The latter would + // result in the title being "helloclobber"). + // =========================================================================== + constexpr char kReplaceTitle[] = "clobber"; + constexpr char kOriginalTitle[] = + "Welcome to Stan the Offline Dino's Homepage"; + + // The script should be able to run before HTML <script> tag starts running. + EXPECT_CALL(mock_cast_wc_observer_, + UpdateTitle(base::ASCIIToUTF16(kReplaceTitle))); + EXPECT_CALL(mock_cast_wc_observer_, + UpdateTitle(base::ASCIIToUTF16(kOriginalTitle))); + + constexpr char kBindingsId[] = "1234"; + + GURL gurl = content::GetFileUrlWithQuery( + GetTestDataFilePath("dynamic_title.html"), ""); + + cast_web_contents_->AddBeforeLoadJavaScript( + kBindingsId, {gurl.GetOrigin().spec()}, "stashed_title = 'hello';"); + + cast_web_contents_->AddBeforeLoadJavaScript( + kBindingsId, {gurl.GetOrigin().spec()}, + "stashed_title = document.title + 'clobber';"); + + cast_web_contents_->LoadUrl(gurl); + title_change_observer_.RunUntilTitleEquals(kReplaceTitle); +} + +IN_PROC_BROWSER_TEST_F(CastWebContentsBrowserTest, + ExecuteJavaScriptOnLoadOrdered) { + // =========================================================================== + // Test: Verifies that bindings are injected in order by producing a + // cumulative, non-commutative result. + // =========================================================================== + constexpr char kExpectedTitle[] = "hello there"; + constexpr char kOriginalTitle[] = + "Welcome to Stan the Offline Dino's Homepage"; + constexpr char kBindingsId1[] = "1234"; + constexpr char kBindingsId2[] = "5678"; + + // The script should be able to run before HTML <script> tag starts running. + // The original title will be loaded first and then the injected script. Other + // scripts must run after the injected script. + EXPECT_CALL(mock_cast_wc_observer_, + UpdateTitle(base::ASCIIToUTF16(kExpectedTitle))); + EXPECT_CALL(mock_cast_wc_observer_, + UpdateTitle(base::ASCIIToUTF16(kOriginalTitle))); + + GURL gurl = content::GetFileUrlWithQuery( + GetTestDataFilePath("dynamic_title.html"), ""); + + cast_web_contents_->AddBeforeLoadJavaScript( + kBindingsId1, {gurl.GetOrigin().spec()}, "stashed_title = 'hello';"); + + cast_web_contents_->AddBeforeLoadJavaScript( + kBindingsId2, {gurl.GetOrigin().spec()}, "stashed_title += ' there';"); + + cast_web_contents_->LoadUrl(gurl); + title_change_observer_.RunUntilTitleEquals(kExpectedTitle); +} + +IN_PROC_BROWSER_TEST_F(CastWebContentsBrowserTest, + ExecuteJavaScriptOnLoadRemoved) { + // =========================================================================== + // Test: Verifies that bindings could be removed successfully before page + // starts loading. + // =========================================================================== + constexpr char kExpectedTitle[] = "foo"; + constexpr char kOriginalTitle[] = + "Welcome to Stan the Offline Dino's Homepage"; + constexpr char kBindingsId1[] = "1234"; + constexpr char kBindingsId2[] = "5678"; + + // The script should be able to run before HTML <script> tag starts running. + // The original title will be loaded first and then the injected script. Other + // scripts must run after the injected script. + EXPECT_CALL(mock_cast_wc_observer_, + UpdateTitle(base::ASCIIToUTF16(kExpectedTitle))); + EXPECT_CALL(mock_cast_wc_observer_, + UpdateTitle(base::ASCIIToUTF16(kOriginalTitle))); + + GURL gurl = content::GetFileUrlWithQuery( + GetTestDataFilePath("dynamic_title.html"), ""); + + cast_web_contents_->AddBeforeLoadJavaScript( + kBindingsId1, {gurl.GetOrigin().spec()}, "stashed_title = 'foo';"); + // Add a script which clobbers "foo". + cast_web_contents_->AddBeforeLoadJavaScript( + kBindingsId2, {gurl.GetOrigin().spec()}, "stashed_title = 'bar';"); + // Deletes the clobbering script. + cast_web_contents_->RemoveBeforeLoadJavaScript(kBindingsId2); + + cast_web_contents_->LoadUrl(gurl); + title_change_observer_.RunUntilTitleEquals(kExpectedTitle); +} + +IN_PROC_BROWSER_TEST_F(CastWebContentsBrowserTest, + ExecuteJavaScriptOnLoadWrongOrigin) { + // =========================================================================== + // Test: Injecting script should not happen if the to-be-loaded page's origin + // is not whitelisted for the injection script. + // =========================================================================== + constexpr char kOriginalTitle[] = + "Welcome to Stan the Offline Dino's Homepage"; + constexpr char kBindingsId[] = "1234"; + + EXPECT_CALL(mock_cast_wc_observer_, + UpdateTitle(base::ASCIIToUTF16(kOriginalTitle))); + + GURL gurl = content::GetFileUrlWithQuery( + GetTestDataFilePath("dynamic_title.html"), ""); + + cast_web_contents_->AddBeforeLoadJavaScript( + kBindingsId, {"http://example.com"}, "stashed_title = 'hello';"); + + cast_web_contents_->LoadUrl(gurl); + title_change_observer_.RunUntilTitleEquals(kOriginalTitle); +} + +IN_PROC_BROWSER_TEST_F(CastWebContentsBrowserTest, + ExecuteJavaScriptOnLoadWildcardOrigin) { + // Start test server for hosting test HTML pages. + embedded_test_server()->ServeFilesFromSourceDirectory(GetTestDataPath()); + StartTestServer(); + // =========================================================================== + // Test: Injecting script should be able to load on arbitrary origins with + // wildcard origin restriction set. + // =========================================================================== + constexpr char kInjectedTitle1[] = "hello"; + constexpr char kInjectedTitle2[] = "world"; + constexpr char kOriginalTitle[] = + "Welcome to Stan the Offline Dino's Homepage"; + constexpr char kBindingsId1[] = "1234"; + constexpr char kBindingsId2[] = "5678"; + + // The script should be able to run before HTML <script> tag starts running. + EXPECT_CALL(mock_cast_wc_observer_, + UpdateTitle(base::ASCIIToUTF16(kOriginalTitle))) + .Times(2); + EXPECT_CALL(mock_cast_wc_observer_, + UpdateTitle(base::ASCIIToUTF16(kInjectedTitle1))); + EXPECT_CALL(mock_cast_wc_observer_, + UpdateTitle(base::ASCIIToUTF16(kInjectedTitle2))); + + GURL gurl{embedded_test_server()->GetURL("/dynamic_title.html")}; + + cast_web_contents_->AddBeforeLoadJavaScript(kBindingsId1, {"*"}, + "stashed_title = 'hello';"); + // Test script injection for the origin 127.0.0.1. + // Load title "hello": + cast_web_contents_->LoadUrl(gurl); + title_change_observer_.RunUntilTitleEquals(kInjectedTitle1); + + // Load AboutBlank page: + cast_web_contents_->LoadUrl(GURL(url::kAboutBlankURL)); + + cast_web_contents_->AddBeforeLoadJavaScript(kBindingsId2, {"*"}, + "stashed_title = 'world';"); + // Test script injection using a different origin ("localhost"), which should + // still be picked up by the wildcard. And the title should be initialized as + // origianl title first, then as 'world'. + GURL alt_url = + embedded_test_server()->GetURL("localhost", "/dynamic_title.html"); + cast_web_contents_->LoadUrl(alt_url); + title_change_observer_.RunUntilTitleEquals(kInjectedTitle2); +} + +IN_PROC_BROWSER_TEST_F(CastWebContentsBrowserTest, + ExecuteJavaScriptOnLoadEarlyAndLateRegistrations) { + // =========================================================================== + // Test: Tests that we can inject scripts before and after RenderFrame + // creation. + // =========================================================================== + constexpr char kExpectedTitle1[] = "foo"; + constexpr char kExpectedTitle2[] = "foo bar"; + constexpr char kOriginalTitle[] = + "Welcome to Stan the Offline Dino's Homepage"; + constexpr char kBindingsId1[] = "1234"; + constexpr char kBindingsId2[] = "5678"; + + // The script should be able to run before HTML <script> tag starts running. + // The original title will be loaded first and then the injected script. Other + // scripts must run after the injected script. + EXPECT_CALL(mock_cast_wc_observer_, + UpdateTitle(base::ASCIIToUTF16(kExpectedTitle2))); + EXPECT_CALL(mock_cast_wc_observer_, + UpdateTitle(base::ASCIIToUTF16(kExpectedTitle1))); + EXPECT_CALL(mock_cast_wc_observer_, + UpdateTitle(base::ASCIIToUTF16(kOriginalTitle))) + .Times(2); + + GURL gurl = content::GetFileUrlWithQuery( + GetTestDataFilePath("dynamic_title.html"), ""); + + cast_web_contents_->AddBeforeLoadJavaScript( + kBindingsId1, {gurl.GetOrigin().spec()}, "stashed_title = 'foo';"); + cast_web_contents_->LoadUrl(gurl); + title_change_observer_.RunUntilTitleEquals(kExpectedTitle1); + + // Inject bindings after RenderFrameCreation + cast_web_contents_->AddBeforeLoadJavaScript( + kBindingsId2, {gurl.GetOrigin().spec()}, "stashed_title += ' bar';"); + + // Navigate away to clean the state. + cast_web_contents_->LoadUrl(GURL(url::kAboutBlankURL)); + + // Navigate back and see if both scripts are working. + cast_web_contents_->LoadUrl(gurl); + title_change_observer_.RunUntilTitleEquals(kExpectedTitle2); +} + } // namespace chromecast #endif // CHROMECAST_BROWSER_CAST_WEB_CONTENTS_BROWSERTEST_H_
diff --git a/chromecast/browser/cast_web_contents_impl.cc b/chromecast/browser/cast_web_contents_impl.cc index c3b3793..de372e9e 100644 --- a/chromecast/browser/cast_web_contents_impl.cc +++ b/chromecast/browser/cast_web_contents_impl.cc
@@ -7,7 +7,10 @@ #include <utility> #include "base/bind.h" +#include "base/bind_helpers.h" #include "base/no_destructor.h" +#include "base/strings/string_piece.h" +#include "base/strings/utf_string_conversions.h" #include "base/threading/sequenced_task_runner_handle.h" #include "base/values.h" #include "chromecast/base/chromecast_switches.h" @@ -15,6 +18,7 @@ #include "chromecast/browser/cast_browser_process.h" #include "chromecast/browser/devtools/remote_debugging_server.h" #include "chromecast/common/mojom/media_playback_options.mojom.h" +#include "chromecast/common/mojom/on_load_script_injector.mojom.h" #include "chromecast/common/mojom/queryable_data_store.mojom.h" #include "chromecast/common/queryable_data.h" #include "content/public/browser/navigation_entry.h" @@ -50,6 +54,24 @@ } } +bool IsOriginWhitelisted(const GURL& url, + const std::vector<std::string>& allowed_origins) { + constexpr const char kWildcard[] = "*"; + url::Origin url_origin = url::Origin::Create(url); + + for (const std::string& allowed_origin : allowed_origins) { + if (allowed_origin == kWildcard) + return true; + + if (url_origin.IsSameOriginWith(url::Origin::Create(GURL(allowed_origin)))) + return true; + + // TODO(crbug.com/893236): Add handling for nonstandard origins + // (e.g. data: URIs). + } + return false; +} + } // namespace // static @@ -227,6 +249,50 @@ } } +CastWebContentsImpl::OriginScopedScript::OriginScopedScript() = default; + +CastWebContentsImpl::OriginScopedScript::OriginScopedScript( + const std::vector<std::string>& origins, + std::string script) + : origins_(std::move(origins)), script_(std::move(script)) {} + +CastWebContentsImpl::OriginScopedScript& +CastWebContentsImpl::OriginScopedScript::operator=( + CastWebContentsImpl::OriginScopedScript&& other) { + origins_ = std::move(other.origins_); + script_ = std::move(other.script_); + return *this; +} + +CastWebContentsImpl::OriginScopedScript::~OriginScopedScript() = default; + +void CastWebContentsImpl::AddBeforeLoadJavaScript( + base::StringPiece id, + const std::vector<std::string>& origins, + base::StringPiece script) { + DCHECK(!id.empty() && !script.empty() && !origins.empty()) + << "Invalid empty parameters were passed to AddBeforeLoadJavascript"; + // If there is no script with the identifier |id|, then create a place for it + // at the end of the injection sequence. + if (before_load_scripts_.find(id.as_string()) == before_load_scripts_.end()) { + before_load_scripts_order_.push_back(id.as_string()); + } + before_load_scripts_[id.as_string()] = + OriginScopedScript(origins, script.as_string()); +} + +void CastWebContentsImpl::RemoveBeforeLoadJavaScript(base::StringPiece id) { + before_load_scripts_.erase(id.as_string()); + + for (auto script_id_iter = before_load_scripts_order_.begin(); + script_id_iter != before_load_scripts_order_.end(); ++script_id_iter) { + if (*script_id_iter == id) { + before_load_scripts_order_.erase(script_id_iter); + return; + } + } +} + void CastWebContentsImpl::AddObserver(CastWebContents::Observer* observer) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(observer); @@ -381,6 +447,35 @@ NotifyPageState(); } +void CastWebContentsImpl::ReadyToCommitNavigation( + content::NavigationHandle* navigation_handle) { + if (before_load_scripts_.empty()) + return; + + if (!navigation_handle->IsInMainFrame() || + navigation_handle->IsSameDocument() || navigation_handle->IsErrorPage()) + return; + + chromecast::shell::mojom::OnLoadScriptInjectorAssociatedPtr + before_load_script_injector; + navigation_handle->GetRenderFrameHost() + ->GetRemoteAssociatedInterfaces() + ->GetInterface(&before_load_script_injector); + + // Provision the renderer's ScriptInjector with the scripts scoped to this + // page's origin. + before_load_script_injector->ClearOnLoadScripts(); + for (auto script_id : before_load_scripts_order_) { + const OriginScopedScript& origin_scoped_script = + before_load_scripts_[script_id]; + if (IsOriginWhitelisted(navigation_handle->GetURL(), + origin_scoped_script.origins())) { + before_load_script_injector->AddOnLoadScript( + origin_scoped_script.script()); + } + } +} + void CastWebContentsImpl::DidFinishNavigation( content::NavigationHandle* navigation_handle) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/chromecast/browser/cast_web_contents_impl.h b/chromecast/browser/cast_web_contents_impl.h index aef4fabb..e9e41e1e 100644 --- a/chromecast/browser/cast_web_contents_impl.h +++ b/chromecast/browser/cast_web_contents_impl.h
@@ -13,10 +13,12 @@ #include "base/containers/flat_map.h" #include "base/containers/flat_set.h" #include "base/macros.h" +#include "base/memory/platform_shared_memory_region.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/optional.h" #include "base/sequence_checker.h" +#include "base/strings/string_piece_forward.h" #include "base/time/time.h" #include "chromecast/browser/cast_media_blocker.h" #include "chromecast/browser/cast_web_contents.h" @@ -57,6 +59,10 @@ void BlockMediaLoading(bool blocked) override; void BlockMediaStarting(bool blocked) override; void EnableBackgroundVideoPlayback(bool enabled) override; + void AddBeforeLoadJavaScript(base::StringPiece id, + const std::vector<std::string>& origins, + base::StringPiece script) override; + void RemoveBeforeLoadJavaScript(base::StringPiece id) override; // Observer interface: void AddObserver(Observer* observer) override; @@ -74,6 +80,8 @@ void RenderProcessGone(base::TerminationStatus status) override; void DidStartNavigation( content::NavigationHandle* navigation_handle) override; + void ReadyToCommitNavigation( + content::NavigationHandle* navigation_handle) override; void DidFinishNavigation( content::NavigationHandle* navigation_handle) override; void DidFinishLoad(content::RenderFrameHost* render_frame_host, @@ -102,6 +110,22 @@ content::WebContentsObserver::MediaStoppedReason reason) override; private: + struct OriginScopedScript { + OriginScopedScript(); + OriginScopedScript(const std::vector<std::string>& origins, + std::string script); + OriginScopedScript& operator=(OriginScopedScript&& other); + ~OriginScopedScript(); + + const std::vector<std::string>& origins() const { return origins_; } + const std::string script() const { return script_; } + + std::vector<std::string> origins_; + std::string script_; + + DISALLOW_COPY_AND_ASSIGN(OriginScopedScript); + }; + void OnPageLoading(); void OnPageLoaded(); void UpdatePageState(); @@ -135,6 +159,9 @@ bool notifying_; int last_error_; + std::map<std::string, OriginScopedScript> before_load_scripts_; + std::vector<std::string> before_load_scripts_order_; + base::ObserverList<Observer>::Unchecked observer_list_; const scoped_refptr<base::SequencedTaskRunner> task_runner_;
diff --git a/chromecast/browser/test/data/dynamic_title.html b/chromecast/browser/test/data/dynamic_title.html new file mode 100644 index 0000000..c1602ea4 --- /dev/null +++ b/chromecast/browser/test/data/dynamic_title.html
@@ -0,0 +1,12 @@ +<html> + <head><title>Welcome to Stan the Offline Dino's Homepage</title></head> + <body> + <script> + // This page surfaces the contents of "stashed_title" to tests via + // the page title. If the script was not executed, or if the script + // failed to execute, then the title will be + // "Welcome to Stan the Offline Dino's Homepage". + document.title = stashed_title; + </script> + </body> +</html>
diff --git a/chromecast/browser/test/data/title1.html b/chromecast/browser/test/data/title1.html new file mode 100644 index 0000000..9c313a2 --- /dev/null +++ b/chromecast/browser/test/data/title1.html
@@ -0,0 +1,4 @@ +<html> + <head><title>title 1</title></head> + <body></body> +</html>
diff --git a/chromecast/browser/test/data/title2.html b/chromecast/browser/test/data/title2.html new file mode 100644 index 0000000..088e30d --- /dev/null +++ b/chromecast/browser/test/data/title2.html
@@ -0,0 +1,4 @@ +<html> + <head><title>title 2</title></head> + <body></body> +</html>
diff --git a/chromecast/common/mojom/BUILD.gn b/chromecast/common/mojom/BUILD.gn index 0ad9f0e0..abee4b1 100644 --- a/chromecast/common/mojom/BUILD.gn +++ b/chromecast/common/mojom/BUILD.gn
@@ -13,6 +13,7 @@ "media_playback_options.mojom", "memory_pressure.mojom", "multiroom.mojom", + "on_load_script_injector.mojom", "queryable_data_store.mojom", ]
diff --git a/chromecast/common/mojom/on_load_script_injector.mojom b/chromecast/common/mojom/on_load_script_injector.mojom new file mode 100644 index 0000000..58c38b1 --- /dev/null +++ b/chromecast/common/mojom/on_load_script_injector.mojom
@@ -0,0 +1,17 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module chromecast.shell.mojom; + +// Interface associated with RenderFrames for managing on-load JavaScript +// injection tasks per frame. Does not enforce script injection policies, +// which must be implemented at a higher level. +interface OnLoadScriptInjector { + // Add an on-load JavaScript injection task. The script will be + // executed before any other script (e.g. <script> tag) runs. + AddOnLoadScript(string script); + + // Clear all registered on-load JavaScript injection tasks. + ClearOnLoadScripts(); +};
diff --git a/chromecast/renderer/BUILD.gn b/chromecast/renderer/BUILD.gn index 85681ec..d21997c 100644 --- a/chromecast/renderer/BUILD.gn +++ b/chromecast/renderer/BUILD.gn
@@ -34,6 +34,8 @@ "cast_url_loader_throttle_provider.h", "native_bindings_helper.cc", "native_bindings_helper.h", + "on_load_script_injector.cc", + "on_load_script_injector.h", "queryable_data_bindings.cc", "queryable_data_bindings.h", "queryable_data_store.cc",
diff --git a/chromecast/renderer/cast_content_renderer_client.cc b/chromecast/renderer/cast_content_renderer_client.cc index 44308e5..363f0c3 100644 --- a/chromecast/renderer/cast_content_renderer_client.cc +++ b/chromecast/renderer/cast_content_renderer_client.cc
@@ -18,6 +18,7 @@ #include "chromecast/renderer/cast_url_loader_throttle_provider.h" #include "chromecast/renderer/media/key_systems_cast.h" #include "chromecast/renderer/media/media_caps_observer_impl.h" +#include "chromecast/renderer/on_load_script_injector.h" #include "chromecast/renderer/queryable_data_bindings.h" #include "components/network_hints/renderer/prescient_networking_dispatcher.h" #include "content/public/common/content_switches.h" @@ -170,6 +171,10 @@ new CastMediaPlaybackOptions(render_frame); new QueryableDataBindings(render_frame); + // Add script injection support to the RenderFrame, used by Cast platform + // APIs. The objects' lifetimes are bound to the RenderFrame's lifetime. + new OnLoadScriptInjector(render_frame); + if (!app_media_capabilities_observer_binding_.is_bound()) { mojom::ApplicationMediaCapabilitiesObserverPtr observer; app_media_capabilities_observer_binding_.Bind(mojo::MakeRequest(&observer));
diff --git a/chromecast/renderer/on_load_script_injector.cc b/chromecast/renderer/on_load_script_injector.cc new file mode 100644 index 0000000..f221830 --- /dev/null +++ b/chromecast/renderer/on_load_script_injector.cc
@@ -0,0 +1,64 @@ +// 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 "chromecast/renderer/on_load_script_injector.h" + +#include <utility> +#include <vector> + +#include "base/bind.h" +#include "base/memory/shared_memory_handle.h" +#include "base/strings/string_piece.h" +#include "base/strings/utf_string_conversions.h" +#include "content/public/renderer/render_frame.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" + +namespace chromecast { +namespace shell { + +OnLoadScriptInjector::OnLoadScriptInjector(content::RenderFrame* frame) + : RenderFrameObserver(frame), weak_ptr_factory_(this) { + render_frame()->GetAssociatedInterfaceRegistry()->AddInterface( + base::BindRepeating(&OnLoadScriptInjector::BindToRequest, + weak_ptr_factory_.GetWeakPtr())); +} + +OnLoadScriptInjector::~OnLoadScriptInjector() {} + +void OnLoadScriptInjector::BindToRequest( + mojom::OnLoadScriptInjectorAssociatedRequest request) { + bindings_.AddBinding(this, std::move(request)); +} + +void OnLoadScriptInjector::DidCommitProvisionalLoad( + bool is_same_document_navigation, + ui::PageTransition transition) { + // Ignore pushState or document fragment navigation. + if (is_same_document_navigation) + return; + + // Don't inject anything for subframes. + if (!render_frame()->IsMainFrame()) + return; + + for (std::string& script : on_load_scripts_) { + base::string16 script_utf16 = base::UTF8ToUTF16(script); + render_frame()->ExecuteJavaScript(script_utf16); + } +} + +void OnLoadScriptInjector::AddOnLoadScript(const std::string& script) { + on_load_scripts_.push_back(std::move(script)); +} + +void OnLoadScriptInjector::ClearOnLoadScripts() { + on_load_scripts_.clear(); +} + +void OnLoadScriptInjector::OnDestruct() { + delete this; +} + +} // namespace shell +} // namespace chromecast
diff --git a/chromecast/renderer/on_load_script_injector.h b/chromecast/renderer/on_load_script_injector.h new file mode 100644 index 0000000..6866887 --- /dev/null +++ b/chromecast/renderer/on_load_script_injector.h
@@ -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. + +#ifndef CHROMECAST_RENDERER_ON_LOAD_SCRIPT_INJECTOR_H_ +#define CHROMECAST_RENDERER_ON_LOAD_SCRIPT_INJECTOR_H_ + +#include <vector> + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/strings/string_piece_forward.h" +#include "chromecast/common/mojom/on_load_script_injector.mojom.h" +#include "content/public/renderer/render_frame_observer.h" +#include "mojo/public/cpp/bindings/associated_binding_set.h" + +namespace chromecast { +namespace shell { + +// Injects one or more scripts into a RenderFrame at the earliest possible time +// during the page load process. +class OnLoadScriptInjector : public content::RenderFrameObserver, + public mojom::OnLoadScriptInjector { + public: + explicit OnLoadScriptInjector(content::RenderFrame* frame); + + void BindToRequest(mojom::OnLoadScriptInjectorAssociatedRequest request); + + void AddOnLoadScript(const std::string& script) override; + void ClearOnLoadScripts() override; + + // RenderFrameObserver override: + void OnDestruct() override; + void DidCommitProvisionalLoad(bool is_same_document_navigation, + ui::PageTransition transition) override; + + private: + // Called by OnDestruct(), when the RenderFrame is destroyed. + ~OnLoadScriptInjector() override; + + std::vector<std::string> on_load_scripts_; + mojo::AssociatedBindingSet<mojom::OnLoadScriptInjector> bindings_; + base::WeakPtrFactory<OnLoadScriptInjector> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(OnLoadScriptInjector); +}; + +} // namespace shell +} // namespace chromecast + +#endif // CHROMECAST_RENDERER_ON_LOAD_SCRIPT_INJECTOR_H_
diff --git a/chromeos/dbus/concierge_client.cc b/chromeos/dbus/concierge_client.cc index fd67537..b6062cf 100644 --- a/chromeos/dbus/concierge_client.cc +++ b/chromeos/dbus/concierge_client.cc
@@ -248,6 +248,32 @@ weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } + void GetVmEnterpriseReportingInfo( + const vm_tools::concierge::GetVmEnterpriseReportingInfoRequest& request, + DBusMethodCallback< + vm_tools::concierge::GetVmEnterpriseReportingInfoResponse> callback) + override { + dbus::MethodCall method_call( + vm_tools::concierge::kVmConciergeInterface, + vm_tools::concierge::kGetVmEnterpriseReportingInfoMethod); + dbus::MessageWriter writer(&method_call); + + if (!writer.AppendProtoAsArrayOfBytes(request)) { + LOG(ERROR) + << "Failed to encode GetVmEnterpriseReportingInfoRequest protobuf"; + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), base::nullopt)); + return; + } + + concierge_proxy_->CallMethod( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::BindOnce( + &ConciergeClientImpl::OnDBusProtoResponse< + vm_tools::concierge::GetVmEnterpriseReportingInfoResponse>, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + } + void WaitForServiceToBeAvailable( dbus::ObjectProxy::WaitForServiceToBeAvailableCallback callback) override {
diff --git a/chromeos/dbus/concierge_client.h b/chromeos/dbus/concierge_client.h index fe82197..df1638e 100644 --- a/chromeos/dbus/concierge_client.h +++ b/chromeos/dbus/concierge_client.h
@@ -128,6 +128,14 @@ const vm_tools::concierge::GetVmInfoRequest& request, DBusMethodCallback<vm_tools::concierge::GetVmInfoResponse> callback) = 0; + // Get enterprise-reporting specific VM info. + // |callback| is called after the method call finishes. + virtual void GetVmEnterpriseReportingInfo( + const vm_tools::concierge::GetVmEnterpriseReportingInfoRequest& request, + DBusMethodCallback< + vm_tools::concierge::GetVmEnterpriseReportingInfoResponse> + callback) = 0; + // Registers |callback| to run when the Concierge service becomes available. // If the service is already available, or if connecting to the name-owner- // changed signal fails, |callback| will be run once asynchronously.
diff --git a/chromeos/dbus/fake_concierge_client.cc b/chromeos/dbus/fake_concierge_client.cc index 9442037..12a3a0b 100644 --- a/chromeos/dbus/fake_concierge_client.cc +++ b/chromeos/dbus/fake_concierge_client.cc
@@ -162,6 +162,16 @@ FROM_HERE, base::BindOnce(std::move(callback), get_vm_info_response_)); } +void FakeConciergeClient::GetVmEnterpriseReportingInfo( + const vm_tools::concierge::GetVmEnterpriseReportingInfoRequest& request, + DBusMethodCallback< + vm_tools::concierge::GetVmEnterpriseReportingInfoResponse> callback) { + get_vm_enterprise_reporting_info_called_ = true; + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), + get_vm_enterprise_reporting_info_response_)); +} + void FakeConciergeClient::WaitForServiceToBeAvailable( dbus::ObjectProxy::WaitForServiceToBeAvailableCallback callback) { wait_for_service_to_be_available_called_ = true;
diff --git a/chromeos/dbus/fake_concierge_client.h b/chromeos/dbus/fake_concierge_client.h index ff1f696..33cc951c 100644 --- a/chromeos/dbus/fake_concierge_client.h +++ b/chromeos/dbus/fake_concierge_client.h
@@ -104,6 +104,15 @@ DBusMethodCallback<vm_tools::concierge::GetVmInfoResponse> callback) override; + // Fake version of the method that gets VM enterprise reporting info. Sets + // get_vm_enterprise_reporting_info_called_. |callback| is called after the + // method call finishes. + void GetVmEnterpriseReportingInfo( + const vm_tools::concierge::GetVmEnterpriseReportingInfoRequest& request, + DBusMethodCallback< + vm_tools::concierge::GetVmEnterpriseReportingInfoResponse> callback) + override; + // Fake version of the method that waits for the Concierge service to be // availble. |callback| is called after the method call finishes. void WaitForServiceToBeAvailable( @@ -163,6 +172,10 @@ bool stop_vm_called() const { return stop_vm_called_; } // Indicates whether GetVmInfo has been called bool get_vm_info_called() const { return get_vm_info_called_; } + // Indicates whether GetEnterpriseReportingInfo has been called + bool get_vm_enterprise_reporting_info_called() const { + return get_vm_enterprise_reporting_info_called_; + } // Indicates whether GetContainerSshKeys has been called bool get_container_ssh_keys_called() const { return get_container_ssh_keys_called_; @@ -229,6 +242,12 @@ const vm_tools::concierge::GetVmInfoResponse& get_vm_info_response) { get_vm_info_response_ = get_vm_info_response; } + void set_get_vm_enterprise_reporting_info_response( + const vm_tools::concierge::GetVmEnterpriseReportingInfoResponse& + get_vm_enterprise_reporting_info_response) { + get_vm_enterprise_reporting_info_response_ = + get_vm_enterprise_reporting_info_response; + } void set_container_ssh_keys_response( const vm_tools::concierge::ContainerSshKeysResponse& container_ssh_keys_response) { @@ -282,6 +301,7 @@ bool start_termina_vm_called_ = false; bool stop_vm_called_ = false; bool get_vm_info_called_ = false; + bool get_vm_enterprise_reporting_info_called_ = false; bool get_container_ssh_keys_called_ = false; bool attach_usb_device_called_ = false; bool detach_usb_device_called_ = false; @@ -300,6 +320,8 @@ vm_tools::concierge::StartVmResponse start_vm_response_; vm_tools::concierge::StopVmResponse stop_vm_response_; vm_tools::concierge::GetVmInfoResponse get_vm_info_response_; + vm_tools::concierge::GetVmEnterpriseReportingInfoResponse + get_vm_enterprise_reporting_info_response_; vm_tools::concierge::ContainerSshKeysResponse container_ssh_keys_response_; vm_tools::concierge::AttachUsbDeviceResponse attach_usb_device_response_; vm_tools::concierge::DetachUsbDeviceResponse detach_usb_device_response_;
diff --git a/components/arc/DEPS b/components/arc/DEPS index 86e6332..ffb51248 100644 --- a/components/arc/DEPS +++ b/components/arc/DEPS
@@ -15,6 +15,7 @@ "+components/version_info", "+content/public/browser", "+media/base/video_codecs.h", + "+media/base/video_types.h", "+media/video/video_encode_accelerator.h", "+mojo", "+storage/browser/fileapi",
diff --git a/components/arc/common/video_accelerator_struct_traits.cc b/components/arc/common/video_accelerator_struct_traits.cc index f99d0c7..9e9f702a 100644 --- a/components/arc/common/video_accelerator_struct_traits.cc +++ b/components/arc/common/video_accelerator_struct_traits.cc
@@ -111,6 +111,51 @@ return false; } +// Make sure values in arc::mojom::VideoPixelFormat match to the values in +// media::VideoPixelFormat. The former is a subset of the later. +#define CHECK_PIXEL_FORMAT_ENUM(value) \ + static_assert( \ + static_cast<int>(arc::mojom::VideoPixelFormat::value) == media::value, \ + "enum ##value mismatch") + +CHECK_PIXEL_FORMAT_ENUM(PIXEL_FORMAT_I420); +CHECK_PIXEL_FORMAT_ENUM(PIXEL_FORMAT_YV12); +CHECK_PIXEL_FORMAT_ENUM(PIXEL_FORMAT_NV12); +CHECK_PIXEL_FORMAT_ENUM(PIXEL_FORMAT_NV21); +CHECK_PIXEL_FORMAT_ENUM(PIXEL_FORMAT_ARGB); +CHECK_PIXEL_FORMAT_ENUM(PIXEL_FORMAT_ABGR); +CHECK_PIXEL_FORMAT_ENUM(PIXEL_FORMAT_XBGR); + +#undef CHECK_PXIEL_FORMAT_ENUM + +// static +arc::mojom::VideoPixelFormat +EnumTraits<arc::mojom::VideoPixelFormat, media::VideoPixelFormat>::ToMojom( + media::VideoPixelFormat input) { + NOTIMPLEMENTED(); + return arc::mojom::VideoPixelFormat::PIXEL_FORMAT_I420; +} + +// static +bool EnumTraits<arc::mojom::VideoPixelFormat, media::VideoPixelFormat>:: + FromMojom(arc::mojom::VideoPixelFormat input, + media::VideoPixelFormat* output) { + switch (input) { + case arc::mojom::VideoPixelFormat::PIXEL_FORMAT_UNKNOWN: + case arc::mojom::VideoPixelFormat::PIXEL_FORMAT_I420: + case arc::mojom::VideoPixelFormat::PIXEL_FORMAT_YV12: + case arc::mojom::VideoPixelFormat::PIXEL_FORMAT_NV12: + case arc::mojom::VideoPixelFormat::PIXEL_FORMAT_NV21: + case arc::mojom::VideoPixelFormat::PIXEL_FORMAT_ARGB: + case arc::mojom::VideoPixelFormat::PIXEL_FORMAT_ABGR: + case arc::mojom::VideoPixelFormat::PIXEL_FORMAT_XBGR: + *output = static_cast<media::VideoPixelFormat>(input); + return true; + } + NOTREACHED(); + return false; +} + // static bool StructTraits<arc::mojom::VideoFramePlaneDataView, arc::VideoFramePlane>:: Read(arc::mojom::VideoFramePlaneDataView data, arc::VideoFramePlane* out) {
diff --git a/components/arc/common/video_accelerator_struct_traits.h b/components/arc/common/video_accelerator_struct_traits.h index c1f4e28f..82068b22 100644 --- a/components/arc/common/video_accelerator_struct_traits.h +++ b/components/arc/common/video_accelerator_struct_traits.h
@@ -8,6 +8,7 @@ #include "components/arc/common/video_common.mojom.h" #include "components/arc/video_accelerator/video_frame_plane.h" #include "media/base/video_codecs.h" +#include "media/base/video_types.h" #include "ui/gfx/geometry/size.h" namespace mojo { @@ -50,6 +51,15 @@ static bool Read(arc::mojom::SizeDataView data, gfx::Size* out); }; + +template <> +struct EnumTraits<arc::mojom::VideoPixelFormat, media::VideoPixelFormat> { + static arc::mojom::VideoPixelFormat ToMojom(media::VideoPixelFormat input); + + static bool FromMojom(arc::mojom::VideoPixelFormat input, + media::VideoPixelFormat* output); +}; + } // namespace mojo #endif // COMPONENTS_ARC_COMMON_VIDEO_ACCELERATOR_STRUCT_TRAITS_H_
diff --git a/components/arc/common/video_common.mojom b/components/arc/common/video_common.mojom index 27e4f86..613ba8e 100644 --- a/components/arc/common/video_common.mojom +++ b/components/arc/common/video_common.mojom
@@ -68,6 +68,19 @@ HAL_PIXEL_FORMAT_NV12 = 0x3231564e, }; +[Extensible] +enum VideoPixelFormat { + // The values must match to the values in media::VideoPixelFormat + PIXEL_FORMAT_UNKNOWN = 0, + PIXEL_FORMAT_I420 = 1, + [MinVersion=2] PIXEL_FORMAT_YV12 = 2, + [MinVersion=2] PIXEL_FORMAT_NV12 = 6, + [MinVersion=2] PIXEL_FORMAT_NV21 = 7, + [MinVersion=2] PIXEL_FORMAT_ARGB = 10, + [MinVersion=2] PIXEL_FORMAT_ABGR = 27, + [MinVersion=2] PIXEL_FORMAT_XBGR = 28, +}; + // The offset and stride of a video frame plane. Both offset and stride must // be non negative. struct VideoFramePlane {
diff --git a/components/arc/common/video_common.typemap b/components/arc/common/video_common.typemap index 69e68668..ee8e5ab 100644 --- a/components/arc/common/video_common.typemap +++ b/components/arc/common/video_common.typemap
@@ -6,6 +6,7 @@ public_headers = [ "//media/base/video_codecs.h", "//components/arc/video_accelerator/video_frame_plane.h", + "//media/base/video_types.h", "//ui/gfx/geometry/size.h", ] public_deps = [ @@ -21,5 +22,6 @@ type_mappings = [ "arc.mojom.VideoCodecProfile=media::VideoCodecProfile", "arc.mojom.VideoFramePlane=arc::VideoFramePlane[move_only]", + "arc.mojom.VideoPixelFormat=media::VideoPixelFormat", "arc.mojom.Size=gfx::Size", ]
diff --git a/components/arc/common/video_encode_accelerator.mojom b/components/arc/common/video_encode_accelerator.mojom index 29c0690..b4c9f41 100644 --- a/components/arc/common/video_encode_accelerator.mojom +++ b/components/arc/common/video_encode_accelerator.mojom
@@ -11,19 +11,6 @@ // Next MinVersion: 4 -[Extensible] -enum VideoPixelFormat { - // The values must match to the values in media::VideoPixelFormat - PIXEL_FORMAT_UNKNOWN = 0, - PIXEL_FORMAT_I420 = 1, - [MinVersion=2] PIXEL_FORMAT_YV12 = 2, - [MinVersion=2] PIXEL_FORMAT_NV12 = 6, - [MinVersion=2] PIXEL_FORMAT_NV21 = 7, - [MinVersion=2] PIXEL_FORMAT_ARGB = 10, - [MinVersion=2] PIXEL_FORMAT_ABGR = 27, - [MinVersion=2] PIXEL_FORMAT_XBGR = 28, -}; - // Specification of an encoding profile supported by an encoder. struct VideoEncodeProfile { VideoCodecProfile profile;
diff --git a/components/arc/common/video_encode_accelerator.typemap b/components/arc/common/video_encode_accelerator.typemap index eb875515..5210cc6 100644 --- a/components/arc/common/video_encode_accelerator.typemap +++ b/components/arc/common/video_encode_accelerator.typemap
@@ -19,7 +19,6 @@ type_mappings = [ "arc.mojom.VideoFrameStorageType=media::VideoEncodeAccelerator::Config::StorageType", "arc.mojom.VideoEncodeAccelerator.Error=media::VideoEncodeAccelerator::Error", - "arc.mojom.VideoPixelFormat=media::VideoPixelFormat", "arc.mojom.VideoEncodeProfile=media::VideoEncodeAccelerator::SupportedProfile", "arc.mojom.VideoEncodeAcceleratorConfig=media::VideoEncodeAccelerator::Config", ]
diff --git a/components/arc/common/video_encode_accelerator_struct_traits.cc b/components/arc/common/video_encode_accelerator_struct_traits.cc index 17c4a79..72bcd88 100644 --- a/components/arc/common/video_encode_accelerator_struct_traits.cc +++ b/components/arc/common/video_encode_accelerator_struct_traits.cc
@@ -65,51 +65,6 @@ return false; } -// Make sure values in arc::mojom::VideoPixelFormat match to the values in -// media::VideoPixelFormat. The former is a subset of the later. -#define CHECK_PIXEL_FORMAT_ENUM(value) \ - static_assert( \ - static_cast<int>(arc::mojom::VideoPixelFormat::value) == media::value, \ - "enum ##value mismatch") - -CHECK_PIXEL_FORMAT_ENUM(PIXEL_FORMAT_I420); -CHECK_PIXEL_FORMAT_ENUM(PIXEL_FORMAT_YV12); -CHECK_PIXEL_FORMAT_ENUM(PIXEL_FORMAT_NV12); -CHECK_PIXEL_FORMAT_ENUM(PIXEL_FORMAT_NV21); -CHECK_PIXEL_FORMAT_ENUM(PIXEL_FORMAT_ARGB); -CHECK_PIXEL_FORMAT_ENUM(PIXEL_FORMAT_ABGR); -CHECK_PIXEL_FORMAT_ENUM(PIXEL_FORMAT_XBGR); - -#undef CHECK_PXIEL_FORMAT_ENUM - -// static -arc::mojom::VideoPixelFormat -EnumTraits<arc::mojom::VideoPixelFormat, media::VideoPixelFormat>::ToMojom( - media::VideoPixelFormat input) { - NOTIMPLEMENTED(); - return arc::mojom::VideoPixelFormat::PIXEL_FORMAT_I420; -} - -// static -bool EnumTraits<arc::mojom::VideoPixelFormat, media::VideoPixelFormat>:: - FromMojom(arc::mojom::VideoPixelFormat input, - media::VideoPixelFormat* output) { - switch (input) { - case arc::mojom::VideoPixelFormat::PIXEL_FORMAT_UNKNOWN: - case arc::mojom::VideoPixelFormat::PIXEL_FORMAT_I420: - case arc::mojom::VideoPixelFormat::PIXEL_FORMAT_YV12: - case arc::mojom::VideoPixelFormat::PIXEL_FORMAT_NV12: - case arc::mojom::VideoPixelFormat::PIXEL_FORMAT_NV21: - case arc::mojom::VideoPixelFormat::PIXEL_FORMAT_ARGB: - case arc::mojom::VideoPixelFormat::PIXEL_FORMAT_ABGR: - case arc::mojom::VideoPixelFormat::PIXEL_FORMAT_XBGR: - *output = static_cast<media::VideoPixelFormat>(input); - return true; - } - NOTREACHED(); - return false; -} - // static bool StructTraits<arc::mojom::VideoEncodeAcceleratorConfigDataView, media::VideoEncodeAccelerator::Config>::
diff --git a/components/arc/common/video_encode_accelerator_struct_traits.h b/components/arc/common/video_encode_accelerator_struct_traits.h index 9f0dee5..aa3078c0 100644 --- a/components/arc/common/video_encode_accelerator_struct_traits.h +++ b/components/arc/common/video_encode_accelerator_struct_traits.h
@@ -31,14 +31,6 @@ }; template <> -struct EnumTraits<arc::mojom::VideoPixelFormat, media::VideoPixelFormat> { - static arc::mojom::VideoPixelFormat ToMojom(media::VideoPixelFormat input); - - static bool FromMojom(arc::mojom::VideoPixelFormat input, - media::VideoPixelFormat* output); -}; - -template <> struct StructTraits<arc::mojom::VideoEncodeProfileDataView, media::VideoEncodeAccelerator::SupportedProfile> { static media::VideoCodecProfile profile(
diff --git a/components/background_task_scheduler/BUILD.gn b/components/background_task_scheduler/BUILD.gn index be854b8..5923277f 100644 --- a/components/background_task_scheduler/BUILD.gn +++ b/components/background_task_scheduler/BUILD.gn
@@ -93,6 +93,7 @@ "android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerPrefsTest.java", "android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerUmaTest.java", "android/junit/src/org/chromium/components/background_task_scheduler/ShadowGcmNetworkManager.java", + "android/junit/src/org/chromium/components/background_task_scheduler/TaskInfoTest.java", "android/junit/src/org/chromium/components/background_task_scheduler/TestBackgroundTask.java", ]
diff --git a/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskInfo.java b/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskInfo.java index 3d263cc..fb9ed42 100644 --- a/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskInfo.java +++ b/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskInfo.java
@@ -25,12 +25,14 @@ private final long mWindowStartTimeMs; private final long mWindowEndTimeMs; private final boolean mHasWindowStartTimeConstraint; + private final boolean mExpiresAfterWindowEndTime; private OneOffInfo(long windowStartTimeMs, long windowEndTimeMs, - boolean hasWindowStartTimeConstraint) { + boolean hasWindowStartTimeConstraint, boolean expiresAfterWindowEndTime) { mWindowStartTimeMs = windowStartTimeMs; mWindowEndTimeMs = windowEndTimeMs; mHasWindowStartTimeConstraint = hasWindowStartTimeConstraint; + mExpiresAfterWindowEndTime = expiresAfterWindowEndTime; } /** @@ -56,10 +58,19 @@ return mHasWindowStartTimeConstraint; } + /** + * @return whether this one-off task expires after {@link #getWindowEndTimeMs()} + * False by default. + */ + public boolean expiresAfterWindowEndTime() { + return mExpiresAfterWindowEndTime; + } + @Override public String toString() { - return "{windowStartTimeMs: " + mWindowStartTimeMs + ", windowEndTimeMs: " - + mWindowEndTimeMs + "}"; + return "{windowStartTimeMs: " + mWindowStartTimeMs + + ", windowEndTimeMs: " + mWindowEndTimeMs + + "} - expires at window_end_time: " + mExpiresAfterWindowEndTime; } } @@ -205,7 +216,7 @@ new PeriodicInfo(builder.mIntervalMs, builder.mFlexMs, builder.mHasFlex); } else { mOneOffInfo = new OneOffInfo(builder.mWindowStartTimeMs, builder.mWindowEndTimeMs, - builder.mHasWindowStartTimeConstraint); + builder.mHasWindowStartTimeConstraint, builder.mExpiresAfterWindowEndTime); mPeriodicInfo = null; } } @@ -420,6 +431,7 @@ private long mWindowStartTimeMs; private long mWindowEndTimeMs; private boolean mHasWindowStartTimeConstraint; + private boolean mExpiresAfterWindowEndTime; // Data about periodic tasks. private long mIntervalMs; @@ -446,6 +458,19 @@ return this; } + /** + * Set whether the task should expire if not scheduled until the window end time. + * This should be called only for One-Off tasks. + * + * @param expiresAfterWindowEndTime whether the task expires or not. + * @return this {@link Builder}. + */ + Builder setExpiresAfterWindowEndTime(boolean expiresAfterWindowEndTime) { + assert !mIsPeriodic; + mExpiresAfterWindowEndTime = expiresAfterWindowEndTime; + return this; + } + Builder setIntervalMs(long intervalMs) { assert mIsPeriodic; mIntervalMs = intervalMs;
diff --git a/components/background_task_scheduler/android/junit/src/org/chromium/components/background_task_scheduler/TaskInfoTest.java b/components/background_task_scheduler/android/junit/src/org/chromium/components/background_task_scheduler/TaskInfoTest.java new file mode 100644 index 0000000..c6aea9c --- /dev/null +++ b/components/background_task_scheduler/android/junit/src/org/chromium/components/background_task_scheduler/TaskInfoTest.java
@@ -0,0 +1,89 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.components.background_task_scheduler; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.util.Feature; + +/** Unit tests for {@link TaskInfo}. */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class TaskInfoTest { + private static final int TEST_START_MS = 300000; + private static final int TEST_END_MS = 600000; + + @Before + public void setUp() { + TestBackgroundTask.reset(); + } + + private void checkGeneralTaskInfoFields( + TaskInfo taskInfo, int taskId, Class<? extends BackgroundTask> backgroundTaskClass) { + assertEquals(taskId, taskInfo.getTaskId()); + assertEquals(backgroundTaskClass, taskInfo.getBackgroundTaskClass()); + } + + @Test + @Feature({"BackgroundTaskScheduler"}) + public void testExpirationWithinDeadline() { + TaskInfo oneOffTask = + TaskInfo.createOneOffTask(TaskIds.TEST, TestBackgroundTask.class, TEST_END_MS) + .setExpiresAfterWindowEndTime(true) + .build(); + + checkGeneralTaskInfoFields(oneOffTask, TaskIds.TEST, TestBackgroundTask.class); + + assertFalse(oneOffTask.getOneOffInfo().hasWindowStartTimeConstraint()); + assertEquals(TEST_END_MS, oneOffTask.getOneOffInfo().getWindowEndTimeMs()); + assertTrue(oneOffTask.getOneOffInfo().expiresAfterWindowEndTime()); + + assertEquals(null, oneOffTask.getPeriodicInfo()); + } + + @Test + @Feature({"BackgroundTaskScheduler"}) + public void testExpirationWithinTimeWindow() { + TaskInfo oneOffTask = TaskInfo.createOneOffTask(TaskIds.TEST, TestBackgroundTask.class, + TEST_START_MS, TEST_END_MS) + .setExpiresAfterWindowEndTime(true) + .build(); + + checkGeneralTaskInfoFields(oneOffTask, TaskIds.TEST, TestBackgroundTask.class); + + assertTrue(oneOffTask.getOneOffInfo().hasWindowStartTimeConstraint()); + assertEquals(TEST_START_MS, oneOffTask.getOneOffInfo().getWindowStartTimeMs()); + assertEquals(TEST_END_MS, oneOffTask.getOneOffInfo().getWindowEndTimeMs()); + assertTrue(oneOffTask.getOneOffInfo().expiresAfterWindowEndTime()); + + assertEquals(null, oneOffTask.getPeriodicInfo()); + } + + @Test + @Feature({"BackgroundTaskScheduler"}) + public void testExpirationWithinZeroTimeWindow() { + TaskInfo oneOffTask = TaskInfo.createOneOffTask(TaskIds.TEST, TestBackgroundTask.class, + TEST_END_MS, TEST_END_MS) + .setExpiresAfterWindowEndTime(true) + .build(); + + checkGeneralTaskInfoFields(oneOffTask, TaskIds.TEST, TestBackgroundTask.class); + + assertTrue(oneOffTask.getOneOffInfo().hasWindowStartTimeConstraint()); + assertEquals(TEST_END_MS, oneOffTask.getOneOffInfo().getWindowStartTimeMs()); + assertEquals(TEST_END_MS, oneOffTask.getOneOffInfo().getWindowEndTimeMs()); + assertTrue(oneOffTask.getOneOffInfo().expiresAfterWindowEndTime()); + + assertEquals(null, oneOffTask.getPeriodicInfo()); + } +} \ No newline at end of file
diff --git a/components/exo/wayland/fuzzer/BUILD.gn b/components/exo/wayland/fuzzer/BUILD.gn index 37051bb..15706168 100644 --- a/components/exo/wayland/fuzzer/BUILD.gn +++ b/components/exo/wayland/fuzzer/BUILD.gn
@@ -124,6 +124,7 @@ "//components/exo:test_support", "//components/exo/wayland", "//skia", + "//third_party/wayland:wayland_util", ] }
diff --git a/components/password_manager/core/browser/credential_manager_impl.cc b/components/password_manager/core/browser/credential_manager_impl.cc index 6c91be7..141237c 100644 --- a/components/password_manager/core/browser/credential_manager_impl.cc +++ b/components/password_manager/core/browser/credential_manager_impl.cc
@@ -107,8 +107,8 @@ pending_request_ ? CredentialManagerError::PENDING_REQUEST : CredentialManagerError::PASSWORDSTOREUNAVAILABLE, base::nullopt); - LogCredentialManagerGetResult(metrics_util::CREDENTIAL_MANAGER_GET_REJECTED, - mediation); + LogCredentialManagerGetResult( + metrics_util::CredentialManagerGetResult::kRejected, mediation); return; } @@ -117,8 +117,8 @@ if (!client_->IsFillingEnabled(GetLastCommittedURL()) || !client_->OnCredentialManagerUsed()) { std::move(callback).Run(CredentialManagerError::SUCCESS, CredentialInfo()); - LogCredentialManagerGetResult(metrics_util::CREDENTIAL_MANAGER_GET_NONE, - mediation); + LogCredentialManagerGetResult( + metrics_util::CredentialManagerGetResult::kNone, mediation); return; } // Return an empty credential if zero-click is required but disabled. @@ -127,7 +127,7 @@ // Callback with empty credential info. std::move(callback).Run(CredentialManagerError::SUCCESS, CredentialInfo()); LogCredentialManagerGetResult( - metrics_util::CREDENTIAL_MANAGER_GET_NONE_ZERO_CLICK_OFF, mediation); + metrics_util::CredentialManagerGetResult::kNoneZeroClickOff, mediation); return; } @@ -192,12 +192,12 @@ base::RecordAction( base::UserMetricsAction("CredentialManager_AccountChooser_Accepted")); metrics_util::LogCredentialManagerGetResult( - metrics_util::CREDENTIAL_MANAGER_GET_ACCOUNT_CHOOSER, mediation); + metrics_util::CredentialManagerGetResult::kAccountChooser, mediation); } else { base::RecordAction( base::UserMetricsAction("CredentialManager_AccountChooser_Dismissed")); metrics_util::LogCredentialManagerGetResult( - metrics_util::CREDENTIAL_MANAGER_GET_NONE, mediation); + metrics_util::CredentialManagerGetResult::kNone, mediation); } SendCredential(send_callback, info); }
diff --git a/components/password_manager/core/browser/credential_manager_pending_request_task.cc b/components/password_manager/core/browser/credential_manager_pending_request_task.cc index 9ff4c1d..689d126 100644 --- a/components/password_manager/core/browser/credential_manager_pending_request_task.cc +++ b/components/password_manager/core/browser/credential_manager_pending_request_task.cc
@@ -122,8 +122,8 @@ std::vector<std::unique_ptr<autofill::PasswordForm>> results) { using metrics_util::LogCredentialManagerGetResult; if (delegate_->GetOrigin() != origin_) { - LogCredentialManagerGetResult(metrics_util::CREDENTIAL_MANAGER_GET_NONE, - mediation_); + LogCredentialManagerGetResult( + metrics_util::CredentialManagerGetResult::kNone, mediation_); delegate_->SendCredential(send_callback_, CredentialInfo()); return; } @@ -179,7 +179,7 @@ origin_); base::RecordAction(base::UserMetricsAction("CredentialManager_Autosignin")); LogCredentialManagerGetResult( - metrics_util::CREDENTIAL_MANAGER_GET_AUTOSIGNIN, mediation_); + metrics_util::CredentialManagerGetResult::kAutoSignIn, mediation_); delegate_->SendCredential(send_callback_, info); return; } @@ -187,13 +187,14 @@ if (mediation_ == CredentialMediationRequirement::kSilent) { metrics_util::CredentialManagerGetResult get_result; if (local_results.empty()) - get_result = metrics_util::CREDENTIAL_MANAGER_GET_NONE_EMPTY_STORE; + get_result = metrics_util::CredentialManagerGetResult::kNoneEmptyStore; else if (!can_use_autosignin) - get_result = metrics_util::CREDENTIAL_MANAGER_GET_NONE_MANY_CREDENTIALS; + get_result = + metrics_util::CredentialManagerGetResult::kNoneManyCredentials; else if (local_results[0]->skip_zero_click) - get_result = metrics_util::CREDENTIAL_MANAGER_GET_NONE_SIGNED_OUT; + get_result = metrics_util::CredentialManagerGetResult::kNoneSignedOut; else - get_result = metrics_util::CREDENTIAL_MANAGER_GET_NONE_FIRST_RUN; + get_result = metrics_util::CredentialManagerGetResult::kNoneFirstRun; if (can_use_autosignin) { // The user had credentials, but either chose not to share them with the @@ -218,7 +219,7 @@ if (local_results.empty()) { LogCredentialManagerGetResult( - metrics_util::CREDENTIAL_MANAGER_GET_NONE_EMPTY_STORE, mediation_); + metrics_util::CredentialManagerGetResult::kNoneEmptyStore, mediation_); delegate_->SendCredential(send_callback_, CredentialInfo()); return; } @@ -228,8 +229,8 @@ base::Bind( &CredentialManagerPendingRequestTaskDelegate::SendPasswordForm, base::Unretained(delegate_), send_callback_, mediation_))) { - LogCredentialManagerGetResult(metrics_util::CREDENTIAL_MANAGER_GET_NONE, - mediation_); + LogCredentialManagerGetResult( + metrics_util::CredentialManagerGetResult::kNone, mediation_); delegate_->SendCredential(send_callback_, CredentialInfo()); } }
diff --git a/components/password_manager/core/browser/password_manager_metrics_util.cc b/components/password_manager/core/browser/password_manager_metrics_util.cc index 7294c3d2..97ee12d6 100644 --- a/components/password_manager/core/browser/password_manager_metrics_util.cc +++ b/components/password_manager/core/browser/password_manager_metrics_util.cc
@@ -119,16 +119,15 @@ CredentialMediationRequirement mediation) { switch (mediation) { case CredentialMediationRequirement::kSilent: - base::UmaHistogramEnumeration("PasswordManager.MediationSilent", result, - CREDENTIAL_MANAGER_GET_COUNT); + base::UmaHistogramEnumeration("PasswordManager.MediationSilent", result); break; case CredentialMediationRequirement::kOptional: - base::UmaHistogramEnumeration("PasswordManager.MediationOptional", result, - CREDENTIAL_MANAGER_GET_COUNT); + base::UmaHistogramEnumeration("PasswordManager.MediationOptional", + result); break; case CredentialMediationRequirement::kRequired: - base::UmaHistogramEnumeration("PasswordManager.MediationRequired", result, - CREDENTIAL_MANAGER_GET_COUNT); + base::UmaHistogramEnumeration("PasswordManager.MediationRequired", + result); break; } }
diff --git a/components/password_manager/core/browser/password_manager_metrics_util.h b/components/password_manager/core/browser/password_manager_metrics_util.h index 42762a6..b4dbf4b3 100644 --- a/components/password_manager/core/browser/password_manager_metrics_util.h +++ b/components/password_manager/core/browser/password_manager_metrics_util.h
@@ -121,26 +121,27 @@ ACCOUNT_CHOOSER_ACTION_COUNT }; -enum CredentialManagerGetResult { +// Metrics: "PasswordManager.Mediation{Silent,Optional,Required}" +enum class CredentialManagerGetResult { // The promise is rejected. - CREDENTIAL_MANAGER_GET_REJECTED, + kRejected, // Auto sign-in is not allowed in the current context. - CREDENTIAL_MANAGER_GET_NONE_ZERO_CLICK_OFF, + kNoneZeroClickOff, // No matching credentials found. - CREDENTIAL_MANAGER_GET_NONE_EMPTY_STORE, + kNoneEmptyStore, // User mediation required due to > 1 matching credentials. - CREDENTIAL_MANAGER_GET_NONE_MANY_CREDENTIALS, + kNoneManyCredentials, // User mediation required due to the signed out state. - CREDENTIAL_MANAGER_GET_NONE_SIGNED_OUT, + kNoneSignedOut, // User mediation required due to pending first run experience dialog. - CREDENTIAL_MANAGER_GET_NONE_FIRST_RUN, + kNoneFirstRun, // Return empty credential for whatever reason. - CREDENTIAL_MANAGER_GET_NONE, + kNone, // Return a credential from the account chooser. - CREDENTIAL_MANAGER_GET_ACCOUNT_CHOOSER, + kAccountChooser, // User is auto signed in. - CREDENTIAL_MANAGER_GET_AUTOSIGNIN, - CREDENTIAL_MANAGER_GET_COUNT + kAutoSignIn, + kMaxValue = kAutoSignIn, }; // Metrics: "PasswordManager.HttpPasswordMigrationMode"
diff --git a/components/policy/tools/template_writers/policy_template_generator.py b/components/policy/tools/template_writers/policy_template_generator.py index bedb927..43f38b6 100755 --- a/components/policy/tools/template_writers/policy_template_generator.py +++ b/components/policy/tools/template_writers/policy_template_generator.py
@@ -22,12 +22,8 @@ def _ImportMessage(self, msg_txt): msg_txt = msg_txt.decode('utf-8') - # Replace the placeholder of app name. - msg_txt = msg_txt.replace('$1', self._config['app_name']) - msg_txt = msg_txt.replace('$2', self._config['os_name']) - msg_txt = msg_txt.replace('$3', self._config['frame_name']) - lines = msg_txt.split('\n') + # Strip any extra leading spaces, but keep useful indentation: min_leading_spaces = min(list(self._IterateLeadingSpaces(lines)) or [0]) if min_leading_spaces > 0:
diff --git a/components/policy/tools/template_writers/policy_template_generator_unittest.py b/components/policy/tools/template_writers/policy_template_generator_unittest.py index 9b5fd3e..b6570eb 100755 --- a/components/policy/tools/template_writers/policy_template_generator_unittest.py +++ b/components/policy/tools/template_writers/policy_template_generator_unittest.py
@@ -257,44 +257,6 @@ self.do_test(policy_defs_mock, LocalMockWriter()) - def testPolicyTexts(self): - # Test that GUI messages of policies all get placeholders replaced. - policy_data_mock = { - 'policy_definitions': [ - { - 'name': 'Group1', - 'type': 'group', - 'desc': '', - 'caption': '', - 'policies': ['Policy1'], - }, - { - 'name': 'Policy1', - 'caption': '1. app_name -- $1', - 'label': '2. os_name -- $2', - 'desc': '3. frame_name -- $3', - 'type': 'string', - 'supported_on': [] - }, - ] - } - - class LocalMockWriter(mock_writer.MockWriter): - - def WritePolicy(self, policy): - if policy['name'] == 'Policy1': - self.tester.assertEquals(policy['caption'], - '1. app_name -- _app_name') - self.tester.assertEquals(policy['label'], '2. os_name -- _os_name') - self.tester.assertEquals(policy['desc'], - '3. frame_name -- _frame_name') - elif policy['name'] == 'Group1': - pass - else: - self.tester.fail() - - self.do_test(policy_data_mock, LocalMockWriter()) - def testIntEnumTexts(self): # Test that GUI messages are assigned correctly to int-enums # (aka dropdown menus).
diff --git a/components/policy/tools/template_writers/writers/plist_strings_writer_unittest.py b/components/policy/tools/template_writers/writers/plist_strings_writer_unittest.py index 83bdf789..91c39f43 100755 --- a/components/policy/tools/template_writers/writers/plist_strings_writer_unittest.py +++ b/components/policy/tools/template_writers/writers/plist_strings_writer_unittest.py
@@ -26,7 +26,7 @@ 'placeholders': [], 'messages': { 'mac_chrome_preferences': { - 'text': '$1 preferen"ces', + 'text': 'Chromium preferen"ces', 'desc': 'blah' } } @@ -48,7 +48,7 @@ 'placeholders': [], 'messages': { 'mac_chrome_preferences': { - 'text': '$1 preferen"ces', + 'text': 'Chromium preferen"ces', 'desc': 'blah' } } @@ -88,7 +88,7 @@ 'placeholders': [], 'messages': { 'mac_chrome_preferences': { - 'text': 'Preferences of $1', + 'text': 'Preferences of Google Chrome', 'desc': 'blah' } } @@ -131,7 +131,7 @@ 'placeholders': [], 'messages': { 'mac_chrome_preferences': { - 'text': 'Preferences of $1', + 'text': 'Preferences of Chromium', 'desc': 'blah' } } @@ -176,7 +176,7 @@ 'placeholders': [], 'messages': { 'mac_chrome_preferences': { - 'text': 'Preferences of $1', + 'text': 'Preferences of Chromium', 'desc': 'blah' } } @@ -233,7 +233,7 @@ 'placeholders': [], 'messages': { 'mac_chrome_preferences': { - 'text': 'Preferences of $1', + 'text': 'Preferences of Chromium', 'desc': 'blah' } } @@ -286,7 +286,7 @@ 'placeholders': [], 'messages': { 'mac_chrome_preferences': { - 'text': '$1 preferences', + 'text': 'Google Chrome preferences', 'desc': 'blah' } } @@ -340,7 +340,7 @@ 'placeholders': [], 'messages': { 'mac_chrome_preferences': { - 'text': '$1 preferences', + 'text': 'Google Chrome preferences', 'desc': 'blah' } } @@ -383,7 +383,7 @@ 'placeholders': [], 'messages': { 'mac_chrome_preferences': { - 'text': '$1 preferences', + 'text': 'Google Chrome preferences', 'desc': 'blah' } }
diff --git a/components/signin/core/browser/fake_profile_oauth2_token_service.cc b/components/signin/core/browser/fake_profile_oauth2_token_service.cc index a38940a..e12ea46 100644 --- a/components/signin/core/browser/fake_profile_oauth2_token_service.cc +++ b/components/signin/core/browser/fake_profile_oauth2_token_service.cc
@@ -7,7 +7,6 @@ #include <memory> #include "google_apis/gaia/fake_oauth2_token_service_delegate.h" -#include "services/network/public/cpp/shared_url_loader_factory.h" FakeProfileOAuth2TokenService::FakeProfileOAuth2TokenService( PrefService* user_prefs) @@ -21,7 +20,6 @@ : ProfileOAuth2TokenService(user_prefs, std::move(delegate)) { OverrideAccessTokenManagerForTesting( std::make_unique<FakeOAuth2AccessTokenManager>( - this /* OAuth2TokenService* */, this /* OAuth2AccessTokenManager::Delegate* */)); } @@ -106,27 +104,6 @@ GetFakeAccessTokenManager()->CancelRequestsForAccount(account_id); } -void FakeProfileOAuth2TokenService::FetchOAuth2Token( - OAuth2AccessTokenManager::RequestImpl* request, - const CoreAccountId& account_id, - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - const std::string& client_id, - const std::string& client_secret, - const OAuth2AccessTokenManager::ScopeSet& scopes) { - GetFakeAccessTokenManager()->FetchOAuth2Token(request, account_id, - url_loader_factory, client_id, - client_secret, scopes); -} - -void FakeProfileOAuth2TokenService::InvalidateAccessTokenImpl( - const CoreAccountId& account_id, - const std::string& client_id, - const OAuth2AccessTokenManager::ScopeSet& scopes, - const std::string& access_token) { - GetFakeAccessTokenManager()->InvalidateAccessTokenImpl(account_id, client_id, - scopes, access_token); -} - FakeOAuth2AccessTokenManager* FakeProfileOAuth2TokenService::GetFakeAccessTokenManager() { return static_cast<FakeOAuth2AccessTokenManager*>(GetAccessTokenManager());
diff --git a/components/signin/core/browser/fake_profile_oauth2_token_service.h b/components/signin/core/browser/fake_profile_oauth2_token_service.h index 9208162..dd293a3 100644 --- a/components/signin/core/browser/fake_profile_oauth2_token_service.h +++ b/components/signin/core/browser/fake_profile_oauth2_token_service.h
@@ -13,10 +13,6 @@ #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "google_apis/gaia/fake_oauth2_access_token_manager.h" -namespace network { -class SharedURLLoaderFactory; -} - // Helper class to simplify writing unittests that depend on an instance of // ProfileOAuth2TokenService. // @@ -91,20 +87,6 @@ void CancelRequestsForAccount(const CoreAccountId& account_id) override; - void FetchOAuth2Token( - OAuth2AccessTokenManager::RequestImpl* request, - const CoreAccountId& account_id, - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - const std::string& client_id, - const std::string& client_secret, - const OAuth2AccessTokenManager::ScopeSet& scopes) override; - - void InvalidateAccessTokenImpl( - const CoreAccountId& account_id, - const std::string& client_id, - const OAuth2AccessTokenManager::ScopeSet& scopes, - const std::string& access_token) override; - private: FakeOAuth2AccessTokenManager* GetFakeAccessTokenManager();
diff --git a/components/signin/ios/browser/device_accounts_provider.h b/components/signin/ios/browser/device_accounts_provider.h index 522ee3f..6f50089 100644 --- a/components/signin/ios/browser/device_accounts_provider.h +++ b/components/signin/ios/browser/device_accounts_provider.h
@@ -45,6 +45,7 @@ struct AccountInfo { std::string gaia; std::string email; + std::string hosted_domain; }; using AccessTokenCallback = base::OnceCallback<
diff --git a/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.mm b/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.mm index f53294b..c85ae58 100644 --- a/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.mm +++ b/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.mm
@@ -70,6 +70,16 @@ } } +// Converts a DeviceAccountsProvider::AccountInfo to an AccountInfo. +AccountInfo AccountInfoFromDeviceAccount( + const DeviceAccountsProvider::AccountInfo& account) { + AccountInfo account_info; + account_info.email = account.email; + account_info.gaia = account.gaia; + account_info.hosted_domain = account.hosted_domain; + return account_info; +} + class SSOAccessTokenFetcher : public OAuth2AccessTokenFetcher { public: SSOAccessTokenFetcher(OAuth2AccessTokenConsumer* consumer, @@ -206,7 +216,7 @@ // a fetch access token operation when it receives a // |OnRefreshTokenAvailable| notification. std::string account_id = account_tracker_service_->SeedAccountInfo( - new_account.gaia, new_account.email); + AccountInfoFromDeviceAccount(new_account)); new_account_ids.insert(account_id); }
diff --git a/components/signin/public/identity_manager/identity_manager_builder.h b/components/signin/public/identity_manager/identity_manager_builder.h index c5792e0..2c42442 100644 --- a/components/signin/public/identity_manager/identity_manager_builder.h +++ b/components/signin/public/identity_manager/identity_manager_builder.h
@@ -16,6 +16,10 @@ class ImageDecoder; } +namespace network { +class NetworkConnectionTracker; +} + namespace signin { enum class AccountConsistencyMethod; } @@ -31,6 +35,7 @@ std::unique_ptr<AccountTrackerService> account_tracker_service; std::unique_ptr<image_fetcher::ImageDecoder> image_decoder; PrefService* local_state; + network::NetworkConnectionTracker* network_connection_tracker; PrefService* pref_service; SigninClient* signin_client; std::unique_ptr<ProfileOAuth2TokenService> token_service;
diff --git a/components/signin/public/identity_manager/identity_manager_unittest.cc b/components/signin/public/identity_manager/identity_manager_unittest.cc index b13fe55e..560ceef 100644 --- a/components/signin/public/identity_manager/identity_manager_unittest.cc +++ b/components/signin/public/identity_manager/identity_manager_unittest.cc
@@ -75,9 +75,8 @@ class CustomFakeOAuth2AccessTokenManager : public FakeOAuth2AccessTokenManager { public: CustomFakeOAuth2AccessTokenManager( - OAuth2TokenService* token_service, OAuth2AccessTokenManager::Delegate* delegate) - : FakeOAuth2AccessTokenManager(token_service, delegate) {} + : FakeOAuth2AccessTokenManager(delegate) {} void set_on_access_token_invalidated_info( CoreAccountId expected_account_id_to_invalidate, @@ -125,7 +124,6 @@ : FakeProfileOAuth2TokenService(user_prefs) { OverrideAccessTokenManagerForTesting( std::make_unique<CustomFakeOAuth2AccessTokenManager>( - this /* OAuth2TokenService* */, this /* OAuth2AccessTokenManager::Delegate* */)); } @@ -140,15 +138,6 @@ } private: - // OAuth2TokenService: - void InvalidateAccessTokenImpl(const CoreAccountId& account_id, - const std::string& client_id, - const ScopeSet& scopes, - const std::string& access_token) override { - GetCustomAccessTokenManager()->InvalidateAccessTokenImpl( - account_id, client_id, scopes, access_token); - } - CustomFakeOAuth2AccessTokenManager* GetCustomAccessTokenManager() { return static_cast<CustomFakeOAuth2AccessTokenManager*>( GetAccessTokenManager());
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 5b00710..c7b8d05 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -2082,6 +2082,10 @@ defines += [ "ENABLE_PROTECTED_MEDIA_IDENTIFIER_PERMISSION" ] } + if (is_chromecast) { + defines += [ "IS_CHROMECAST" ] + } + if (is_chromecast && is_linux) { sources += [ "tracing/cast_tracing_agent.cc",
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc index b34fbbdc..544c0eca 100644 --- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -1946,6 +1946,11 @@ RunHtmlTest(FILE_PATH_LITERAL("video.html")); } +IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, + AccessibilityNodeChangedCrashInEditableText) { + RunHtmlTest(FILE_PATH_LITERAL("node-changed-crash-in-editable-text.html")); +} + // TODO(crbug.com/916003): Fix race condition. IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, DISABLED_AccessibilityNoSourceVideo) {
diff --git a/content/browser/frame_host/navigation_controller_impl_unittest.cc b/content/browser/frame_host/navigation_controller_impl_unittest.cc index f6de22c..3b44a73 100644 --- a/content/browser/frame_host/navigation_controller_impl_unittest.cc +++ b/content/browser/frame_host/navigation_controller_impl_unittest.cc
@@ -1046,9 +1046,10 @@ EXPECT_EQ(kExistingURL1, controller.GetVisibleEntry()->GetURL()); } -// Tests an ignored navigation when there is a pending new navigation. -// This will happen if the user enters a URL, but before that commits, the -// current blank page reloads. See http://crbug.com/77507. +// Verify that a direct commit message from the renderer properly cancels a +// pending new navigation. This will happen if the user enters a URL, but +// before that commits, the current blank page reloads. +// Original bug: http://crbug.com/77507. TEST_F(NavigationControllerTest, LoadURL_IgnorePreemptsPending) { NavigationControllerImpl& controller = controller_impl(); @@ -1063,8 +1064,9 @@ // Now make a pending new navigation. const GURL kNewURL("http://eh"); - controller.LoadURL( - kNewURL, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + auto navigation = + NavigationSimulator::CreateBrowserInitiated(kNewURL, contents()); + navigation->Start(); EXPECT_EQ(0U, navigation_entry_changed_counter_); EXPECT_EQ(0U, navigation_list_pruned_counter_); EXPECT_EQ(-1, controller.GetPendingEntryIndex()); @@ -1072,10 +1074,8 @@ EXPECT_EQ(-1, controller.GetLastCommittedEntryIndex()); EXPECT_EQ(1, delegate->navigation_state_change_count()); - // Before that commits, a document.write and location.reload can cause the - // renderer to send a FrameNavigate with nav_entry_id 0. - // PlzNavigate: this will stop the old navigation and start a new one. - main_test_rfh()->SendRendererInitiatedNavigationRequest(kExistingURL, true); + // Certain rare cases can make a direct DidCommitProvisionalLoad call without + // going to the browser. Renderer reload of an about:blank is such a case. main_test_rfh()->SendNavigate(0, false, kExistingURL); // This should clear the pending entry and notify of a navigation state
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 7437f47..ee3bf9e 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -236,9 +236,9 @@ // The next value to use for the accessibility reset token. int g_next_accessibility_reset_token = 1; -#if defined(OS_ANDROID) || defined(OS_FUCHSIA) +#if defined(OS_ANDROID) || defined(OS_FUCHSIA) || defined(IS_CHROMECAST) // Whether to allow injecting javascript into any kind of frame, for Android -// WebView and Fuchsia web.ContextProvider. +// WebView, Fuchsia web.ContextProvider and CastOS content shell. bool g_allow_injecting_javascript = false; #endif @@ -781,12 +781,12 @@ return RenderFrameHostImpl::FromID(render_process_id, render_frame_id); } -#if defined(OS_ANDROID) || defined(OS_FUCHSIA) +#if defined(OS_ANDROID) || defined(OS_FUCHSIA) || defined(IS_CHROMECAST) // static void RenderFrameHost::AllowInjectingJavaScript() { g_allow_injecting_javascript = true; } -#endif // defined(OS_ANDROID) || defined(OS_FUCHSIA) +#endif // defined(OS_ANDROID) || defined(OS_FUCHSIA) || defined(IS_CHROMECAST) // static RenderFrameHostImpl* RenderFrameHostImpl::FromID(int process_id, @@ -5796,7 +5796,7 @@ } bool RenderFrameHostImpl::CanExecuteJavaScript() { -#if defined(OS_ANDROID) || defined(OS_FUCHSIA) +#if defined(OS_ANDROID) || defined(OS_FUCHSIA) || defined(IS_CHROMECAST) if (g_allow_injecting_javascript) return true; #endif
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h index b9bf9cc..32e3064 100644 --- a/content/browser/service_worker/service_worker_version.h +++ b/content/browser/service_worker/service_worker_version.h
@@ -860,11 +860,6 @@ mojo::AssociatedBinding<blink::mojom::ServiceWorkerHost> binding_; - // The number of fetch event responses that the service worker is streaming to - // the browser process. We try to not stop the service worker while there is - // an inflight response. - int inflight_stream_response_count_ = 0; - // Set to true if the worker has no inflight events and the idle timer has // been triggered. Set back to false if another event starts since the worker // is no longer idle.
diff --git a/content/browser/worker_host/worker_script_fetch_initiator.cc b/content/browser/worker_host/worker_script_fetch_initiator.cc index ed3c851f..21d0df1 100644 --- a/content/browser/worker_host/worker_script_fetch_initiator.cc +++ b/content/browser/worker_host/worker_script_fetch_initiator.cc
@@ -364,7 +364,9 @@ // Get the direct network factory from |loader_factory_getter|. When // NetworkService is enabled, it returns a factory that doesn't support // reconnection to the network service after a crash, but it's OK since - // it's used for a single shared worker startup. + // it's used only for a single request to fetch the worker's main script + // during startup. If the network service crashes, worker startup should + // simply fail. network::mojom::URLLoaderFactoryPtr network_factory_ptr; loader_factory_getter->CloneNetworkFactory( mojo::MakeRequest(&network_factory_ptr)); @@ -390,16 +392,20 @@ &ServiceWorkerContextWrapper::resource_context, service_worker_context); // NetworkService (PlzWorker): - // Start loading a shared worker main script. + // Start loading a web worker main script. if (base::FeatureList::IsEnabled(network::features::kNetworkService)) { // TODO(nhiroki): Figure out what we should do in |wc_getter| for loading - // shared worker's main script. + // web worker's main script. Returning the WebContents of the closest + // ancestor's frame is a possible option, but it doesn't work when a shared + // worker creates a dedicated worker after the closest ancestor's frame is + // gone. The frame tree node ID has the same issue. base::RepeatingCallback<WebContents*()> wc_getter = base::BindRepeating([]() -> WebContents* { return nullptr; }); std::vector<std::unique_ptr<URLLoaderThrottle>> throttles = GetContentClient()->browser()->CreateURLLoaderThrottlesOnIO( *resource_request, resource_context, wc_getter, - nullptr /* navigation_ui_data */, -1 /* frame_tree_node_id */); + nullptr /* navigation_ui_data */, + RenderFrameHost::kNoFrameTreeNodeId); WorkerScriptFetcher::CreateAndStart( std::make_unique<WorkerScriptLoaderFactory>( @@ -454,8 +460,8 @@ // NetworkService (PlzWorker): // Prepare the controller service worker info to pass to the renderer. This is // only provided if NetworkService is enabled. In the non-NetworkService case, - // the controller is sent in SetController IPCs during the request for the - // shared worker script. + // the controller is sent in SetController IPCs during the request for the web + // worker script. blink::mojom::ControllerServiceWorkerInfoPtr controller; base::WeakPtr<ServiceWorkerObjectHost> controller_service_worker_object_host; if (subresource_loader_params &&
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index b422bbf7..62f34c7 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -1158,8 +1158,17 @@ // Returns the RapporService from the browser process. virtual ::rappor::RapporService* GetRapporService(); - // Allows the embedder to register one or more URLLoaderThrottles for a - // navigation request. + // Allows the embedder to register one or more URLLoaderThrottles for one of + // the following requests: + // 1) A navigation request. + // 2) A request for a dedicated worker's main script (when PlzDedicatedWorker + // is enabled). + // 3) A request for a shared worker's main script. + // + // For a request for worker's main script, |wc_getter|, |navigation_ui_data|, + // and |frame_tree_node_id| take a callback returning a nullptr, nullptr, and + // RenderFrameHost::kNoFrameTreeNodeId respectively. + // // This is called both when the network service is enabled and disabled. // This is called on the IO thread. virtual std::vector<std::unique_ptr<URLLoaderThrottle>>
diff --git a/content/public/browser/render_frame_host.h b/content/public/browser/render_frame_host.h index 6e92678d..36149b2 100644 --- a/content/public/browser/render_frame_host.h +++ b/content/public/browser/render_frame_host.h
@@ -74,10 +74,10 @@ // Returns nullptr if the IDs do not correspond to a live RenderFrameHost. static RenderFrameHost* FromID(int render_process_id, int render_frame_id); -#if defined(OS_ANDROID) || defined(OS_FUCHSIA) +#if defined(OS_ANDROID) || defined(OS_FUCHSIA) || defined(IS_CHROMECAST) // Globally allows for injecting JavaScript into the main world. This feature - // is present only to support Android WebView and Fuchsia web.Contexts, and - // must not be used in other configurations. + // is present only to support Android WebView, Fuchsia web.Contexts, and + // CastOS content shell. It must not be used in other configurations. static void AllowInjectingJavaScript(); #endif
diff --git a/content/public/renderer/BUILD.gn b/content/public/renderer/BUILD.gn index 1cdc546b..3adfa9b 100644 --- a/content/public/renderer/BUILD.gn +++ b/content/public/renderer/BUILD.gn
@@ -30,7 +30,6 @@ visibility = [ "//content/*" ] sources = [ - "associated_resource_fetcher.h", "browser_plugin_delegate.cc", "browser_plugin_delegate.h", "chrome_object_extensions_utils.cc",
diff --git a/content/public/renderer/associated_resource_fetcher.h b/content/public/renderer/associated_resource_fetcher.h deleted file mode 100644 index a7da31c..0000000 --- a/content/public/renderer/associated_resource_fetcher.h +++ /dev/null
@@ -1,73 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_PUBLIC_RENDERER_ASSOCIATED_RESOURCE_FETCHER_H_ -#define CONTENT_PUBLIC_RENDERER_ASSOCIATED_RESOURCE_FETCHER_H_ - -#include <string> - -#include "base/callback.h" -#include "content/common/content_export.h" -#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h" -#include "third_party/blink/public/platform/web_url_request.h" - -class GURL; - -namespace blink { -class WebLocalFrame; -class WebURLResponse; -struct WebAssociatedURLLoaderOptions; -} - -namespace content { - -// Interface to download resources asynchronously. -class CONTENT_EXPORT AssociatedResourceFetcher { - public: - virtual ~AssociatedResourceFetcher() {} - - // This will be called asynchronously after the URL has been fetched, - // successfully or not. If there is a failure, response and data will both be - // empty. |response| and |data| are both valid until the URLFetcher instance - // is destroyed. - using StartCallback = - base::OnceCallback<void(const blink::WebURLResponse& response, - const std::string& data)>; - - // Creates a AssociatedResourceFetcher for the specified resource. Caller - // takes - // ownership of the returned object. Deleting the AssociatedResourceFetcher - // will cancel - // the request, and the callback will never be run. - static AssociatedResourceFetcher* Create(const GURL& url); - - virtual void SetSkipServiceWorker(bool skip_service_worker) = 0; - virtual void SetCacheMode(blink::mojom::FetchCacheMode mode) = 0; - - // Associate the corresponding WebURLLoaderOptions to the loader. Must be - // called before Start. Used if the LoaderType is FRAME_ASSOCIATED_LOADER. - virtual void SetLoaderOptions( - const blink::WebAssociatedURLLoaderOptions& options) = 0; - - // Starts the request using the specified frame. Calls |callback| when - // done. - // - // |fetch_request_mode| is the mode to use. See - // https://fetch.spec.whatwg.org/#concept-request-mode. - // - // |fetch_credentials_mode| is the credentials mode to use. See - // https://fetch.spec.whatwg.org/#concept-request-credentials-mode - virtual void Start(blink::WebLocalFrame* frame, - blink::mojom::RequestContextType request_context, - network::mojom::RequestMode request_mode, - network::mojom::CredentialsMode credentials_mode, - StartCallback callback) = 0; - - // Manually cancel the request. - virtual void Cancel() = 0; -}; - -} // namespace content - -#endif // CONTENT_PUBLIC_RENDERER_ASSOCIATED_RESOURCE_FETCHER_H_
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index 9125eae..15d4d297 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -206,8 +206,6 @@ "media/stream/apply_constraints_processor.h", "media/stream/audio_service_audio_processor_proxy.cc", "media/stream/audio_service_audio_processor_proxy.h", - "media/stream/local_media_stream_audio_source.cc", - "media/stream/local_media_stream_audio_source.h", "media/stream/media_stream_audio_processor.cc", "media/stream/media_stream_audio_processor.h", "media/stream/media_stream_center.cc",
diff --git a/content/renderer/fetchers/associated_resource_fetcher_impl.cc b/content/renderer/fetchers/associated_resource_fetcher_impl.cc index 0a53fe13..98eb954 100644 --- a/content/renderer/fetchers/associated_resource_fetcher_impl.cc +++ b/content/renderer/fetchers/associated_resource_fetcher_impl.cc
@@ -14,8 +14,6 @@ #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_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/web/blink.h" #include "third_party/blink/public/web/web_associated_url_loader.h" #include "third_party/blink/public/web/web_associated_url_loader_client.h" @@ -26,7 +24,8 @@ namespace content { // static -AssociatedResourceFetcher* AssociatedResourceFetcher::Create(const GURL& url) { +AssociatedResourceFetcherImpl* AssociatedResourceFetcherImpl::Create( + const GURL& url) { return new AssociatedResourceFetcherImpl(url); }
diff --git a/content/renderer/fetchers/associated_resource_fetcher_impl.h b/content/renderer/fetchers/associated_resource_fetcher_impl.h index d7846a7b..31b6eea 100644 --- a/content/renderer/fetchers/associated_resource_fetcher_impl.h +++ b/content/renderer/fetchers/associated_resource_fetcher_impl.h
@@ -11,8 +11,9 @@ #include "base/callback.h" #include "base/compiler_specific.h" #include "base/macros.h" -#include "content/public/renderer/associated_resource_fetcher.h" +#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.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/web/web_associated_url_loader_options.h" class GURL; @@ -24,30 +25,54 @@ namespace content { -class AssociatedResourceFetcherImpl : public AssociatedResourceFetcher { +// Interface to download resources asynchronously. +class AssociatedResourceFetcherImpl { public: - // AssociatedResourceFetcher implementation: - void SetSkipServiceWorker(bool skip_service_worker) override; - void SetCacheMode(blink::mojom::FetchCacheMode mode) override; - void SetLoaderOptions( - const blink::WebAssociatedURLLoaderOptions& options) override; + // This will be called asynchronously after the URL has been fetched, + // successfully or not. If there is a failure, response and data will both be + // empty. |response| and |data| are both valid until the URLFetcher instance + // is destroyed. + using StartCallback = + base::OnceCallback<void(const blink::WebURLResponse& response, + const std::string& data)>; + + // Creates a AssociatedResourceFetcherImpl for the specified resource. + // Caller takes ownership of the returned object. + // Deleting the AssociatedResourceFetcherImpl will cancel + // the request, and the callback will never be run. + static AssociatedResourceFetcherImpl* Create(const GURL& url); + + ~AssociatedResourceFetcherImpl(); + + void SetSkipServiceWorker(bool skip_service_worker); + void SetCacheMode(blink::mojom::FetchCacheMode mode); + + // Associate the corresponding WebURLLoaderOptions to the loader. Must be + // called before Start. Used if the LoaderType is FRAME_ASSOCIATED_LOADER. + void SetLoaderOptions(const blink::WebAssociatedURLLoaderOptions& options); + + // Starts the request using the specified frame. Calls |callback| when + // done. + // + // |fetch_request_mode| is the mode to use. See + // https://fetch.spec.whatwg.org/#concept-request-mode. + // + // |fetch_credentials_mode| is the credentials mode to use. See + // https://fetch.spec.whatwg.org/#concept-request-credentials-mode void Start(blink::WebLocalFrame* frame, blink::mojom::RequestContextType request_context, network::mojom::RequestMode request_mode, network::mojom::CredentialsMode credentials_mode, - StartCallback callback) override; + StartCallback callback); + + // Manually cancel the request. + void Cancel(); private: - friend class AssociatedResourceFetcher; - class ClientImpl; explicit AssociatedResourceFetcherImpl(const GURL& url); - ~AssociatedResourceFetcherImpl() override; - - void Cancel() override; - std::unique_ptr<blink::WebAssociatedURLLoader> loader_; std::unique_ptr<ClientImpl> client_;
diff --git a/content/renderer/fetchers/multi_resolution_image_resource_fetcher.cc b/content/renderer/fetchers/multi_resolution_image_resource_fetcher.cc index 7cefd22b..110006d 100644 --- a/content/renderer/fetchers/multi_resolution_image_resource_fetcher.cc +++ b/content/renderer/fetchers/multi_resolution_image_resource_fetcher.cc
@@ -9,7 +9,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "content/child/image_decoder.h" -#include "content/public/renderer/associated_resource_fetcher.h" +#include "content/renderer/fetchers/associated_resource_fetcher_impl.h" #include "third_party/blink/public/platform/web_security_origin.h" #include "third_party/blink/public/platform/web_url_response.h" #include "third_party/blink/public/web/web_associated_url_loader_options.h" @@ -36,7 +36,7 @@ id_(id), http_status_code_(0), image_url_(image_url) { - fetcher_.reset(AssociatedResourceFetcher::Create(image_url)); + fetcher_.reset(AssociatedResourceFetcherImpl::Create(image_url)); WebAssociatedURLLoaderOptions options; fetcher_->SetLoaderOptions(options);
diff --git a/content/renderer/fetchers/multi_resolution_image_resource_fetcher.h b/content/renderer/fetchers/multi_resolution_image_resource_fetcher.h index d72a651..8436f24 100644 --- a/content/renderer/fetchers/multi_resolution_image_resource_fetcher.h +++ b/content/renderer/fetchers/multi_resolution_image_resource_fetcher.h
@@ -24,7 +24,7 @@ namespace content { -class AssociatedResourceFetcher; +class AssociatedResourceFetcherImpl; // A resource fetcher that returns all (differently-sized) frames in // an image. Useful for favicons. @@ -72,7 +72,7 @@ const GURL image_url_; // Does the actual download. - std::unique_ptr<AssociatedResourceFetcher> fetcher_; + std::unique_ptr<AssociatedResourceFetcherImpl> fetcher_; DISALLOW_COPY_AND_ASSIGN(MultiResolutionImageResourceFetcher); };
diff --git a/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc b/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc index 235d2a3..5e7bd43 100644 --- a/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc +++ b/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc
@@ -14,7 +14,6 @@ #include "base/test/scoped_feature_list.h" #include "base/test/scoped_task_environment.h" #include "build/build_config.h" -#include "content/renderer/media/stream/local_media_stream_audio_source.h" #include "content/renderer/media/stream/processed_local_audio_source.h" #include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h" #include "media/base/audio_parameters.h" @@ -25,6 +24,7 @@ #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" #include "third_party/blink/public/platform/web_media_constraints.h" #include "third_party/blink/public/platform/web_string.h" +#include "third_party/blink/public/web/modules/mediastream/local_media_stream_audio_source.h" #include "third_party/blink/public/web/modules/mediastream/mock_constraint_factory.h" namespace content { @@ -126,7 +126,8 @@ media::AudioParameters::PlatformEffectsMask::NO_EFFECTS); } - std::unique_ptr<LocalMediaStreamAudioSource> GetLocalMediaStreamAudioSource( + std::unique_ptr<blink::LocalMediaStreamAudioSource> + GetLocalMediaStreamAudioSource( bool enable_system_echo_canceller, bool disable_local_echo, bool render_to_associated_sink, @@ -145,8 +146,9 @@ if (render_to_associated_sink) device.matched_output_device_id = std::string("some_device_id"); - return std::make_unique<LocalMediaStreamAudioSource>( - -1, device, requested_buffer_size, disable_local_echo, + return std::make_unique<blink::LocalMediaStreamAudioSource>( + /*blink::WebLocalFrame=*/nullptr, device, requested_buffer_size, + disable_local_echo, blink::WebPlatformMediaStreamSource::ConstraintsCallback(), blink::scheduler::GetSingleThreadTaskRunnerForTesting()); } @@ -391,7 +393,7 @@ auto result = SelectSettings(); EXPECT_TRUE(result.HasValue()); - std::unique_ptr<LocalMediaStreamAudioSource> local_source = + std::unique_ptr<blink::LocalMediaStreamAudioSource> local_source = GetLocalMediaStreamAudioSource( false /* enable_system_echo_canceller */, false /* disable_local_echo */, @@ -770,7 +772,7 @@ if (!IsDeviceCapture()) return; - std::unique_ptr<LocalMediaStreamAudioSource> source = + std::unique_ptr<blink::LocalMediaStreamAudioSource> source = GetLocalMediaStreamAudioSource(false /* enable_system_echo_canceller */, false /* disable_local_echo */, false /* render_to_associated_sink */); @@ -887,7 +889,7 @@ if (!IsDeviceCapture()) return; - std::unique_ptr<LocalMediaStreamAudioSource> source = + std::unique_ptr<blink::LocalMediaStreamAudioSource> source = GetLocalMediaStreamAudioSource(false /* enable_system_echo_canceller */, false /* disable_local_echo */, false /* render_to_associated_sink */); @@ -1044,7 +1046,7 @@ if (!IsDeviceCapture()) return; - std::unique_ptr<LocalMediaStreamAudioSource> source = + std::unique_ptr<blink::LocalMediaStreamAudioSource> source = GetLocalMediaStreamAudioSource(false /* enable_system_echo_canceller */, false /* disable_local_echo */, false /* render_to_associated_sink */); @@ -1559,7 +1561,7 @@ // sources that have no audio processing. TEST_P(MediaStreamConstraintsUtilAudioTest, SourceWithNoAudioProcessing) { for (bool enable_properties : {true, false}) { - std::unique_ptr<LocalMediaStreamAudioSource> source = + std::unique_ptr<blink::LocalMediaStreamAudioSource> source = GetLocalMediaStreamAudioSource( enable_properties /* enable_system_echo_canceller */, enable_properties /* disable_local_echo */, @@ -1827,7 +1829,7 @@ } TEST_P(MediaStreamConstraintsUtilAudioTest, ExperimetanlEcWithSource) { - std::unique_ptr<LocalMediaStreamAudioSource> source = + std::unique_ptr<blink::LocalMediaStreamAudioSource> source = GetLocalMediaStreamAudioSource( false /* enable_system_echo_canceller */, false /* disable_local_echo */, false /* render_to_associated_sink */,
diff --git a/content/renderer/media/stream/user_media_processor.cc b/content/renderer/media/stream/user_media_processor.cc index c7543bfb..ff76e6f 100644 --- a/content/renderer/media/stream/user_media_processor.cc +++ b/content/renderer/media/stream/user_media_processor.cc
@@ -19,7 +19,6 @@ #include "base/task_runner.h" #include "base/task_runner_util.h" #include "base/threading/thread_task_runner_handle.h" -#include "content/renderer/media/stream/local_media_stream_audio_source.h" #include "content/renderer/media/stream/media_stream_audio_processor.h" #include "content/renderer/media/stream/media_stream_constraints_util_audio.h" #include "content/renderer/media/stream/media_stream_device_observer.h" @@ -42,6 +41,7 @@ #include "third_party/blink/public/platform/web_media_stream_source.h" #include "third_party/blink/public/platform/web_media_stream_track.h" #include "third_party/blink/public/platform/web_string.h" +#include "third_party/blink/public/web/modules/mediastream/local_media_stream_audio_source.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_video_content.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_video_device.h" @@ -1052,8 +1052,8 @@ if (blink::IsScreenCaptureMediaType(device.type) || !MediaStreamAudioProcessor::WouldModifyAudio( audio_processing_properties)) { - return std::make_unique<LocalMediaStreamAudioSource>( - render_frame_->GetRoutingID(), device, + return std::make_unique<blink::LocalMediaStreamAudioSource>( + render_frame_->GetWebFrame(), device, base::OptionalOrNullptr(current_request_info_->audio_capture_settings() .requested_buffer_size()), stream_controls->disable_local_echo, std::move(source_ready),
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc index e722b08..461008f4 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -533,6 +533,16 @@ //------------------------------------------------------------------------------ +scoped_refptr<media::AudioCapturerSource> +RendererBlinkPlatformImpl::NewAudioCapturerSource( + blink::WebLocalFrame* web_frame, + const media::AudioSourceParameters& params) { + return AudioDeviceFactory::NewAudioCapturerSource( + RenderFrame::GetRoutingIdForWebFrame(web_frame), params); +} + +//------------------------------------------------------------------------------ + std::unique_ptr<WebRTCPeerConnectionHandler> RendererBlinkPlatformImpl::CreateRTCPeerConnectionHandler( WebRTCPeerConnectionHandlerClient* client,
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h index 07344fa3..0fbb6ee6 100644 --- a/content/renderer/renderer_blink_platform_impl.h +++ b/content/renderer/renderer_blink_platform_impl.h
@@ -124,6 +124,9 @@ size_t data_size) override; blink::WebBlobRegistry* GetBlobRegistry() override; + scoped_refptr<media::AudioCapturerSource> NewAudioCapturerSource( + blink::WebLocalFrame* web_frame, + const media::AudioSourceParameters& params) override; std::unique_ptr<blink::WebRTCPeerConnectionHandler> CreateRTCPeerConnectionHandler( blink::WebRTCPeerConnectionHandlerClient* client,
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 02c9ea1..7821e7e 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1875,7 +1875,6 @@ "../renderer/media/render_media_log_unittest.cc", "../renderer/media/renderer_webaudiodevice_impl_unittest.cc", "../renderer/media/stream/media_stream_audio_processor_unittest.cc", - "../renderer/media/stream/media_stream_audio_unittest.cc", "../renderer/media/stream/media_stream_constraints_util_audio_unittest.cc", "../renderer/media/stream/media_stream_device_observer_unittest.cc", "../renderer/media/stream/media_stream_video_source_unittest.cc", @@ -1990,8 +1989,8 @@ "//content/browser/background_fetch:background_fetch_proto", "//content/browser/cache_storage:cache_storage_proto", "//content/browser/devtools:devtools_background_services_proto", - "//content/browser/devtools:inspector_protocol_encoding_test", "//content/browser/devtools:inspector_protocol_bindings_test", + "//content/browser/devtools:inspector_protocol_encoding_test", "//content/browser/dom_storage:local_storage_proto", "//content/browser/indexed_db/scopes:scopes_metadata_proto", "//content/browser/notifications:notification_proto",
diff --git a/content/test/data/accessibility/html/node-changed-crash-in-editable-text-expected-android.txt b/content/test/data/accessibility/html/node-changed-crash-in-editable-text-expected-android.txt new file mode 100644 index 0000000..a18eaf4 --- /dev/null +++ b/content/test/data/accessibility/html/node-changed-crash-in-editable-text-expected-android.txt
@@ -0,0 +1,6 @@ +android.webkit.WebView focusable focused scrollable +++android.widget.EditText clickable editable_text focusable multiline hint='Done' +++++android.view.View +++++android.view.View +++++++android.view.View +++++android.view.View \ No newline at end of file
diff --git a/content/test/data/accessibility/html/node-changed-crash-in-editable-text-expected-auralinux.txt b/content/test/data/accessibility/html/node-changed-crash-in-editable-text-expected-auralinux.txt new file mode 100644 index 0000000..5971b57 --- /dev/null +++ b/content/test/data/accessibility/html/node-changed-crash-in-editable-text-expected-auralinux.txt
@@ -0,0 +1,6 @@ +[document web] +++[section] name='Done' selectable-text +++++[section] +++++[section] +++++++[section] +++++[section] \ No newline at end of file
diff --git a/content/test/data/accessibility/html/node-changed-crash-in-editable-text-expected-blink.txt b/content/test/data/accessibility/html/node-changed-crash-in-editable-text-expected-blink.txt new file mode 100644 index 0000000..12a7d67 --- /dev/null +++ b/content/test/data/accessibility/html/node-changed-crash-in-editable-text-expected-blink.txt
@@ -0,0 +1,4 @@ +rootWebArea +++genericContainer multiline name='Done' +++++genericContainer +++++genericContainer
diff --git a/content/test/data/accessibility/html/node-changed-crash-in-editable-text-expected-mac.txt b/content/test/data/accessibility/html/node-changed-crash-in-editable-text-expected-mac.txt new file mode 100644 index 0000000..0adbb83 --- /dev/null +++ b/content/test/data/accessibility/html/node-changed-crash-in-editable-text-expected-mac.txt
@@ -0,0 +1,6 @@ +AXWebArea +++AXTextArea AXDescription='Done' +++++AXGroup +++++AXGroup +++++++AXGroup +++++AXGroup \ No newline at end of file
diff --git a/content/test/data/accessibility/html/node-changed-crash-in-editable-text-expected-uia-win.txt b/content/test/data/accessibility/html/node-changed-crash-in-editable-text-expected-uia-win.txt new file mode 100644 index 0000000..10ae582 --- /dev/null +++ b/content/test/data/accessibility/html/node-changed-crash-in-editable-text-expected-uia-win.txt
@@ -0,0 +1,4 @@ +document +++group Name='Done' +++++group +++++group
diff --git a/content/test/data/accessibility/html/node-changed-crash-in-editable-text-expected-win.txt b/content/test/data/accessibility/html/node-changed-crash-in-editable-text-expected-win.txt new file mode 100644 index 0000000..d0eaeac --- /dev/null +++ b/content/test/data/accessibility/html/node-changed-crash-in-editable-text-expected-win.txt
@@ -0,0 +1,4 @@ +ROLE_SYSTEM_DOCUMENT FOCUSABLE +++IA2_ROLE_SECTION name='Done' FOCUSABLE IA2_STATE_MULTI_LINE +++++IA2_ROLE_SECTION +++++IA2_ROLE_SECTION
diff --git a/content/test/data/accessibility/html/node-changed-crash-in-editable-text.html b/content/test/data/accessibility/html/node-changed-crash-in-editable-text.html new file mode 100644 index 0000000..e662b0a7 --- /dev/null +++ b/content/test/data/accessibility/html/node-changed-crash-in-editable-text.html
@@ -0,0 +1,41 @@ +<!-- +@WAIT-FOR:Done +@NO_CHILDREN_DUMP +This is a regression test for a bug that caused a crash when a node inside +editable text was modified and had a sibling removed in the same update. The +actual test output is not interesting, all that matters is that it correctly +waits for "Done" to appear in the accessibility tree and doesn't generate an +invalid tree update in the process. +--> +<script> + function go() { + + // To reproduce the testcase we need to dirty an element and cause its + // parent (who is observing OnNodeChanged) to have an incorrect cached child + // count. This needs to be done in a single ax_tree update. + + // dirty child, this needs to be sent in the same update as the node removal + document.getElementById('child').setAttribute("max", "bar"); + document.getElementById('child').removeChild(document.getElementById('grandChild')); + + // "remove" element. Deleting the element using removeChild doesn't create + // the same failing update pattern + document.getElementById('to-be-removed').outerText = ""; + + // This needs to be in a seperate update, test only, not related to regression + setTimeout(() => { + document.body.setAttribute("aria-label", "Done"); + }, 20); + } +</script> + +<body onload="go();" contentEditable="true" aria-label="@NO_CHILDREN_DUMP"> + <div id='to-be-removed'></div> + <div id='child' aria-hidden="false"> + <div id='grandChild' aria-hidden="false"></div> + </div> + + <div aria-hidden="false"> + <!-- <audio src='foo'></audio> --> + </div> +</body> \ No newline at end of file
diff --git a/docs/linux_build_instructions.md b/docs/linux_build_instructions.md index cdbcc1f..831f362a 100644 --- a/docs/linux_build_instructions.md +++ b/docs/linux_build_instructions.md
@@ -17,7 +17,7 @@ * At least 100GB of free disk space. * You must have Git and Python v2 installed already. -Most development is done on Ubuntu (currently 14.04, Trusty Tahr). There are +Most development is done on Ubuntu (currently 16.04, Xenial Xerus). There are some instructions for other distros below, but they are mostly unsupported. ## Install `depot_tools`
diff --git a/docs/windows_build_instructions.md b/docs/windows_build_instructions.md index f7741e62..3490c0a 100644 --- a/docs/windows_build_instructions.md +++ b/docs/windows_build_instructions.md
@@ -50,7 +50,7 @@ --includeRecommended ``` -You must have the version 10.0.17763 or higher Windows 10 SDK installed. This +You must have the version 10.0.18362 or higher Windows 10 SDK installed. This can be installed separately or by checking the appropriate box in the Visual Studio Installer.
diff --git a/google_apis/gaia/fake_oauth2_access_token_manager.cc b/google_apis/gaia/fake_oauth2_access_token_manager.cc index 65df882..4e48c808 100644 --- a/google_apis/gaia/fake_oauth2_access_token_manager.cc +++ b/google_apis/gaia/fake_oauth2_access_token_manager.cc
@@ -20,9 +20,8 @@ FakeOAuth2AccessTokenManager::PendingRequest::~PendingRequest() {} FakeOAuth2AccessTokenManager::FakeOAuth2AccessTokenManager( - OAuth2TokenService* token_service, OAuth2AccessTokenManager::Delegate* delegate) - : OAuth2AccessTokenManager(token_service, delegate), + : OAuth2AccessTokenManager(delegate), auto_post_fetch_response_on_message_loop_(false), weak_ptr_factory_(this) {}
diff --git a/google_apis/gaia/fake_oauth2_access_token_manager.h b/google_apis/gaia/fake_oauth2_access_token_manager.h index fed88c1..d9efa6be 100644 --- a/google_apis/gaia/fake_oauth2_access_token_manager.h +++ b/google_apis/gaia/fake_oauth2_access_token_manager.h
@@ -32,7 +32,6 @@ }; explicit FakeOAuth2AccessTokenManager( - OAuth2TokenService* token_service, OAuth2AccessTokenManager::Delegate* delegate); ~FakeOAuth2AccessTokenManager() override;
diff --git a/google_apis/gaia/fake_oauth2_token_service.cc b/google_apis/gaia/fake_oauth2_token_service.cc index 988f5e3..df03166 100644 --- a/google_apis/gaia/fake_oauth2_token_service.cc +++ b/google_apis/gaia/fake_oauth2_token_service.cc
@@ -10,25 +10,12 @@ : OAuth2TokenService(std::make_unique<FakeOAuth2TokenServiceDelegate>()) { OverrideAccessTokenManagerForTesting( std::make_unique<FakeOAuth2AccessTokenManager>( - this /* OAuth2TokenService* */, this /* OAuth2AccessTokenManager::Delegate* */)); } FakeOAuth2TokenService::~FakeOAuth2TokenService() { } -void FakeOAuth2TokenService::FetchOAuth2Token( - OAuth2AccessTokenManager::RequestImpl* request, - const CoreAccountId& account_id, - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - const std::string& client_id, - const std::string& client_secret, - const OAuth2AccessTokenManager::ScopeSet& scopes) { - GetFakeAccessTokenManager()->FetchOAuth2Token(request, account_id, - url_loader_factory, client_id, - client_secret, scopes); -} - void FakeOAuth2TokenService::AddAccount(const CoreAccountId& account_id) { GetDelegate()->UpdateCredentials(account_id, "fake_refresh_token"); }
diff --git a/google_apis/gaia/fake_oauth2_token_service.h b/google_apis/gaia/fake_oauth2_token_service.h index c261e46..453058a 100644 --- a/google_apis/gaia/fake_oauth2_token_service.h +++ b/google_apis/gaia/fake_oauth2_token_service.h
@@ -11,10 +11,6 @@ #include "google_apis/gaia/fake_oauth2_token_service_delegate.h" #include "google_apis/gaia/oauth2_token_service.h" -namespace network { -class SharedURLLoaderFactory; -} - // Do-nothing implementation of OAuth2TokenService. class FakeOAuth2TokenService : public OAuth2TokenService { public: @@ -38,16 +34,6 @@ FakeOAuth2TokenServiceDelegate* GetFakeOAuth2TokenServiceDelegate(); - protected: - // OAuth2TokenService overrides. - void FetchOAuth2Token( - OAuth2AccessTokenManager::RequestImpl* request, - const CoreAccountId& account_id, - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - const std::string& client_id, - const std::string& client_secret, - const OAuth2AccessTokenManager::ScopeSet& scopes) override; - private: FakeOAuth2AccessTokenManager* GetFakeAccessTokenManager();
diff --git a/google_apis/gaia/oauth2_access_token_manager.cc b/google_apis/gaia/oauth2_access_token_manager.cc index f0964c1..91da5a6 100644 --- a/google_apis/gaia/oauth2_access_token_manager.cc +++ b/google_apis/gaia/oauth2_access_token_manager.cc
@@ -11,7 +11,6 @@ #include "base/timer/timer.h" #include "google_apis/gaia/gaia_urls.h" #include "google_apis/gaia/oauth2_access_token_fetcher.h" -#include "google_apis/gaia/oauth2_token_service.h" #include "services/network/public/cpp/shared_url_loader_factory.h" int OAuth2AccessTokenManager::max_fetch_retry_num_ = 5; @@ -391,11 +390,8 @@ } OAuth2AccessTokenManager::OAuth2AccessTokenManager( - OAuth2TokenService* token_service, OAuth2AccessTokenManager::Delegate* delegate) - : token_service_(token_service), - delegate_(delegate) { - DCHECK(token_service_); + : delegate_(delegate) { DCHECK(delegate_); } @@ -552,13 +548,9 @@ const CoreAccountId& account_id, const ScopeSet& scopes, const std::string& access_token) { - // TODO(https://crbug.com/967598): Use directly - // OAuth2AccessTokenManager::InvalidateAccessTokenImpl once this fully manages - // access tokens independently of OAuth2TokenService. For now, some tests need - // to call overridden of OAuth2TokenService::InvalidateAccessTokenImpl. - token_service_->InvalidateAccessTokenImpl( - account_id, GaiaUrls::GetInstance()->oauth2_chrome_client_id(), scopes, - access_token); + InvalidateAccessTokenImpl(account_id, + GaiaUrls::GetInstance()->oauth2_chrome_client_id(), + scopes, access_token); } void OAuth2AccessTokenManager::InvalidateAccessTokenImpl( @@ -648,13 +640,8 @@ } else { // The token isn't in the cache and the delegate isn't fetching it: fetch it // ourselves! - // TODO(https://crbug.com/967598): Use directly - // OAuth2AccessTokenManager::FetchOAuth2Token this fully manages access - // tokens independently of OAuth2TokenService. For now, some tests need to - // override OAuth2TokenService::FetchOAuth2Token. - token_service_->FetchOAuth2Token(request.get(), account_id, - url_loader_factory, client_id, - client_secret, scopes); + FetchOAuth2Token(request.get(), account_id, url_loader_factory, client_id, + client_secret, scopes); } return std::move(request); }
diff --git a/google_apis/gaia/oauth2_access_token_manager.h b/google_apis/gaia/oauth2_access_token_manager.h index 7dbd401..c347b5ed 100644 --- a/google_apis/gaia/oauth2_access_token_manager.h +++ b/google_apis/gaia/oauth2_access_token_manager.h
@@ -17,7 +17,6 @@ } class OAuth2AccessTokenFetcher; -class OAuth2TokenService; // Class that manages requests for OAuth2 access tokens. class OAuth2AccessTokenManager { @@ -175,11 +174,7 @@ typedef std::map<RequestParameters, OAuth2AccessTokenConsumer::TokenResponse> TokenCache; - // TODO(https://crbug.com/967598): Remove |token_service| once - // OAuth2AccessTokenManager fully manages access tokens independently of - // OAuth2TokenService. explicit OAuth2AccessTokenManager( - OAuth2TokenService* token_service, OAuth2AccessTokenManager::Delegate* delegate); virtual ~OAuth2AccessTokenManager(); @@ -340,9 +335,6 @@ // List of observers to notify when access token status changes. base::ObserverList<DiagnosticsObserver, true>::Unchecked diagnostics_observer_list_; - // TODO(https://crbug.com/967598): Remove this once OAuth2AccessTokenManager - // fully manages access tokens independently of OAuth2TokenService. - OAuth2TokenService* token_service_; Delegate* delegate_; // A map from fetch parameters to a fetcher that is fetching an OAuth2 access // token using these parameters.
diff --git a/google_apis/gaia/oauth2_token_service.cc b/google_apis/gaia/oauth2_token_service.cc index f5a3909..9627a60 100644 --- a/google_apis/gaia/oauth2_token_service.cc +++ b/google_apis/gaia/oauth2_token_service.cc
@@ -30,7 +30,6 @@ DCHECK(delegate_); AddObserver(this); token_manager_ = std::make_unique<OAuth2AccessTokenManager>( - this /* OAuth2TokenService* */, this /* OAuth2AccessTokenManager::Delegate* */); } @@ -177,17 +176,6 @@ scopes, consumer); } -void OAuth2TokenService::FetchOAuth2Token( - OAuth2AccessTokenManager::RequestImpl* request, - const CoreAccountId& account_id, - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - const std::string& client_id, - const std::string& client_secret, - const OAuth2AccessTokenManager::ScopeSet& scopes) { - token_manager_->FetchOAuth2Token(request, account_id, url_loader_factory, - client_id, client_secret, scopes); -} - bool OAuth2TokenService::AreAllCredentialsLoaded() const { return all_credentials_loaded_; } @@ -236,16 +224,6 @@ delegate_->InvalidateTokenForMultilogin(failed_account); } -void OAuth2TokenService::InvalidateAccessTokenImpl( - const CoreAccountId& account_id, - const std::string& client_id, - const OAuth2AccessTokenManager::ScopeSet& scopes, - const std::string& access_token) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - token_manager_->InvalidateAccessTokenImpl(account_id, client_id, scopes, - access_token); -} - void OAuth2TokenService::OnRefreshTokensLoaded() { all_credentials_loaded_ = true; }
diff --git a/google_apis/gaia/oauth2_token_service.h b/google_apis/gaia/oauth2_token_service.h index c388985..e91f286 100644 --- a/google_apis/gaia/oauth2_token_service.h +++ b/google_apis/gaia/oauth2_token_service.h
@@ -237,27 +237,6 @@ // Deprecated. It's moved to OAuth2AccessTokenManager. virtual void CancelRequestsForAccount(const CoreAccountId& account_id); - // Fetches an OAuth token for the specified client/scopes. Virtual so it can - // be overridden for tests and for platform-specific behavior. - // Deprecated. It's moved to OAuth2AccessTokenManager. - virtual void FetchOAuth2Token( - OAuth2AccessTokenManager::RequestImpl* request, - const CoreAccountId& account_id, - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - const std::string& client_id, - const std::string& client_secret, - const OAuth2AccessTokenManager::ScopeSet& scopes); - - // Invalidates the |access_token| issued for |account_id|, |client_id| and - // |scopes|. Virtual so it can be overridden for tests and for platform- - // specific behavior. - // Deprecated. It's moved to OAuth2AccessTokenManager. - virtual void InvalidateAccessTokenImpl( - const CoreAccountId& account_id, - const std::string& client_id, - const OAuth2AccessTokenManager::ScopeSet& scopes, - const std::string& access_token); - private: friend class OAuth2TokenServiceDelegate;
diff --git a/infra/config/cr-buildbucket.cfg b/infra/config/cr-buildbucket.cfg index 0566864..6f85927 100644 --- a/infra/config/cr-buildbucket.cfg +++ b/infra/config/cr-buildbucket.cfg
@@ -3078,60 +3078,60 @@ # Goma RBE ToT/Staging/FYI builders { name: "Chromium Linux Goma RBE ToT" - dimensions: "os:Ubuntu-14.04" + mixins: "linux-xenial" mixins: "goma-ci" } builders { name: "Chromium Linux Goma RBE ToT (ATS)" - dimensions: "os:Ubuntu-14.04" + mixins: "linux-xenial" mixins: "goma-ats" mixins: "goma-ci" } builders { name: "Chromium Linux Goma RBE Staging" - dimensions: "os:Ubuntu-14.04" + mixins: "linux-xenial" mixins: "goma-ci" mixins: "goma-rbe-staging" } builders { name: "Chromium Linux Goma RBE Staging (clobber)" - dimensions: "os:Ubuntu-14.04" + mixins: "linux-xenial" mixins: "goma-ci" mixins: "goma-rbe-staging" } builders { name: "Chromium Linux Goma RBE Staging (dbg)" - dimensions: "os:Ubuntu-14.04" + mixins: "linux-xenial" mixins: "goma-ci" mixins: "goma-rbe-staging" } builders { name: "Chromium Linux Goma RBE Staging (dbg) (clobber)" - dimensions: "os:Ubuntu-14.04" + mixins: "linux-xenial" mixins: "goma-ci" mixins: "goma-rbe-staging" } builders { name: "Chromium Linux Goma RBE Prod" - dimensions: "os:Ubuntu-14.04" + mixins: "linux-xenial" mixins: "goma-ci" mixins: "goma-rbe-prod" } builders { name: "Chromium Linux Goma RBE Prod (clobber)" - dimensions: "os:Ubuntu-14.04" + mixins: "linux-xenial" mixins: "goma-ci" mixins: "goma-rbe-prod" } builders { name: "Chromium Linux Goma RBE Prod (dbg)" - dimensions: "os:Ubuntu-14.04" + mixins: "linux-xenial" mixins: "goma-ci" mixins: "goma-rbe-prod" } builders { name: "Chromium Linux Goma RBE Prod (dbg) (clobber)" - dimensions: "os:Ubuntu-14.04" + mixins: "linux-xenial" mixins: "goma-ci" mixins: "goma-rbe-prod" } @@ -3214,42 +3214,42 @@ } builders { name: "Chromium Android ARM 32-bit Goma RBE ToT" - dimensions: "os:Ubuntu-14.04" + mixins: "linux-xenial" mixins: "goma-ci" } builders { name: "Chromium Android ARM 32-bit Goma RBE ToT (ATS)" - dimensions: "os:Ubuntu-14.04" + mixins: "linux-xenial" mixins: "goma-ats" mixins: "goma-ci" } builders { name: "Chromium Android ARM 32-bit Goma RBE Staging" - dimensions: "os:Ubuntu-14.04" + mixins: "linux-xenial" mixins: "goma-ci" mixins: "goma-rbe-staging" } builders { name: "Chromium Android ARM 32-bit Goma RBE Prod" - dimensions: "os:Ubuntu-14.04" + mixins: "linux-xenial" mixins: "goma-ci" mixins: "goma-rbe-prod" } builders { name: "Chromium Android ARM 32-bit Goma RBE Prod (clobber)" - dimensions: "os:Ubuntu-14.04" + mixins: "linux-xenial" mixins: "goma-ci" mixins: "goma-rbe-prod" } builders { name: "Chromium Android ARM 32-bit Goma RBE Prod (dbg)" - dimensions: "os:Ubuntu-14.04" + mixins: "linux-xenial" mixins: "goma-ci" mixins: "goma-rbe-prod" } builders { name: "Chromium Android ARM 32-bit Goma RBE Prod (dbg) (clobber)" - dimensions: "os:Ubuntu-14.04" + mixins: "linux-xenial" mixins: "goma-ci" mixins: "goma-rbe-prod" } @@ -3306,7 +3306,7 @@ } builders { name: "Chromium Linux Goma Staging" - dimensions: "os:Ubuntu-14.04" + mixins: "linux-xenial" mixins: "goma-ci" } builders { @@ -3420,7 +3420,7 @@ } builders { name: "Android Builder (dbg) Goma Latest Client" - dimensions: "os:Ubuntu-14.04" + mixins: "linux-xenial" mixins: "fyi-ci" } builders { @@ -3447,12 +3447,12 @@ } builders { name: "Linux x64 Goma Latest Client LocalOutputCache" - dimensions: "os:Ubuntu-14.04" + mixins: "linux-xenial" mixins: "fyi-ci" } builders { name: "Linux Builder Goma Latest Client" - dimensions: "os:Ubuntu-14.04" + mixins: "linux-xenial" mixins: "fyi-ci" } builders { @@ -3483,12 +3483,12 @@ } builders { name: "Linux x64 Goma Latest Client (clobber)" - dimensions: "os:Ubuntu-14.04" + mixins: "linux-xenial" mixins: "fyi-ci" } builders { name: "chromeos-amd64-generic-rel-goma-latest" - dimensions: "os:Ubuntu-14.04" + mixins: "linux-xenial" mixins: "fyi-ci" } builders {
diff --git a/ios/chrome/browser/OWNERS b/ios/chrome/browser/OWNERS index 1f4b984..9244a78 100644 --- a/ios/chrome/browser/OWNERS +++ b/ios/chrome/browser/OWNERS
@@ -3,9 +3,6 @@ per-file ios_chrome_io_thread*=rsleevi@chromium.org # Only for adding and removing flags. -per-file about_flags.*=* -per-file experimental_flags.*=* - per-file ios_chrome_flag_descriptions.*=* # TEAM: ios-directory-owners@chromium.org
diff --git a/ios/chrome/browser/autofill/BUILD.gn b/ios/chrome/browser/autofill/BUILD.gn index 4460e586..8709bb30b 100644 --- a/ios/chrome/browser/autofill/BUILD.gn +++ b/ios/chrome/browser/autofill/BUILD.gn
@@ -69,6 +69,7 @@ "//ios/chrome/browser/ui/autofill/manual_fill:manual_fill_ui", "//ios/chrome/browser/ui/image_util", "//ios/chrome/browser/ui/util", + "//ios/chrome/browser/webdata_services", "//ios/chrome/common/ui_util", "//ios/web/public/deprecated", "//ios/web/public/js_messaging", @@ -163,6 +164,7 @@ "//ios/chrome/browser/ui/util", "//ios/chrome/browser/web:test_support", "//ios/chrome/browser/web:web_internal", + "//ios/chrome/browser/webdata_services", "//ios/chrome/test/base", "//ios/web/public/deprecated", "//ios/web/public/js_messaging",
diff --git a/ios/chrome/browser/autofill/autocomplete_history_manager_factory.cc b/ios/chrome/browser/autofill/autocomplete_history_manager_factory.cc index d191af2d..f0de9e2 100644 --- a/ios/chrome/browser/autofill/autocomplete_history_manager_factory.cc +++ b/ios/chrome/browser/autofill/autocomplete_history_manager_factory.cc
@@ -15,9 +15,9 @@ #include "ios/chrome/browser/autofill/autofill_profile_validator_factory.h" #include "ios/chrome/browser/browser_state/browser_state_otr_helper.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" -#include "ios/chrome/browser/browser_state/web_data_service_factory.h" #include "ios/chrome/browser/history/history_service_factory.h" #include "ios/chrome/browser/signin/identity_manager_factory.h" +#include "ios/chrome/browser/webdata_services/web_data_service_factory.h" namespace autofill {
diff --git a/ios/chrome/browser/autofill/autofill_controller_unittest.mm b/ios/chrome/browser/autofill/autofill_controller_unittest.mm index ad8df79..5553e28 100644 --- a/ios/chrome/browser/autofill/autofill_controller_unittest.mm +++ b/ios/chrome/browser/autofill/autofill_controller_unittest.mm
@@ -32,7 +32,6 @@ #import "ios/chrome/browser/autofill/form_suggestion_controller.h" #include "ios/chrome/browser/autofill/personal_data_manager_factory.h" #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" -#include "ios/chrome/browser/browser_state/web_data_service_factory.h" #include "ios/chrome/browser/infobars/infobar_manager_impl.h" #include "ios/chrome/browser/ssl/ios_security_state_tab_helper.h" #import "ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h" @@ -40,6 +39,7 @@ #include "ios/chrome/browser/ui/settings/personal_data_manager_finished_profile_tasks_waiter.h" #include "ios/chrome/browser/web/chrome_web_client.h" #import "ios/chrome/browser/web/chrome_web_test.h" +#include "ios/chrome/browser/webdata_services/web_data_service_factory.h" #import "ios/web/public/deprecated/crw_js_injection_receiver.h" #include "ios/web/public/js_messaging/web_frame.h" #include "ios/web/public/js_messaging/web_frame_util.h"
diff --git a/ios/chrome/browser/autofill/personal_data_manager_factory.cc b/ios/chrome/browser/autofill/personal_data_manager_factory.cc index 41ad023..b9adba1 100644 --- a/ios/chrome/browser/autofill/personal_data_manager_factory.cc +++ b/ios/chrome/browser/autofill/personal_data_manager_factory.cc
@@ -15,9 +15,9 @@ #include "ios/chrome/browser/autofill/autofill_profile_validator_factory.h" #include "ios/chrome/browser/browser_state/browser_state_otr_helper.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" -#include "ios/chrome/browser/browser_state/web_data_service_factory.h" #include "ios/chrome/browser/history/history_service_factory.h" #include "ios/chrome/browser/signin/identity_manager_factory.h" +#include "ios/chrome/browser/webdata_services/web_data_service_factory.h" namespace autofill {
diff --git a/ios/chrome/browser/browser_state/BUILD.gn b/ios/chrome/browser/browser_state/BUILD.gn index 2667d7e4..fbb8335 100644 --- a/ios/chrome/browser/browser_state/BUILD.gn +++ b/ios/chrome/browser/browser_state/BUILD.gn
@@ -9,8 +9,6 @@ "chrome_browser_state.h", "chrome_browser_state.mm", "chrome_browser_state_manager.h", - "web_data_service_factory.cc", - "web_data_service_factory.h", ] public_deps = [ @@ -26,7 +24,6 @@ "//components/prefs", "//components/search_engines", "//components/signin/core/browser", - "//components/signin/core/browser/webdata", "//components/sync_preferences", "//components/variations/net", "//components/webdata_services", @@ -127,6 +124,7 @@ "//ios/chrome/browser/undo", "//ios/chrome/browser/unified_consent", "//ios/chrome/browser/web_state_list/web_usage_enabler", + "//ios/chrome/browser/webdata_services", "//ios/net", "//ios/public/provider/chrome/browser", "//ios/public/provider/chrome/browser/signin", @@ -200,6 +198,7 @@ "//ios/chrome/browser/prefs:browser_prefs", "//ios/chrome/browser/sync/glue", "//ios/chrome/browser/undo", + "//ios/chrome/browser/webdata_services", "//ios/chrome/test:test_support", "//ios/public/provider/chrome/browser", "//ios/public/provider/chrome/browser/ui",
diff --git a/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm b/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm index 450a9a6..652aecc 100644 --- a/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm +++ b/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm
@@ -11,7 +11,6 @@ #include "ios/chrome/browser/autofill/personal_data_manager_factory.h" #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" #include "ios/chrome/browser/bookmarks/startup_task_runner_service_factory.h" -#include "ios/chrome/browser/browser_state/web_data_service_factory.h" #include "ios/chrome/browser/browsing_data/browsing_data_remover_factory.h" #include "ios/chrome/browser/content_settings/cookie_settings_factory.h" #include "ios/chrome/browser/dom_distiller/dom_distiller_service_factory.h" @@ -59,6 +58,7 @@ #include "ios/chrome/browser/undo/bookmark_undo_service_factory.h" #include "ios/chrome/browser/unified_consent/unified_consent_service_factory.h" #import "ios/chrome/browser/web_state_list/web_usage_enabler/web_state_list_web_usage_enabler_factory.h" +#include "ios/chrome/browser/webdata_services/web_data_service_factory.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support."
diff --git a/ios/chrome/browser/browser_state/test_chrome_browser_state.mm b/ios/chrome/browser/browser_state/test_chrome_browser_state.mm index 541a3fb..1fc59ec 100644 --- a/ios/chrome/browser/browser_state/test_chrome_browser_state.mm +++ b/ios/chrome/browser/browser_state/test_chrome_browser_state.mm
@@ -38,7 +38,6 @@ #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" #include "ios/chrome/browser/bookmarks/bookmark_sync_service_factory.h" #include "ios/chrome/browser/browser_state/browser_state_keyed_service_factories.h" -#include "ios/chrome/browser/browser_state/web_data_service_factory.h" #include "ios/chrome/browser/history/history_client_impl.h" #include "ios/chrome/browser/history/history_service_factory.h" #include "ios/chrome/browser/history/top_sites_factory.h" @@ -46,6 +45,7 @@ #include "ios/chrome/browser/prefs/browser_prefs.h" #include "ios/chrome/browser/prefs/ios_chrome_pref_service_factory.h" #include "ios/chrome/browser/undo/bookmark_undo_service_factory.h" +#include "ios/chrome/browser/webdata_services/web_data_service_factory.h" #include "ios/public/provider/chrome/browser/chrome_browser_provider.h" #include "ios/web/public/thread/web_task_traits.h" #include "ios/web/public/thread/web_thread.h"
diff --git a/ios/chrome/browser/browsing_data/BUILD.gn b/ios/chrome/browser/browsing_data/BUILD.gn index 5e3b7ba..a6b3c3fa 100644 --- a/ios/chrome/browser/browsing_data/BUILD.gn +++ b/ios/chrome/browser/browsing_data/BUILD.gn
@@ -69,6 +69,7 @@ "//ios/chrome/browser/snapshots", "//ios/chrome/browser/sync", "//ios/chrome/browser/translate:translate", + "//ios/chrome/browser/webdata_services", "//ios/net", "//ios/public/provider/chrome/browser", "//ios/web",
diff --git a/ios/chrome/browser/browsing_data/browsing_data_counter_wrapper.cc b/ios/chrome/browser/browsing_data/browsing_data_counter_wrapper.cc index c5c490a7..9243d2f 100644 --- a/ios/chrome/browser/browsing_data/browsing_data_counter_wrapper.cc +++ b/ios/chrome/browser/browsing_data/browsing_data_counter_wrapper.cc
@@ -16,13 +16,13 @@ #include "components/prefs/pref_service.h" #include "components/sync/driver/sync_service.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" -#include "ios/chrome/browser/browser_state/web_data_service_factory.h" #include "ios/chrome/browser/browsing_data/browsing_data_features.h" #include "ios/chrome/browser/browsing_data/cache_counter.h" #include "ios/chrome/browser/history/history_service_factory.h" #include "ios/chrome/browser/history/web_history_service_factory.h" #include "ios/chrome/browser/passwords/ios_chrome_password_store_factory.h" #include "ios/chrome/browser/sync/profile_sync_service_factory.h" +#include "ios/chrome/browser/webdata_services/web_data_service_factory.h" namespace {
diff --git a/ios/chrome/browser/browsing_data/browsing_data_remover_impl.mm b/ios/chrome/browser/browsing_data/browsing_data_remover_impl.mm index 0bb5cd1..2ae8a28 100644 --- a/ios/chrome/browser/browsing_data/browsing_data_remover_impl.mm +++ b/ios/chrome/browser/browsing_data/browsing_data_remover_impl.mm
@@ -42,7 +42,6 @@ #include "ios/chrome/browser/autofill/strike_database_factory.h" #include "ios/chrome/browser/bookmarks/bookmark_remover_helper.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" -#include "ios/chrome/browser/browser_state/web_data_service_factory.h" #include "ios/chrome/browser/browsing_data/browsing_data_features.h" #include "ios/chrome/browser/browsing_data/browsing_data_remove_mask.h" #include "ios/chrome/browser/external_files/external_file_remover.h" @@ -58,6 +57,7 @@ #import "ios/chrome/browser/sessions/session_service_ios.h" #include "ios/chrome/browser/signin/account_consistency_service_factory.h" #include "ios/chrome/browser/snapshots/snapshots_util.h" +#include "ios/chrome/browser/webdata_services/web_data_service_factory.h" #include "ios/net/http_cache_helper.h" #import "ios/web/public/browsing_data/browsing_data_removing_util.h" #include "ios/web/public/thread/web_task_traits.h"
diff --git a/ios/chrome/browser/flags/OWNERS b/ios/chrome/browser/flags/OWNERS new file mode 100644 index 0000000..7352d8d --- /dev/null +++ b/ios/chrome/browser/flags/OWNERS
@@ -0,0 +1,4 @@ +per-file about_flags.*=* + +# TEAM: ios-directory-owners@chromium.org +# OS: iOS
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index d1568b95..b5d214c2a 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -496,10 +496,6 @@ flags_ui::kOsIos, FEATURE_VALUE_TYPE( autofill::features::kAutofillNoLocalSaveOnUploadSuccess)}, - {"display-search-engine-favicon", - flag_descriptions::kDisplaySearchEngineFaviconName, - flag_descriptions::kDisplaySearchEngineFaviconDescription, - flags_ui::kOsIos, FEATURE_VALUE_TYPE(kDisplaySearchEngineFavicon)}, {"autofill-no-local-save-on-unmask-success", flag_descriptions::kAutofillNoLocalSaveOnUnmaskSuccessName, flag_descriptions::kAutofillNoLocalSaveOnUnmaskSuccessDescription,
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/ios_chrome_flag_descriptions.cc index 526c6f8..b130756b 100644 --- a/ios/chrome/browser/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/ios_chrome_flag_descriptions.cc
@@ -148,11 +148,6 @@ "A crash report will be uploaded if the main thread is frozen more than " "the time specified by this flag."; -const char kDisplaySearchEngineFaviconName[] = - "Display search engine favicons."; -const char kDisplaySearchEngineFaviconDescription[] = - "When enabled, Settings will display search engine favicons"; - const char kDragAndDropName[] = "Drag and Drop"; const char kDragAndDropDescription[] = "Enable support for drag and drop.";
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.h b/ios/chrome/browser/ios_chrome_flag_descriptions.h index b675513..9a61e50 100644 --- a/ios/chrome/browser/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/ios_chrome_flag_descriptions.h
@@ -117,11 +117,6 @@ extern const char kDetectMainThreadFreezeName[]; extern const char kDetectMainThreadFreezeDescription[]; -// Title and description for the flag to enable displaying search engine -// favicons in Settings. -extern const char kDisplaySearchEngineFaviconName[]; -extern const char kDisplaySearchEngineFaviconDescription[]; - // Title and description for the flag to enable drag and drop. extern const char kDragAndDropName[]; extern const char kDragAndDropDescription[];
diff --git a/ios/chrome/browser/passwords/BUILD.gn b/ios/chrome/browser/passwords/BUILD.gn index 1d90f1a5..d7b9cc0 100644 --- a/ios/chrome/browser/passwords/BUILD.gn +++ b/ios/chrome/browser/passwords/BUILD.gn
@@ -82,6 +82,7 @@ "//ios/chrome/browser/ui/infobars/coordinators", "//ios/chrome/browser/ui/util", "//ios/chrome/browser/web", + "//ios/chrome/browser/webdata_services", "//ios/chrome/common/ui_util", "//ios/public/provider/chrome/browser", "//ios/public/provider/chrome/browser/ui",
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_store_factory.cc b/ios/chrome/browser/passwords/ios_chrome_password_store_factory.cc index e3e5bca..3c3ef87 100644 --- a/ios/chrome/browser/passwords/ios_chrome_password_store_factory.cc +++ b/ios/chrome/browser/passwords/ios_chrome_password_store_factory.cc
@@ -26,9 +26,9 @@ #include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/browser_state/browser_state_otr_helper.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" -#include "ios/chrome/browser/browser_state/web_data_service_factory.h" #include "ios/chrome/browser/sync/glue/sync_start_util.h" #include "ios/chrome/browser/sync/profile_sync_service_factory.h" +#include "ios/chrome/browser/webdata_services/web_data_service_factory.h" #include "services/network/public/cpp/shared_url_loader_factory.h" // static
diff --git a/ios/chrome/browser/search_engines/BUILD.gn b/ios/chrome/browser/search_engines/BUILD.gn index 6f45520..fcb6f27 100644 --- a/ios/chrome/browser/search_engines/BUILD.gn +++ b/ios/chrome/browser/search_engines/BUILD.gn
@@ -39,6 +39,7 @@ "//ios/chrome/browser/browser_state", "//ios/chrome/browser/google", "//ios/chrome/browser/history", + "//ios/chrome/browser/webdata_services", "//ios/chrome/common", "//ios/web", "//net",
diff --git a/ios/chrome/browser/search_engines/template_url_service_factory.cc b/ios/chrome/browser/search_engines/template_url_service_factory.cc index 24b178a5..3ca6db4 100644 --- a/ios/chrome/browser/search_engines/template_url_service_factory.cc +++ b/ios/chrome/browser/search_engines/template_url_service_factory.cc
@@ -15,11 +15,11 @@ #include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/browser_state/browser_state_otr_helper.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" -#include "ios/chrome/browser/browser_state/web_data_service_factory.h" #include "ios/chrome/browser/google/google_url_tracker_factory.h" #include "ios/chrome/browser/history/history_service_factory.h" #include "ios/chrome/browser/search_engines/template_url_service_client_impl.h" #include "ios/chrome/browser/search_engines/ui_thread_search_terms_data.h" +#include "ios/chrome/browser/webdata_services/web_data_service_factory.h" #include "rlz/buildflags/buildflags.h" #if BUILDFLAG(ENABLE_RLZ)
diff --git a/ios/chrome/browser/signin/BUILD.gn b/ios/chrome/browser/signin/BUILD.gn index 9fccecb..5149c316 100644 --- a/ios/chrome/browser/signin/BUILD.gn +++ b/ios/chrome/browser/signin/BUILD.gn
@@ -77,6 +77,7 @@ "//ios/chrome/browser/crash_report", "//ios/chrome/browser/reading_list:reading_list_remover", "//ios/chrome/browser/ui/commands", + "//ios/chrome/browser/webdata_services", "//ios/chrome/common", "//ios/net", "//ios/public/provider/chrome/browser",
diff --git a/ios/chrome/browser/signin/device_accounts_provider_impl.mm b/ios/chrome/browser/signin/device_accounts_provider_impl.mm index e16dfda..f88583c4 100644 --- a/ios/chrome/browser/signin/device_accounts_provider_impl.mm +++ b/ios/chrome/browser/signin/device_accounts_provider_impl.mm
@@ -6,6 +6,7 @@ #include "base/logging.h" #include "base/strings/sys_string_conversions.h" +#include "components/signin/core/browser/account_info.h" #include "ios/chrome/browser/signin/constants.h" #include "ios/chrome/browser/signin/signin_util.h" #import "ios/public/provider/chrome/browser/chrome_browser_provider.h" @@ -18,13 +19,22 @@ #endif namespace { -// Returns the account info for |identity|. -// Returns an empty account info if |identity| is nil. +// Returns the account info for |identity| (which must not be nil). DeviceAccountsProvider::AccountInfo GetAccountInfo(ChromeIdentity* identity) { + DCHECK(identity); DeviceAccountsProvider::AccountInfo account_info; - if (identity) { - account_info.gaia = base::SysNSStringToUTF8([identity gaiaID]); - account_info.email = base::SysNSStringToUTF8([identity userEmail]); + account_info.gaia = base::SysNSStringToUTF8([identity gaiaID]); + account_info.email = base::SysNSStringToUTF8([identity userEmail]); + + // If hosted domain is nil, then it means the information has not been + // fetched from gaia; in that case, set account_info.hosted_domain to + // an empty string. Otherwise, set it to the value of the hostedDomain + // or kNoHostedDomainFound if the string is empty. + NSString* hostedDomain = [identity hostedDomain]; + if (hostedDomain) { + account_info.hosted_domain = [hostedDomain length] + ? base::SysNSStringToUTF8(hostedDomain) + : kNoHostedDomainFound; } return account_info; }
diff --git a/ios/chrome/browser/signin/ios_chrome_signin_client.mm b/ios/chrome/browser/signin/ios_chrome_signin_client.mm index 8e390b0..9b1715ab 100644 --- a/ios/chrome/browser/signin/ios_chrome_signin_client.mm +++ b/ios/chrome/browser/signin/ios_chrome_signin_client.mm
@@ -12,9 +12,9 @@ #include "ios/chrome/browser/browser_state/browser_state_info_cache.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/browser_state/chrome_browser_state_manager.h" -#include "ios/chrome/browser/browser_state/web_data_service_factory.h" #include "ios/chrome/browser/signin/account_consistency_service_factory.h" #include "ios/chrome/browser/signin/gaia_auth_fetcher_ios.h" +#include "ios/chrome/browser/webdata_services/web_data_service_factory.h" #include "ios/chrome/common/channel_info.h" #include "services/network/public/cpp/shared_url_loader_factory.h"
diff --git a/ios/chrome/browser/sync/BUILD.gn b/ios/chrome/browser/sync/BUILD.gn index c9e8dcc1..d248b83 100644 --- a/ios/chrome/browser/sync/BUILD.gn +++ b/ios/chrome/browser/sync/BUILD.gn
@@ -79,6 +79,7 @@ "//ios/chrome/browser/sync/sessions", "//ios/chrome/browser/tabs", "//ios/chrome/browser/undo", + "//ios/chrome/browser/webdata_services", "//ios/chrome/common", "//ios/web", "//net",
diff --git a/ios/chrome/browser/sync/ios_chrome_sync_client.mm b/ios/chrome/browser/sync/ios_chrome_sync_client.mm index f8a32d5..a8335f8 100644 --- a/ios/chrome/browser/sync/ios_chrome_sync_client.mm +++ b/ios/chrome/browser/sync/ios_chrome_sync_client.mm
@@ -47,7 +47,6 @@ #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" #include "ios/chrome/browser/bookmarks/bookmark_sync_service_factory.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" -#include "ios/chrome/browser/browser_state/web_data_service_factory.h" #include "ios/chrome/browser/dom_distiller/dom_distiller_service_factory.h" #include "ios/chrome/browser/favicon/favicon_service_factory.h" #include "ios/chrome/browser/history/history_service_factory.h" @@ -63,6 +62,7 @@ #include "ios/chrome/browser/sync/send_tab_to_self_sync_service_factory.h" #include "ios/chrome/browser/sync/session_sync_service_factory.h" #include "ios/chrome/browser/undo/bookmark_undo_service_factory.h" +#include "ios/chrome/browser/webdata_services/web_data_service_factory.h" #include "ios/chrome/common/channel_info.h" #include "ios/web/public/thread/web_task_traits.h" #include "ios/web/public/thread/web_thread.h"
diff --git a/ios/chrome/browser/sync/profile_sync_service_factory.cc b/ios/chrome/browser/sync/profile_sync_service_factory.cc index d28e6ee..3012314 100644 --- a/ios/chrome/browser/sync/profile_sync_service_factory.cc +++ b/ios/chrome/browser/sync/profile_sync_service_factory.cc
@@ -27,7 +27,6 @@ #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" #include "ios/chrome/browser/bookmarks/bookmark_sync_service_factory.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" -#include "ios/chrome/browser/browser_state/web_data_service_factory.h" #include "ios/chrome/browser/favicon/favicon_service_factory.h" #include "ios/chrome/browser/gcm/ios_chrome_gcm_profile_service_factory.h" #include "ios/chrome/browser/history/history_service_factory.h" @@ -46,6 +45,7 @@ #include "ios/chrome/browser/sync/model_type_store_service_factory.h" #include "ios/chrome/browser/sync/session_sync_service_factory.h" #include "ios/chrome/browser/undo/bookmark_undo_service_factory.h" +#include "ios/chrome/browser/webdata_services/web_data_service_factory.h" #include "ios/chrome/common/channel_info.h" #include "ios/web/public/thread/web_task_traits.h" #include "ios/web/public/thread/web_thread.h"
diff --git a/ios/chrome/browser/ui/autofill/BUILD.gn b/ios/chrome/browser/ui/autofill/BUILD.gn index 8c479d7..3e35495 100644 --- a/ios/chrome/browser/ui/autofill/BUILD.gn +++ b/ios/chrome/browser/ui/autofill/BUILD.gn
@@ -53,6 +53,7 @@ "//ios/chrome/browser/ui/coordinators:chrome_coordinators", "//ios/chrome/browser/ui/util", "//ios/chrome/browser/web_state_list:web_state_list", + "//ios/chrome/browser/webdata_services", "//ios/chrome/common", "//ios/public/provider/chrome/browser", "//ios/third_party/material_components_ios",
diff --git a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm index a53aa21..ef7d42a 100644 --- a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm +++ b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm
@@ -27,7 +27,6 @@ #include "ios/chrome/browser/autofill/autocomplete_history_manager_factory.h" #include "ios/chrome/browser/autofill/personal_data_manager_factory.h" #include "ios/chrome/browser/autofill/strike_database_factory.h" -#include "ios/chrome/browser/browser_state/web_data_service_factory.h" #include "ios/chrome/browser/infobars/infobar.h" #include "ios/chrome/browser/infobars/infobar_utils.h" #include "ios/chrome/browser/metrics/ukm_url_recorder.h" @@ -37,6 +36,7 @@ #include "ios/chrome/browser/translate/chrome_ios_translate_client.h" #include "ios/chrome/browser/ui/autofill/card_unmask_prompt_view_bridge.h" #include "ios/chrome/browser/ui/autofill/save_card_infobar_controller.h" +#include "ios/chrome/browser/webdata_services/web_data_service_factory.h" #include "ios/chrome/common/channel_info.h" #include "ios/public/provider/chrome/browser/chrome_browser_provider.h" #include "services/network/public/cpp/shared_url_loader_factory.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_cell.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_cell.mm index 3e9e2f3..a789eb5 100644 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_cell.mm +++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_cell.mm
@@ -272,14 +272,6 @@ constant:kStandardSpacing], [_imageContainer.bottomAnchor constraintLessThanOrEqualToAnchor:_faviconView.bottomAnchor], - [_imageContainer.leadingAnchor - constraintEqualToAnchor:self.contentView.leadingAnchor - constant:kStandardSpacing], - - // Title label. - [_titleLabel.trailingAnchor - constraintEqualToAnchor:self.contentView.trailingAnchor - constant:-kStandardSpacing], // Favicon. [_faviconView.leadingAnchor @@ -309,33 +301,63 @@ [_noImageIcon.heightAnchor constraintEqualToAnchor:_noImageIcon.widthAnchor] ]]; - // Prevent _additionalInformationLabel from overlapping with _titleLabel when - // a11y font size is used. + AddSameConstraints(_contentImageView, _imageContainer); + + // For standard layout, the image container should be aligned to the right + // border if kOptionalArticleThumbnail is enabled, otherwise the left border. if (base::FeatureList::IsEnabled(kOptionalArticleThumbnail)) { + // Prevent _additionalInformationLabel from overlapping with _titleLabel + // when a11y font size is used. [_additionalInformationLabel.topAnchor constraintGreaterThanOrEqualToAnchor:_titleLabel.bottomAnchor constant:kSmallSpacing] .active = YES; + + _imageTitleHorizontalSpacing = [_imageContainer.leadingAnchor + constraintEqualToAnchor:_titleLabel.trailingAnchor + constant:kStandardSpacing]; + + _standardConstraints = @[ + _imageTitleHorizontalSpacing, + [_titleLabel.topAnchor constraintEqualToAnchor:_imageContainer.topAnchor], + [_titleLabel.leadingAnchor + constraintEqualToAnchor:self.contentView.leadingAnchor + constant:kStandardSpacing], + [_imageContainer.trailingAnchor + constraintEqualToAnchor:self.contentView.trailingAnchor + constant:-kStandardSpacing], + ]; + } else { + _imageTitleHorizontalSpacing = [_titleLabel.leadingAnchor + constraintEqualToAnchor:_imageContainer.trailingAnchor + constant:kStandardSpacing]; + + _standardConstraints = @[ + _imageTitleHorizontalSpacing, + [_titleLabel.topAnchor constraintEqualToAnchor:_imageContainer.topAnchor], + [_imageContainer.leadingAnchor + constraintEqualToAnchor:self.contentView.leadingAnchor + constant:kStandardSpacing], + [_titleLabel.trailingAnchor + constraintEqualToAnchor:self.contentView.trailingAnchor + constant:-kStandardSpacing], + ]; } - AddSameConstraints(_contentImageView, _imageContainer); - - _imageTitleHorizontalSpacing = [_titleLabel.leadingAnchor - constraintEqualToAnchor:_imageContainer.trailingAnchor - constant:kStandardSpacing]; + // For a11y layout, the image container is always aligned to the left border. _imageTitleVerticalSpacing = [_titleLabel.topAnchor constraintEqualToAnchor:_imageContainer.bottomAnchor constant:kStandardSpacing]; - _standardConstraints = @[ - _imageTitleHorizontalSpacing, - [_titleLabel.topAnchor constraintEqualToAnchor:_imageContainer.topAnchor], - ]; - _accessibilityConstraints = @[ - [_titleLabel.leadingAnchor + _imageTitleVerticalSpacing, + [_imageContainer.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:kStandardSpacing], - _imageTitleVerticalSpacing, + [_titleLabel.leadingAnchor + constraintEqualToAnchor:_imageContainer.leadingAnchor], + [_titleLabel.trailingAnchor + constraintEqualToAnchor:self.contentView.trailingAnchor + constant:-kStandardSpacing], ]; if (UIContentSizeCategoryIsAccessibilityCategory(
diff --git a/ios/chrome/browser/ui/settings/cells/search_engine_item.mm b/ios/chrome/browser/ui/settings/cells/search_engine_item.mm index b7fbc8e7..b30cb0b 100644 --- a/ios/chrome/browser/ui/settings/cells/search_engine_item.mm +++ b/ios/chrome/browser/ui/settings/cells/search_engine_item.mm
@@ -8,7 +8,6 @@ #include "base/strings/sys_string_conversions.h" #import "ios/chrome/browser/ui/settings/cells/settings_cells_constants.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h" -#import "ios/chrome/browser/ui/table_view/cells/table_view_detail_text_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_url_item.h" #import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h" #include "ios/chrome/browser/ui/ui_feature_flags.h" @@ -33,13 +32,7 @@ - (instancetype)initWithType:(NSInteger)type { self = [super initWithType:type]; if (self) { - // TODO(crbug.com/910525): Remove usage of TableViewDetailTextCell after the - // feature is launched. - if (base::FeatureList::IsEnabled(kDisplaySearchEngineFavicon)) { self.cellClass = TableViewURLCell.class; - } else { - self.cellClass = TableViewDetailTextCell.class; - } } return self; } @@ -50,40 +43,20 @@ self.uniqueIdentifier = base::SysUTF8ToNSString(self.URL.host()); - // TODO(crbug.com/910525): Remove usage of TableViewDetailTextCell after the - // feature is launched. - if (base::FeatureList::IsEnabled(kDisplaySearchEngineFavicon)) { - TableViewURLCell* cell = - base::mac::ObjCCastStrict<TableViewURLCell>(tableCell); + TableViewURLCell* cell = + base::mac::ObjCCastStrict<TableViewURLCell>(tableCell); + cell.titleLabel.text = self.text; + cell.URLLabel.text = self.detailText; + cell.cellUniqueIdentifier = self.uniqueIdentifier; + cell.accessibilityTraits |= UIAccessibilityTraitButton; - cell.titleLabel.text = self.text; - cell.URLLabel.text = self.detailText; - cell.cellUniqueIdentifier = self.uniqueIdentifier; - cell.accessibilityTraits |= UIAccessibilityTraitButton; - - if (styler.cellTitleColor) - cell.titleLabel.textColor = styler.cellTitleColor; - - cell.URLLabel.textColor = UIColorFromRGB(kSettingsCellsURLTextColor); - - [cell configureUILayout]; - } else { - TableViewDetailTextCell* cell = - base::mac::ObjCCastStrict<TableViewDetailTextCell>(tableCell); - - cell.textLabel.text = self.text; - cell.detailTextLabel.text = self.detailText; - cell.accessibilityTraits |= UIAccessibilityTraitButton; - - if (styler.cellTitleColor) { - cell.textLabel.textColor = styler.cellTitleColor; - } else { - cell.textLabel.textColor = - UIColorFromRGB(kTableViewTextLabelColorLightGrey); - } - cell.detailTextLabel.textColor = - UIColorFromRGB(kTableViewSecondaryLabelLightGrayTextColor); + if (styler.cellTitleColor) { + cell.titleLabel.textColor = styler.cellTitleColor; } + + cell.URLLabel.textColor = UIColorFromRGB(kSettingsCellsURLTextColor); + + [cell configureUILayout]; } @end
diff --git a/ios/chrome/browser/ui/settings/cells/search_engine_item_unittest.mm b/ios/chrome/browser/ui/settings/cells/search_engine_item_unittest.mm index de2aac1..57ea30cb 100644 --- a/ios/chrome/browser/ui/settings/cells/search_engine_item_unittest.mm +++ b/ios/chrome/browser/ui/settings/cells/search_engine_item_unittest.mm
@@ -5,7 +5,6 @@ #import "ios/chrome/browser/ui/settings/cells/search_engine_item.h" #include "base/mac/foundation_util.h" -#import "ios/chrome/browser/ui/table_view/cells/table_view_detail_text_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_url_item.h" #import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h" #include "ios/chrome/browser/ui/ui_feature_flags.h" @@ -36,37 +35,18 @@ item.accessoryType = UITableViewCellAccessoryCheckmark; id cell = [[[item cellClass] alloc] init]; - // TODO(crbug.com/910525): Remove usage of TableViewDetailTextCell after the - // feature is launched. - if (base::FeatureList::IsEnabled(kDisplaySearchEngineFavicon)) { - ASSERT_TRUE([cell isMemberOfClass:[TableViewURLCell class]]); + ASSERT_TRUE([cell isMemberOfClass:[TableViewURLCell class]]); - TableViewURLCell* URLCell = - base::mac::ObjCCastStrict<TableViewURLCell>(cell); - EXPECT_FALSE(URLCell.titleLabel.text); - EXPECT_FALSE(URLCell.URLLabel.text); - EXPECT_EQ(item.uniqueIdentifier, URLCell.cellUniqueIdentifier); - EXPECT_EQ(UITableViewCellAccessoryNone, URLCell.accessoryType); + TableViewURLCell* URLCell = base::mac::ObjCCastStrict<TableViewURLCell>(cell); + EXPECT_FALSE(URLCell.titleLabel.text); + EXPECT_FALSE(URLCell.URLLabel.text); + EXPECT_EQ(item.uniqueIdentifier, URLCell.cellUniqueIdentifier); + EXPECT_EQ(UITableViewCellAccessoryNone, URLCell.accessoryType); - ChromeTableViewStyler* styler = [[ChromeTableViewStyler alloc] init]; - [item configureCell:URLCell withStyler:styler]; - EXPECT_NSEQ(text, URLCell.titleLabel.text); - EXPECT_NSEQ(detailText, URLCell.URLLabel.text); - EXPECT_EQ(item.uniqueIdentifier, URLCell.cellUniqueIdentifier); - EXPECT_EQ(UITableViewCellAccessoryCheckmark, URLCell.accessoryType); - } else { - ASSERT_TRUE([cell isMemberOfClass:[TableViewDetailTextCell class]]); - - TableViewDetailTextCell* textCell = - base::mac::ObjCCastStrict<TableViewDetailTextCell>(cell); - EXPECT_FALSE(textCell.textLabel.text); - EXPECT_FALSE(textCell.detailTextLabel.text); - EXPECT_EQ(UITableViewCellAccessoryNone, textCell.accessoryType); - - ChromeTableViewStyler* styler = [[ChromeTableViewStyler alloc] init]; - [item configureCell:textCell withStyler:styler]; - EXPECT_NSEQ(text, textCell.textLabel.text); - EXPECT_NSEQ(detailText, textCell.detailTextLabel.text); - EXPECT_EQ(UITableViewCellAccessoryCheckmark, textCell.accessoryType); - } + ChromeTableViewStyler* styler = [[ChromeTableViewStyler alloc] init]; + [item configureCell:URLCell withStyler:styler]; + EXPECT_NSEQ(text, URLCell.titleLabel.text); + EXPECT_NSEQ(detailText, URLCell.URLLabel.text); + EXPECT_EQ(item.uniqueIdentifier, URLCell.cellUniqueIdentifier); + EXPECT_EQ(UITableViewCellAccessoryCheckmark, URLCell.accessoryType); }
diff --git a/ios/chrome/browser/ui/settings/search_engine_table_view_controller.mm b/ios/chrome/browser/ui/settings/search_engine_table_view_controller.mm index 42b441a..0237efb 100644 --- a/ios/chrome/browser/ui/settings/search_engine_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/search_engine_table_view_controller.mm
@@ -98,11 +98,8 @@ - (void)viewDidLoad { [super viewDidLoad]; - if (base::FeatureList::IsEnabled(kDisplaySearchEngineFavicon)) { - self.tableView.separatorInset = - UIEdgeInsetsMake(0, kTableViewSeparatorLeadingInset, 0, - kTableViewSeparatorTrailingInset); - } + self.tableView.separatorInset = UIEdgeInsetsMake( + 0, kTableViewSeparatorLeadingInset, 0, kTableViewSeparatorTrailingInset); [self loadModel]; } @@ -225,33 +222,30 @@ TableViewItem* item = [self.tableViewModel itemAtIndexPath:indexPath]; DCHECK(item.type == ItemTypePrepopulatedEngine || item.type == ItemTypeCustomEngine); - if (base::FeatureList::IsEnabled(kDisplaySearchEngineFavicon)) { - SearchEngineItem* engineItem = - base::mac::ObjCCastStrict<SearchEngineItem>(item); - TableViewURLCell* urlCell = - base::mac::ObjCCastStrict<TableViewURLCell>(cell); + SearchEngineItem* engineItem = + base::mac::ObjCCastStrict<SearchEngineItem>(item); + TableViewURLCell* urlCell = base::mac::ObjCCastStrict<TableViewURLCell>(cell); - if (item.type == ItemTypePrepopulatedEngine) { - _faviconLoader->FaviconForPageUrl( - engineItem.URL, kFaviconDesiredSizeInPoint, kFaviconMinSizeInPoint, - /*fallback_to_google_server=*/YES, ^(FaviconAttributes* attributes) { - // Only set favicon if the cell hasn't been reused. - if (urlCell.cellUniqueIdentifier == engineItem.uniqueIdentifier) { - DCHECK(attributes); - [urlCell.faviconView configureWithAttributes:attributes]; - } - }); - } else { - _faviconLoader->FaviconForIconUrl( - engineItem.URL, kFaviconDesiredSizeInPoint, kFaviconMinSizeInPoint, - ^(FaviconAttributes* attributes) { - // Only set favicon if the cell hasn't been reused. - if (urlCell.cellUniqueIdentifier == engineItem.uniqueIdentifier) { - DCHECK(attributes); - [urlCell.faviconView configureWithAttributes:attributes]; - } - }); - } + if (item.type == ItemTypePrepopulatedEngine) { + _faviconLoader->FaviconForPageUrl( + engineItem.URL, kFaviconDesiredSizeInPoint, kFaviconMinSizeInPoint, + /*fallback_to_google_server=*/YES, ^(FaviconAttributes* attributes) { + // Only set favicon if the cell hasn't been reused. + if (urlCell.cellUniqueIdentifier == engineItem.uniqueIdentifier) { + DCHECK(attributes); + [urlCell.faviconView configureWithAttributes:attributes]; + } + }); + } else { + _faviconLoader->FaviconForIconUrl( + engineItem.URL, kFaviconDesiredSizeInPoint, kFaviconMinSizeInPoint, + ^(FaviconAttributes* attributes) { + // Only set favicon if the cell hasn't been reused. + if (urlCell.cellUniqueIdentifier == engineItem.uniqueIdentifier) { + DCHECK(attributes); + [urlCell.faviconView configureWithAttributes:attributes]; + } + }); } return cell; }
diff --git a/ios/chrome/browser/ui/ui_feature_flags.cc b/ios/chrome/browser/ui/ui_feature_flags.cc index a0a5f625..80bf763a 100644 --- a/ios/chrome/browser/ui/ui_feature_flags.cc +++ b/ios/chrome/browser/ui/ui_feature_flags.cc
@@ -26,9 +26,6 @@ const base::Feature kSettingsRefresh{"SettingsRefresh", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kDisplaySearchEngineFavicon{ - "DisplaySearchEngineFavicon", base::FEATURE_ENABLED_BY_DEFAULT}; - const base::Feature kNewOmniboxPopupLayout{"NewOmniboxPopupLayout", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ios/chrome/browser/ui/ui_feature_flags.h b/ios/chrome/browser/ui/ui_feature_flags.h index f315429..142a2b3 100644 --- a/ios/chrome/browser/ui/ui_feature_flags.h +++ b/ios/chrome/browser/ui/ui_feature_flags.h
@@ -29,9 +29,6 @@ // Feature to apply UI Refresh theme to the settings. extern const base::Feature kSettingsRefresh; -// Feature to display search engine favicons in Settings. -extern const base::Feature kDisplaySearchEngineFavicon; - // Feature to display the new omnibox popup design with favicons, search engine // favicon in the omnibox, rich entities support, new layout. extern const base::Feature kNewOmniboxPopupLayout;
diff --git a/ios/chrome/browser/webdata_services/BUILD.gn b/ios/chrome/browser/webdata_services/BUILD.gn new file mode 100644 index 0000000..f739457 --- /dev/null +++ b/ios/chrome/browser/webdata_services/BUILD.gn
@@ -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. + +source_set("webdata_services") { + sources = [ + "web_data_service_factory.cc", + "web_data_service_factory.h", + ] + deps = [ + "//base", + "//components/autofill/core/browser", + "//components/keyed_service/core", + "//components/keyed_service/ios", + "//components/search_engines", + "//components/signin/core/browser", + "//components/signin/core/browser/webdata", + "//components/webdata_services", + "//ios/chrome/browser", + "//ios/chrome/browser/browser_state", + "//ios/web/public/thread", + ] +}
diff --git a/ios/chrome/browser/browser_state/web_data_service_factory.cc b/ios/chrome/browser/webdata_services/web_data_service_factory.cc similarity index 97% rename from ios/chrome/browser/browser_state/web_data_service_factory.cc rename to ios/chrome/browser/webdata_services/web_data_service_factory.cc index e3288863..62633b2 100644 --- a/ios/chrome/browser/browser_state/web_data_service_factory.cc +++ b/ios/chrome/browser/webdata_services/web_data_service_factory.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/chrome/browser/browser_state/web_data_service_factory.h" +#include "ios/chrome/browser/webdata_services/web_data_service_factory.h" #include "base/bind.h" #include "base/bind_helpers.h"
diff --git a/ios/chrome/browser/browser_state/web_data_service_factory.h b/ios/chrome/browser/webdata_services/web_data_service_factory.h similarity index 92% rename from ios/chrome/browser/browser_state/web_data_service_factory.h rename to ios/chrome/browser/webdata_services/web_data_service_factory.h index 79ed343..3d8d62a 100644 --- a/ios/chrome/browser/browser_state/web_data_service_factory.h +++ b/ios/chrome/browser/webdata_services/web_data_service_factory.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_CHROME_BROWSER_BROWSER_STATE_WEB_DATA_SERVICE_FACTORY_H_ -#define IOS_CHROME_BROWSER_BROWSER_STATE_WEB_DATA_SERVICE_FACTORY_H_ +#ifndef IOS_CHROME_BROWSER_WEBDATA_SERVICES_WEB_DATA_SERVICE_FACTORY_H_ +#define IOS_CHROME_BROWSER_WEBDATA_SERVICES_WEB_DATA_SERVICE_FACTORY_H_ #include <memory> @@ -78,4 +78,4 @@ } // namespace ios -#endif // IOS_CHROME_BROWSER_BROWSER_STATE_WEB_DATA_SERVICE_FACTORY_H_ +#endif // IOS_CHROME_BROWSER_WEBDATA_SERVICES_WEB_DATA_SERVICE_FACTORY_H_
diff --git a/ios/public/provider/chrome/browser/signin/chrome_identity.h b/ios/public/provider/chrome/browser/signin/chrome_identity.h index c755a07..94e4169 100644 --- a/ios/public/provider/chrome/browser/signin/chrome_identity.h +++ b/ios/public/provider/chrome/browser/signin/chrome_identity.h
@@ -28,6 +28,12 @@ // between apps. @property(strong, nonatomic, readonly) NSString* hashedGaiaID; +// Returns the cached hosted domain for the identity (fetched asynchronously). +// If the value has not been fetched, this property will be nil. Otherwise it +// will be the hosted domain or an empty string if the account is a consumer +// account (e.g. gmail.com). +@property(strong, nonatomic, readonly) NSString* hostedDomain; + @end #endif // IOS_PUBLIC_PROVIDER_CHROME_BROWSER_SIGNIN_CHROME_IDENTITY_H_
diff --git a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc index 4e2d8bcd2..efe7fc7 100644 --- a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
@@ -118,6 +118,14 @@ : frame(frame), force_keyframe(force_keyframe) {} V4L2VideoEncodeAccelerator::InputFrameInfo::InputFrameInfo( + scoped_refptr<VideoFrame> frame, + bool force_keyframe, + size_t index) + : frame(std::move(frame)), + force_keyframe(force_keyframe), + ip_output_buffer_index(index) {} + +V4L2VideoEncodeAccelerator::InputFrameInfo::InputFrameInfo( const InputFrameInfo&) = default; V4L2VideoEncodeAccelerator::InputFrameInfo::~InputFrameInfo() {} @@ -145,9 +153,6 @@ DCHECK(!encoder_thread_.IsRunning()); DCHECK(!device_poll_thread_.IsRunning()); VLOGF(2); - - DestroyInputBuffers(); - DestroyOutputBuffers(); } bool V4L2VideoEncodeAccelerator::Initialize(const Config& config, @@ -185,7 +190,7 @@ if (!is_flush_supported_) VLOGF(2) << "V4L2_ENC_CMD_STOP is not supported."; - struct v4l2_capability caps{}; + struct v4l2_capability caps {}; const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps); if ((caps.capabilities & kCapsRequired) != kCapsRequired) { @@ -193,9 +198,30 @@ return false; } + if (!encoder_thread_.Start()) { + VLOGF(1) << "encoder thread failed to start"; + return false; + } + + bool result = false; + base::WaitableEvent done; + encoder_thread_.task_runner()->PostTask( + FROM_HERE, + base::BindOnce(&V4L2VideoEncodeAccelerator::InitializeTask, + base::Unretained(this), config, &result, &done)); + done.Wait(); + return result; +} + +void V4L2VideoEncodeAccelerator::InitializeTask(const Config& config, + bool* result, + base::WaitableEvent* done) { + DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread()); + *result = false; if (!SetFormats(config.input_format, config.output_profile)) { VLOGF(1) << "Failed setting up formats"; - return false; + done->Signal(); + return; } if (config.input_format != device_input_layout_->format()) { @@ -210,84 +236,35 @@ VideoFrame::NumPlanes(config.input_format))); if (!input_layout) { VLOGF(1) << "Invalid image processor input layout"; - return false; + done->Signal(); + return; } - // Convert from |config.input_format| to |device_input_layout_->format()|, - // keeping the size at |visible_size_| and requiring the output buffers to - // be of at least |device_input_layout_->coded_size()|. - // Unretained(this) is safe in creating ErrorCB because - // V4L2VideoEncodeAccelerator instance outlives |image_processor_| and - // ImageProcessor invalidates posted ErrorCB when its Reset() or destructor - // is called. - // |input_storage_type| can be STORAGE_SHMEM and STORAGE_MOJO_SHARED_BUFFER. - // However, it doesn't matter VideoFrame::STORAGE_OWNED_MEMORY is specified - // for |input_storage_type| here, as long as VideoFrame on Process()'s data - // can be accessed by VideoFrame::data(). - image_processor_ = ImageProcessorFactory::Create( - ImageProcessor::PortConfig(*input_layout, visible_size_, - {VideoFrame::STORAGE_OWNED_MEMORY}), - ImageProcessor::PortConfig( - *device_input_layout_, visible_size_, - {VideoFrame::STORAGE_DMABUFS, VideoFrame::STORAGE_OWNED_MEMORY}), - // Try OutputMode::ALLOCATE first because we want v4l2IP chooses - // ALLOCATE mode. For libyuvIP, it accepts only IMPORT. - {ImageProcessor::OutputMode::ALLOCATE, - ImageProcessor::OutputMode::IMPORT}, - kImageProcBufferCount, - // We have to bind |weak_this| for ImageProcessorError, because child - // thread is outlive this V4L2VideoEncodeAccelerator. - base::BindRepeating(&V4L2VideoEncodeAccelerator::ImageProcessorError, - weak_this_)); - if (!image_processor_) { - VLOGF(1) << "Failed initializing image processor"; - return false; + if (!CreateImageProcessor(*input_layout, *device_input_layout_, + visible_size_)) { + VLOGF(1) << "Failed to create image processor"; + done->Signal(); + return; } - // The output of image processor is the input of encoder. Output coded - // width of processor must be the same as input coded width of encoder. - // Output coded height of processor can be larger but not smaller than the - // input coded height of encoder. For example, suppose input size of encoder - // is 320x193. It is OK if the output of processor is 320x208. - if (image_processor_->output_layout().coded_size().width() != - device_input_layout_->coded_size().width() || - image_processor_->output_layout().coded_size().height() < - device_input_layout_->coded_size().height()) { - VLOGF(1) << "Invalid image processor output coded size " - << image_processor_->output_layout().coded_size().ToString() - << ", encode input coded size is " - << device_input_layout_->coded_size().ToString(); - return false; - } - - // Initialize |free_image_processor_output_buffer_indices_|. - free_image_processor_output_buffer_indices_.resize(kImageProcBufferCount); - std::iota(free_image_processor_output_buffer_indices_.begin(), - free_image_processor_output_buffer_indices_.end(), 0); - - if (!AllocateImageProcessorOutputBuffers()) - return false; } - if (!InitInputMemoryType(config)) - return false; - - if (!InitControls(config)) - return false; - - if (!CreateOutputBuffers()) - return false; - - if (!encoder_thread_.Start()) { - VLOGF(1) << "encoder thread failed to start"; - return false; + if (!InitInputMemoryType(config)) { + done->Signal(); + return; } - - RequestEncodingParametersChange( - config.initial_bitrate, config.initial_framerate.value_or( - VideoEncodeAccelerator::kDefaultFramerate)); + if (!InitControls(config)) { + done->Signal(); + return; + } + if (!CreateOutputBuffers()) { + done->Signal(); + return; + } encoder_state_ = kInitialized; - + RequestEncodingParametersChangeTask( + config.initial_bitrate, config.initial_framerate.value_or( + VideoEncodeAccelerator::kDefaultFramerate)); child_task_runner_->PostTask( FROM_HERE, base::BindOnce( @@ -295,23 +272,87 @@ image_processor_.get() ? image_processor_->input_layout().coded_size() : input_allocated_size_, output_buffer_byte_size_)); - return true; + + // Finish initialization. + *result = true; + done->Signal(); } -bool V4L2VideoEncodeAccelerator::AllocateImageProcessorOutputBuffers() { +bool V4L2VideoEncodeAccelerator::CreateImageProcessor( + const VideoFrameLayout& input_layout, + const VideoFrameLayout& output_layout, + const gfx::Size& visible_size) { + VLOGF(2); + DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread()); + DCHECK_NE(input_layout.format(), output_layout.format()); + + // Convert from |config.input_format| to |device_input_layout_->format()|, + // keeping the size at |visible_size| and requiring the output buffers to + // be of at least |device_input_layout_->coded_size()|. + // |input_storage_type| can be STORAGE_SHMEM and STORAGE_MOJO_SHARED_BUFFER. + // However, it doesn't matter VideoFrame::STORAGE_OWNED_MEMORY is specified + // for |input_storage_type| here, as long as VideoFrame on Process()'s data + // can be accessed by VideoFrame::data(). + image_processor_ = ImageProcessorFactory::Create( + ImageProcessor::PortConfig(input_layout, visible_size, + {VideoFrame::STORAGE_OWNED_MEMORY}), + ImageProcessor::PortConfig( + output_layout, visible_size, + {VideoFrame::STORAGE_DMABUFS, VideoFrame::STORAGE_OWNED_MEMORY}), + // Try OutputMode::ALLOCATE first because we want v4l2IP chooses + // ALLOCATE mode. For libyuvIP, it accepts only IMPORT. + {ImageProcessor::OutputMode::ALLOCATE, + ImageProcessor::OutputMode::IMPORT}, + kImageProcBufferCount, + // Unretained(this) is safe here, because image_processor is destroyed + // before video_encoder_thread stops. + BindToCurrentLoop( + base::BindRepeating(&V4L2VideoEncodeAccelerator::ImageProcessorError, + base::Unretained(this)))); + if (!image_processor_) { + VLOGF(1) << "Failed initializing image processor"; + return false; + } + + // The output of image processor is the input of encoder. Output coded + // width of processor must be the same as input coded width of encoder. + // Output coded height of processor can be larger but not smaller than the + // input coded height of encoder. For example, suppose input size of encoder + // is 320x193. It is OK if the output of processor is 320x208. + const auto& ip_output_size = image_processor_->output_layout().coded_size(); + if (ip_output_size.width() != output_layout.coded_size().width() || + ip_output_size.height() < output_layout.coded_size().height()) { + VLOGF(1) << "Invalid image processor output coded size " + << ip_output_size.ToString() << ", expected output coded size is " + << output_layout.coded_size().ToString(); + return false; + } + + // Initialize |free_image_processor_output_buffer_indices_|. + free_image_processor_output_buffer_indices_.resize(kImageProcBufferCount); + std::iota(free_image_processor_output_buffer_indices_.begin(), + free_image_processor_output_buffer_indices_.end(), 0); + return AllocateImageProcessorOutputBuffers(kImageProcBufferCount, + visible_size); +} + +bool V4L2VideoEncodeAccelerator::AllocateImageProcessorOutputBuffers( + size_t count, + const gfx::Size& visible_size) { + DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread()); DCHECK(image_processor_); // Allocate VideoFrames for image processor output if its mode is IMPORT. if (image_processor_->output_mode() != ImageProcessor::OutputMode::IMPORT) { return true; } - image_processor_output_buffers_.resize(kImageProcBufferCount); + image_processor_output_buffers_.resize(count); const auto output_storage_type = image_processor_->output_storage_type(); - for (size_t i = 0; i < kImageProcBufferCount; i++) { + for (size_t i = 0; i < count; i++) { switch (output_storage_type) { case VideoFrame::STORAGE_OWNED_MEMORY: image_processor_output_buffers_[i] = VideoFrame::CreateFrameWithLayout( - *device_input_layout_, gfx::Rect(visible_size_), visible_size_, + *device_input_layout_, gfx::Rect(visible_size), visible_size, base::TimeDelta(), true); if (!image_processor_output_buffers_[i]) { VLOG(1) << "Failed to create VideoFrame"; @@ -329,6 +370,7 @@ } bool V4L2VideoEncodeAccelerator::InitInputMemoryType(const Config& config) { + DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread()); if (image_processor_) { const auto storage_type = image_processor_->output_storage_type(); if (storage_type == VideoFrame::STORAGE_DMABUFS) { @@ -354,7 +396,7 @@ } void V4L2VideoEncodeAccelerator::ImageProcessorError() { - DCHECK(child_task_runner_->BelongsToCurrentThread()); + DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread()); VLOGF(1) << "Image processor error"; NOTIFY_ERROR(kPlatformFailureError); } @@ -364,51 +406,10 @@ DVLOGF(4) << "force_keyframe=" << force_keyframe; DCHECK(child_task_runner_->BelongsToCurrentThread()); - if (image_processor_) { - if (!free_image_processor_output_buffer_indices_.empty()) { - // Create a VideoFrame by wrapping an instance from - // |image_processor_output_buffers_|. The new VideoFrame has its own life - // cycle but shares underlying payload from the VideoFrame being wrapped. - // When the VideoEncodeAccelerator finish processing ImageProcessor's - // output frame, the frame is no longer referenced, hence trigger - // destruction observer to recycle the frame. - const size_t output_buffer_index = - free_image_processor_output_buffer_indices_.back(); - free_image_processor_output_buffer_indices_.pop_back(); - if (image_processor_->output_mode() == - ImageProcessor::OutputMode::IMPORT) { - const auto& buf = image_processor_output_buffers_[output_buffer_index]; - auto output_frame = VideoFrame::WrapVideoFrame( - *buf, buf->format(), buf->visible_rect(), buf->natural_size()); - - // We have to bind |weak_this| for FrameProcessed, because child - // thread is outlive this V4L2VideoEncodeAccelerator. - if (!image_processor_->Process( - frame, std::move(output_frame), - base::BindOnce(&V4L2VideoEncodeAccelerator::FrameProcessed, - weak_this_, force_keyframe, frame->timestamp(), - output_buffer_index))) { - NOTIFY_ERROR(kPlatformFailureError); - } - } else { - // We have to bind |weak_this| for FrameProcessed, because child - // thread is outlive this V4L2VideoEncodeAccelerator. - if (!image_processor_->Process( - frame, base::BindOnce( - &V4L2VideoEncodeAccelerator::FrameProcessed, - weak_this_, force_keyframe, frame->timestamp()))) { - NOTIFY_ERROR(kPlatformFailureError); - } - } - } else { - image_processor_input_queue_.emplace(std::move(frame), force_keyframe); - } - } else { - encoder_thread_.task_runner()->PostTask( - FROM_HERE, base::BindOnce(&V4L2VideoEncodeAccelerator::EncodeTask, - base::Unretained(this), std::move(frame), - force_keyframe)); - } + encoder_thread_.task_runner()->PostTask( + FROM_HERE, + base::BindOnce(&V4L2VideoEncodeAccelerator::EncodeTask, + base::Unretained(this), std::move(frame), force_keyframe)); } void V4L2VideoEncodeAccelerator::UseOutputBitstreamBuffer( @@ -416,24 +417,10 @@ DVLOGF(4) << "id=" << buffer.id(); DCHECK(child_task_runner_->BelongsToCurrentThread()); - if (buffer.size() < output_buffer_byte_size_) { - NOTIFY_ERROR(kInvalidArgumentError); - return; - } - - auto shm = std::make_unique<UnalignedSharedMemory>(buffer.TakeRegion(), - buffer.size(), false); - if (!shm->MapAt(buffer.offset(), buffer.size())) { - NOTIFY_ERROR(kPlatformFailureError); - return; - } - - std::unique_ptr<BitstreamBufferRef> buffer_ref( - new BitstreamBufferRef(buffer.id(), std::move(shm))); encoder_thread_.task_runner()->PostTask( FROM_HERE, base::BindOnce(&V4L2VideoEncodeAccelerator::UseOutputBitstreamBufferTask, - base::Unretained(this), std::move(buffer_ref))); + base::Unretained(this), std::move(buffer))); } void V4L2VideoEncodeAccelerator::RequestEncodingParametersChange( @@ -457,8 +444,6 @@ client_ptr_factory_.reset(); weak_this_ptr_factory_.InvalidateWeakPtrs(); - image_processor_ = nullptr; - // If the encoder thread is running, destroy using posted task. if (encoder_thread_.IsRunning()) { encoder_thread_.task_runner()->PostTask( @@ -526,38 +511,31 @@ base::TimeDelta timestamp, size_t output_buffer_index, scoped_refptr<VideoFrame> frame) { - DCHECK(child_task_runner_->BelongsToCurrentThread()); + DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread()); DVLOGF(4) << "force_keyframe=" << force_keyframe << ", output_buffer_index=" << output_buffer_index; DCHECK_GE(output_buffer_index, 0u); - DCHECK(encoder_thread_.IsRunning()); - DCHECK(!weak_this_.WasInvalidated()); - frame->AddDestructionObserver(BindToCurrentLoop(base::BindOnce( - &V4L2VideoEncodeAccelerator::ReuseImageProcessorOutputBuffer, weak_this_, - output_buffer_index))); - + encoder_input_queue_.emplace(std::move(frame), force_keyframe, + output_buffer_index); encoder_thread_.task_runner()->PostTask( - FROM_HERE, base::BindOnce(&V4L2VideoEncodeAccelerator::EncodeTask, - base::Unretained(this), frame, force_keyframe)); + FROM_HERE, base::BindOnce(&V4L2VideoEncodeAccelerator::Enqueue, + base::Unretained(this))); } void V4L2VideoEncodeAccelerator::ReuseImageProcessorOutputBuffer( size_t output_buffer_index) { - DCHECK(child_task_runner_->BelongsToCurrentThread()); + DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread()); DVLOGF(4) << "output_buffer_index=" << output_buffer_index; free_image_processor_output_buffer_indices_.push_back(output_buffer_index); - if (!image_processor_input_queue_.empty()) { - InputFrameInfo frame_info = image_processor_input_queue_.front(); - image_processor_input_queue_.pop(); - Encode(frame_info.frame, frame_info.force_keyframe); - } + InputImageProcessorTask(); } size_t V4L2VideoEncodeAccelerator::CopyIntoOutputBuffer( const uint8_t* bitstream_data, size_t bitstream_size, std::unique_ptr<BitstreamBufferRef> buffer_ref) { + DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread()); uint8_t* dst_ptr = static_cast<uint8_t*>(buffer_ref->shm->memory()); size_t remaining_dst_size = buffer_ref->shm->size(); @@ -635,16 +613,73 @@ return; } - encoder_input_queue_.emplace(std::move(frame), force_keyframe); - Enqueue(); + if (image_processor_) { + image_processor_input_queue_.emplace(std::move(frame), force_keyframe); + InputImageProcessorTask(); + } else { + encoder_input_queue_.emplace(std::move(frame), force_keyframe); + Enqueue(); + } +} + +void V4L2VideoEncodeAccelerator::InputImageProcessorTask() { + if (free_image_processor_output_buffer_indices_.empty()) + return; + if (image_processor_input_queue_.empty()) + return; + const size_t output_buffer_index = + free_image_processor_output_buffer_indices_.back(); + free_image_processor_output_buffer_indices_.pop_back(); + + InputFrameInfo frame_info = std::move(image_processor_input_queue_.front()); + image_processor_input_queue_.pop(); + auto frame = std::move(frame_info.frame); + const bool force_keyframe = frame_info.force_keyframe; + auto timestamp = frame->timestamp(); + if (image_processor_->output_mode() == ImageProcessor::OutputMode::IMPORT) { + const auto& buf = image_processor_output_buffers_[output_buffer_index]; + auto output_frame = VideoFrame::WrapVideoFrame( + *buf, buf->format(), buf->visible_rect(), buf->natural_size()); + + // Unretained(this) is safe here, because image_processor is destroyed + // before video_encoder_thread stops. + if (!image_processor_->Process( + std::move(frame), std::move(output_frame), + BindToCurrentLoop( + base::BindOnce(&V4L2VideoEncodeAccelerator::FrameProcessed, + base::Unretained(this), force_keyframe, + timestamp, output_buffer_index)))) { + NOTIFY_ERROR(kPlatformFailureError); + } + } else { + if (!image_processor_->Process( + std::move(frame), + BindToCurrentLoop(base::BindOnce( + &V4L2VideoEncodeAccelerator::FrameProcessed, + base::Unretained(this), force_keyframe, timestamp)))) { + NOTIFY_ERROR(kPlatformFailureError); + } + } } void V4L2VideoEncodeAccelerator::UseOutputBitstreamBufferTask( - std::unique_ptr<BitstreamBufferRef> buffer_ref) { - DVLOGF(4) << "id=" << buffer_ref->id; + BitstreamBuffer buffer) { + DVLOGF(4) << "id=" << buffer.id(); DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread()); - encoder_output_queue_.push_back(std::move(buffer_ref)); + if (buffer.size() < output_buffer_byte_size_) { + NOTIFY_ERROR(kInvalidArgumentError); + return; + } + auto shm = std::make_unique<UnalignedSharedMemory>(buffer.TakeRegion(), + buffer.size(), false); + if (!shm->MapAt(buffer.offset(), buffer.size())) { + NOTIFY_ERROR(kPlatformFailureError); + return; + } + + encoder_output_queue_.push_back( + std::make_unique<BitstreamBufferRef>(buffer.id(), std::move(shm))); Enqueue(); if (encoder_state_ == kInitialized) { @@ -668,6 +703,13 @@ // Set our state to kError, and early-out all tasks. encoder_state_ = kError; + + if (encoder_thread_.task_runner() && + encoder_thread_.task_runner()->BelongsToCurrentThread()) { + DestroyInputBuffers(); + DestroyOutputBuffers(); + image_processor_ = nullptr; + } } void V4L2VideoEncodeAccelerator::ServiceDeviceTask() { @@ -819,6 +861,8 @@ input_record.at_device = false; input_record.frame = NULL; + if (input_record.ip_output_buffer_index) + ReuseImageProcessorOutputBuffer(*input_record.ip_output_buffer_index); free_input_buffers_.push_back(dqbuf.index); input_buffer_queued_count_--; } @@ -890,6 +934,7 @@ bool V4L2VideoEncodeAccelerator::EnqueueInputRecord() { DVLOGF(4); + DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread()); DCHECK(!free_input_buffers_.empty()); DCHECK(!encoder_input_queue_.empty()); TRACE_EVENT0("media,gpu", "V4L2VEA::EnqueueInputRecord"); @@ -977,6 +1022,7 @@ IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QBUF, &qbuf); input_record.at_device = true; input_record.frame = frame; + input_record.ip_output_buffer_index = frame_info.ip_output_buffer_index; encoder_input_queue_.pop(); free_input_buffers_.pop_back(); input_buffer_queued_count_++; @@ -985,6 +1031,7 @@ bool V4L2VideoEncodeAccelerator::EnqueueOutputRecord() { DVLOGF(4); + DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread()); DCHECK(!free_output_buffers_.empty()); DCHECK(!encoder_output_queue_.empty()); TRACE_EVENT0("media,gpu", "V4L2VEA::EnqueueOutputRecord"); @@ -1166,7 +1213,7 @@ bool V4L2VideoEncodeAccelerator::SetOutputFormat( VideoCodecProfile output_profile) { - DCHECK(child_task_runner_->BelongsToCurrentThread()); + DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread()); DCHECK(!input_streamon_); DCHECK(!output_streamon_); @@ -1195,7 +1242,7 @@ bool V4L2VideoEncodeAccelerator::NegotiateInputFormat( VideoPixelFormat input_format) { VLOGF(2); - DCHECK(child_task_runner_->BelongsToCurrentThread()); + DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread()); DCHECK(!input_streamon_); DCHECK(!output_streamon_); @@ -1251,7 +1298,7 @@ bool V4L2VideoEncodeAccelerator::SetFormats(VideoPixelFormat input_format, VideoCodecProfile output_profile) { VLOGF(2); - DCHECK(child_task_runner_->BelongsToCurrentThread()); + DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread()); DCHECK(!input_streamon_); DCHECK(!output_streamon_); @@ -1295,6 +1342,7 @@ } bool V4L2VideoEncodeAccelerator::IsCtrlExposed(uint32_t ctrl_id) { + DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread()); struct v4l2_queryctrl query_ctrl{}; query_ctrl.id = ctrl_id; @@ -1303,6 +1351,7 @@ bool V4L2VideoEncodeAccelerator::SetExtCtrls( std::vector<struct v4l2_ext_control> ctrls) { + DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread()); struct v4l2_ext_controls ext_ctrls{}; ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG; ext_ctrls.count = ctrls.size(); @@ -1311,6 +1360,7 @@ } bool V4L2VideoEncodeAccelerator::InitControls(const Config& config) { + DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread()); std::vector<struct v4l2_ext_control> ctrls; struct v4l2_ext_control ctrl{}; @@ -1432,8 +1482,6 @@ bool V4L2VideoEncodeAccelerator::CreateInputBuffers() { VLOGF(2); - // This function runs on encoder_thread_ after output buffers have been - // provided by the client. DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread()); DCHECK(!input_streamon_); @@ -1454,7 +1502,7 @@ bool V4L2VideoEncodeAccelerator::CreateOutputBuffers() { VLOGF(2); - DCHECK(child_task_runner_->BelongsToCurrentThread()); + DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread()); DCHECK(!output_streamon_); struct v4l2_requestbuffers reqbufs{}; @@ -1493,7 +1541,7 @@ void V4L2VideoEncodeAccelerator::DestroyInputBuffers() { VLOGF(2); - DCHECK(child_task_runner_->BelongsToCurrentThread()); + DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread()); DCHECK(!input_streamon_); free_input_buffers_.clear(); @@ -1512,7 +1560,7 @@ void V4L2VideoEncodeAccelerator::DestroyOutputBuffers() { VLOGF(2); - DCHECK(child_task_runner_->BelongsToCurrentThread()); + DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread()); DCHECK(!output_streamon_); free_output_buffers_.clear();
diff --git a/media/gpu/v4l2/v4l2_video_encode_accelerator.h b/media/gpu/v4l2/v4l2_video_encode_accelerator.h index 05a88fab..f52ba96 100644 --- a/media/gpu/v4l2/v4l2_video_encode_accelerator.h +++ b/media/gpu/v4l2/v4l2_video_encode_accelerator.h
@@ -70,6 +70,10 @@ ~InputRecord(); bool at_device; scoped_refptr<VideoFrame> frame; + + // This is valid only if image processor is used. The buffer associated with + // this index can be reused in Dequeue(). + base::Optional<size_t> ip_output_buffer_index; }; // Record for output buffers. @@ -86,10 +90,17 @@ struct InputFrameInfo { InputFrameInfo(); InputFrameInfo(scoped_refptr<VideoFrame> frame, bool force_keyframe); + InputFrameInfo(scoped_refptr<VideoFrame> frame, + bool force_keyframe, + size_t index); InputFrameInfo(const InputFrameInfo&); ~InputFrameInfo(); scoped_refptr<VideoFrame> frame; bool force_keyframe; + + // This is valid only if image processor is used. This info needs to be + // propagated to InputRecord. + base::Optional<size_t> ip_output_buffer_index; }; enum { @@ -130,8 +141,7 @@ // Add a BitstreamBuffer to the queue of buffers ready to be used for encoder // output. - void UseOutputBitstreamBufferTask( - std::unique_ptr<BitstreamBufferRef> buffer_ref); + void UseOutputBitstreamBufferTask(BitstreamBuffer buffer); // Device destruction task. void DestroyTask(); @@ -178,10 +188,24 @@ // these (e.g. in Initialize() or Destroy()). // + // Create image processor that will process input_layout to output_layout. The + // visible size of processed video frames are |visible_size|. + bool CreateImageProcessor(const VideoFrameLayout& input_layout, + const VideoFrameLayout& output_layout, + const gfx::Size& visible_size); + // Process one video frame in |image_processor_input_queue_| by + // |image_processor_|. + void InputImageProcessorTask(); + // Change encoding parameters. void RequestEncodingParametersChangeTask(uint32_t bitrate, uint32_t framerate); + // Do several initializations (e.g. set up format) on |encoder_thread_|. + void InitializeTask(const Config& config, + bool* result, + base::WaitableEvent* done); + // Set up formats and initialize the device for them. bool SetFormats(VideoPixelFormat input_format, VideoCodecProfile output_profile); @@ -212,9 +236,10 @@ // false otherwise. bool IsCtrlExposed(uint32_t ctrl_id); - // Allocates video frames for image processor's output buffers. - // Returns false if there's something wrong. - bool AllocateImageProcessorOutputBuffers(); + // Allocates |count| video frames with |visible_size| for image processor's + // output buffers. Returns false if there's something wrong. + bool AllocateImageProcessorOutputBuffers(size_t count, + const gfx::Size& visible_size); // Recycle output buffer of image processor with |output_buffer_index|. void ReuseImageProcessorOutputBuffer(size_t output_buffer_index);
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc index 30cf28a..e2399f4 100644 --- a/pdf/pdfium/pdfium_engine.cc +++ b/pdf/pdfium/pdfium_engine.cc
@@ -3023,7 +3023,8 @@ visible_selection.Offset(-dirty_in_screen.point().x(), -dirty_in_screen.point().y()); - Highlight(region, stride, visible_selection, &highlighted_rects); + Highlight(region, stride, visible_selection, kHighlightColorR, + kHighlightColorG, kHighlightColorB, &highlighted_rects); } } @@ -3034,7 +3035,8 @@ visible_selection.Offset(-dirty_in_screen.point().x(), -dirty_in_screen.point().y()); - Highlight(region, stride, visible_selection, &highlighted_rects); + Highlight(region, stride, visible_selection, kHighlightColorR, + kHighlightColorG, kHighlightColorB, &highlighted_rects); } form_highlights_.clear(); } @@ -3139,6 +3141,9 @@ void PDFiumEngine::Highlight(void* buffer, int stride, const pp::Rect& rect, + int color_red, + int color_green, + int color_blue, std::vector<pp::Rect>* highlighted_rects) { if (!buffer) return; @@ -3175,9 +3180,9 @@ continue; uint8_t* pixel = static_cast<uint8_t*>(buffer) + y * stride + x * 4; - pixel[0] = static_cast<uint8_t>(pixel[0] * (kHighlightColorB / 255.0)); - pixel[1] = static_cast<uint8_t>(pixel[1] * (kHighlightColorG / 255.0)); - pixel[2] = static_cast<uint8_t>(pixel[2] * (kHighlightColorR / 255.0)); + pixel[0] = static_cast<uint8_t>(pixel[0] * (color_blue / 255.0)); + pixel[1] = static_cast<uint8_t>(pixel[1] * (color_green / 255.0)); + pixel[2] = static_cast<uint8_t>(pixel[2] * (color_red / 255.0)); } } }
diff --git a/pdf/pdfium/pdfium_engine.h b/pdf/pdfium/pdfium_engine.h index e66201ad..96b7841 100644 --- a/pdf/pdfium/pdfium_engine.h +++ b/pdf/pdfium/pdfium_engine.h
@@ -399,6 +399,9 @@ void Highlight(void* buffer, int stride, const pp::Rect& rect, + int color_red, + int color_green, + int color_blue, std::vector<pp::Rect>* highlighted_rects); // Helper function to convert a device to page coordinates. If the page is
diff --git a/services/tracing/perfetto/producer_host.cc b/services/tracing/perfetto/producer_host.cc index 891773a..0958629 100644 --- a/services/tracing/perfetto/producer_host.cc +++ b/services/tracing/perfetto/producer_host.cc
@@ -141,11 +141,16 @@ // sanitization here because ProducerEndpoint::CommitData() (And any other // ProducerEndpoint methods) are designed to deal with malformed / malicious // inputs. -void ProducerHost::CommitData(const perfetto::CommitDataRequest& data_request) { +void ProducerHost::CommitData(const perfetto::CommitDataRequest& data_request, + CommitDataCallback callback) { if (on_commit_callback_for_testing_) { on_commit_callback_for_testing_.Run(data_request); } - producer_endpoint_->CommitData(data_request); + // This assumes that CommitData() will execute the callback synchronously. + producer_endpoint_->CommitData(data_request, [&callback]() { + std::move(callback).Run(); + }); + DCHECK(!callback); // Should have been run synchronously above. } void ProducerHost::RegisterDataSource(
diff --git a/services/tracing/perfetto/producer_host.h b/services/tracing/perfetto/producer_host.h index 91bb082..9d531482 100644 --- a/services/tracing/perfetto/producer_host.h +++ b/services/tracing/perfetto/producer_host.h
@@ -69,7 +69,8 @@ // This interface gets called by the per-process ProducerClients // to signal that there's changes to be committed to the // Shared Memory buffer (like finished chunks). - void CommitData(const perfetto::CommitDataRequest& data_request) override; + void CommitData(const perfetto::CommitDataRequest& data_request, + CommitDataCallback callback) override; // Called by the ProducerClient to signal the Host that it can // provide a specific data source.
diff --git a/services/tracing/public/cpp/perfetto/producer_client.cc b/services/tracing/public/cpp/perfetto/producer_client.cc index 0b521ee..51e00bb 100644 --- a/services/tracing/public/cpp/perfetto/producer_client.cc +++ b/services/tracing/public/cpp/perfetto/producer_client.cc
@@ -241,6 +241,12 @@ void ProducerClient::CommitData(const perfetto::CommitDataRequest& commit, CommitDataCallback callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + auto commit_callback = + callback ? base::BindOnce([](CommitDataCallback callback) { callback(); }, + callback) + : mojom::ProducerHost::CommitDataCallback(); + // We need to make sure the CommitData IPC is sent off without triggering any // trace events, as that could stall waiting for SMB chunks to be freed up // which requires the tracing service to receive the IPC. @@ -248,17 +254,11 @@ AutoThreadLocalBoolean thread_is_in_trace_event( TraceEventDataSource::GetThreadIsInTraceEventTLS()); - producer_host_->CommitData(commit); + producer_host_->CommitData(commit, std::move(commit_callback)); return; } - producer_host_->CommitData(commit); -} - -void ProducerClient::CommitDataOnSequence( - const perfetto::CommitDataRequest& request) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - producer_host_->CommitData(request); + producer_host_->CommitData(commit, std::move(commit_callback)); } perfetto::SharedMemory* ProducerClient::shared_memory() const {
diff --git a/services/tracing/public/cpp/perfetto/producer_client.h b/services/tracing/public/cpp/perfetto/producer_client.h index ecc8607..cf4f56c3 100644 --- a/services/tracing/public/cpp/perfetto/producer_client.h +++ b/services/tracing/public/cpp/perfetto/producer_client.h
@@ -97,7 +97,6 @@ private: friend class base::NoDestructor<ProducerClient>; - void CommitDataOnSequence(const perfetto::CommitDataRequest& request); void BindClientAndHostPipesOnSequence(mojom::ProducerClientRequest, mojom::ProducerHostPtrInfo);
diff --git a/services/tracing/public/mojom/perfetto_service.mojom b/services/tracing/public/mojom/perfetto_service.mojom index b9241b0..f6cbddb 100644 --- a/services/tracing/public/mojom/perfetto_service.mojom +++ b/services/tracing/public/mojom/perfetto_service.mojom
@@ -102,8 +102,9 @@ // 2) Patch data (i.e. apply diff) that has been previously copied into the // tracing buffer (if it's not been overwritten). // The service is robust in terms of tolerating malformed or malicious - // requests. - CommitData(CommitDataRequest data_request); + // requests. The callback is run after the service has handled the commit + // request. + CommitData(CommitDataRequest data_request) => (); // Called by a ProducerClient to let the Host know it can provide a specific // datasource.
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index ed2cca6..87e4f01 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -8154,8 +8154,7 @@ "scripts": [ { "name": "test_traffic_annotation_auditor", - "script": "test_traffic_annotation_auditor.py", - "swarming": {} + "script": "test_traffic_annotation_auditor.py" } ] },
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index 82ef370..5310f68 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -1733,10 +1733,16 @@ "../../chrome/android/monochrome/scripts/monochrome_apk_checker.py", "--chrome-apk", "apks/ChromeModernPublic.apk", + "--chrome-pathmap", + "apks/ChromeModernPublic.apk.pathmap.txt", "--system-webview-apk", "apks/SystemWebView.apk", + "--system-webview-pathmap", + "apks/SystemWebView.apk.pathmap.txt", "--monochrome-apk", "apks/MonochromePublic.apk", + "--monochrome-pathmap", + "apks/MonochromePublic.apk.pathmap.txt", ], "label": "//chrome/android/monochrome:monochrome_apk_checker", "script": "//testing/scripts/monochrome_apk_checker_wrapper.py",
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 57a94a0..a5b5fba 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -1703,9 +1703,6 @@ } }, 'linux-annotator-rel': { - 'mixins': [ - 'linux-trusty', - ], 'test_suites': { 'scripts': 'test_traffic_annotation_auditor_script', }
diff --git a/testing/scripts/monochrome_apk_checker_wrapper.py b/testing/scripts/monochrome_apk_checker_wrapper.py index a05f8bd..983c378 100755 --- a/testing/scripts/monochrome_apk_checker_wrapper.py +++ b/testing/scripts/monochrome_apk_checker_wrapper.py
@@ -9,14 +9,31 @@ import argparse import json +import os import sys import subprocess import time - import common +def _PathExists(path): + return path is not None and os.path.exists(path) + + +def _ForwardOptionalArgs(args): + forwardable_args = [] + if _PathExists(args.monochrome_pathmap): + forwardable_args += ['--monochrome-pathmap', args.monochrome_pathmap] + if _PathExists(args.chrome_pathmap): + forwardable_args += ['--chrome-pathmap', args.chrome_pathmap] + if _PathExists(args.system_webview_pathmap): + forwardable_args += [ + '--system-webview-pathmap', args.system_webview_pathmap + ] + return forwardable_args + + def main(): parser = argparse.ArgumentParser(prog='monochrome_apk_checker_wrapper') @@ -30,14 +47,27 @@ # Ignored, but required to satisfy the isolated_script interface. # We aren't a perf test, so don't have any perf output. parser.add_argument('--isolated-script-test-perf-output') + + # We must intercept the pathmap args since they are always passed by the + # trybots but the files in question may not actually exist (path shortening + # may not be enabled for all apks). Check if the files exist and forward the + # arg iff they are. + parser.add_argument( + '--monochrome-pathmap', help='The monochrome APK resources pathmap path.') + parser.add_argument( + '--chrome-pathmap', help='The chrome APK resources pathmap path.') + parser.add_argument( + '--system-webview-pathmap', + help='The system webview APK resources pathmap path.') + args, extra = parser.parse_known_args(sys.argv[1:]) if args.isolated_script_test_filter and ( 'monochrome_apk_checker' not in args.isolated_script_test_filter): - parser.error('isolated-script-test-filter has invalid test: %s' % ( - args.isolated_script_test_filter)) + parser.error('isolated-script-test-filter has invalid test: %s' % + (args.isolated_script_test_filter)) - cmd = [args.script] + extra + cmd = [args.script] + extra + _ForwardOptionalArgs(args) start_time = time.time() ret = subprocess.call(cmd)
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index e6259db..757a9d5 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -367,6 +367,7 @@ "web/mac/web_substring_util.h", "web/mac/web_substring_util.h", "web/modules/autofill/web_form_element_observer.h", + "web/modules/mediastream/local_media_stream_audio_source.h", "web/modules/mediastream/media_stream_constraints_util.h", "web/modules/mediastream/media_stream_constraints_util_sets.h", "web/modules/mediastream/media_stream_constraints_util_video_content.h",
diff --git a/third_party/blink/public/platform/DEPS b/third_party/blink/public/platform/DEPS index 91bd315..ec73d34 100644 --- a/third_party/blink/public/platform/DEPS +++ b/third_party/blink/public/platform/DEPS
@@ -23,6 +23,7 @@ "+build/build_config.h", "+cc", "+components/viz/common", + "+media/base/audio_capturer_source.h", "+media/base/audio_renderer_sink.h", "+media/base/video_transformation.h", "+mojo/public",
diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h index e5fdbad..5b29bbe 100644 --- a/third_party/blink/public/platform/platform.h +++ b/third_party/blink/public/platform/platform.h
@@ -41,6 +41,7 @@ #include "base/threading/thread.h" #include "base/time/time.h" #include "components/viz/common/surfaces/frame_sink_id.h" +#include "media/base/audio_capturer_source.h" #include "media/base/audio_renderer_sink.h" #include "mojo/public/cpp/system/data_pipe.h" #include "mojo/public/cpp/system/message_pipe.h" @@ -80,6 +81,7 @@ namespace media { struct AudioSinkParameters; +struct AudioSourceParameters; class GpuVideoAcceleratorFactories; } @@ -545,6 +547,13 @@ // called by platform/graphics/ is fine. virtual bool IsGpuCompositingDisabled() { return true; } + // Media stream ---------------------------------------------------- + virtual scoped_refptr<media::AudioCapturerSource> NewAudioCapturerSource( + blink::WebLocalFrame* web_frame, + const media::AudioSourceParameters& params) { + return nullptr; + } + // WebRTC ---------------------------------------------------------- // Creates a WebRTCPeerConnectionHandler for RTCPeerConnection.
diff --git a/content/renderer/media/stream/local_media_stream_audio_source.h b/third_party/blink/public/web/modules/mediastream/local_media_stream_audio_source.h similarity index 62% rename from content/renderer/media/stream/local_media_stream_audio_source.h rename to third_party/blink/public/web/modules/mediastream/local_media_stream_audio_source.h index c115e5b..2b77bf8 100644 --- a/content/renderer/media/stream/local_media_stream_audio_source.h +++ b/third_party/blink/public/web/modules/mediastream/local_media_stream_audio_source.h
@@ -2,24 +2,28 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_RENDERER_MEDIA_STREAM_LOCAL_MEDIA_STREAM_AUDIO_SOURCE_H_ -#define CONTENT_RENDERER_MEDIA_STREAM_LOCAL_MEDIA_STREAM_AUDIO_SOURCE_H_ +#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_LOCAL_MEDIA_STREAM_AUDIO_SOURCE_H_ +#define THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_LOCAL_MEDIA_STREAM_AUDIO_SOURCE_H_ + +#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h" #include <string> -#include "content/common/content_export.h" #include "media/base/audio_capturer_source.h" -#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h" +#include "third_party/blink/public/platform/web_common.h" -namespace content { +namespace blink { + +class WebLocalFrame; // Represents a local source of audio data generated by an AudioInputDevice. -// Uses content::AudioDeviceFactory to auto-create the AudioInputDevice, using -// the parameters and session ID found in MediaStreamDevice, just before the -// first track is connected. Audio data is transported directly to the tracks -// (i.e., there is no audio processing). -class CONTENT_EXPORT LocalMediaStreamAudioSource - : public blink::MediaStreamAudioSource, +// Uses content::AudioDeviceFactory (indirectly through +// blink::Platform::NewAudioRendererSink) to auto-create the AudioInputDevice, +// using the parameters and session ID found in MediaStreamDevice, just before +// the first track is connected. Audio data is transported directly to the +// tracks (i.e., there is no audio processing). +class BLINK_MODULES_EXPORT LocalMediaStreamAudioSource + : public MediaStreamAudioSource, public media::AudioCapturerSource::CaptureCallback { public: // |consumer_render_frame_id| references the RenderFrame that will consume the @@ -27,8 +31,8 @@ // ID are read from |device_info|. |requested_buffer_size| is the desired // buffer size for the audio hardware, a nullptr means to use the default. LocalMediaStreamAudioSource( - int consumer_render_frame_id, - const blink::MediaStreamDevice& device, + WebLocalFrame* web_frame, + const MediaStreamDevice& device, const int* requested_buffer_size, bool disable_local_echo, ConstraintsRepeatingCallback started_callback, @@ -37,7 +41,7 @@ ~LocalMediaStreamAudioSource() final; // MediaStreamAudioSource implementation. - void ChangeSourceImpl(const blink::MediaStreamDevice& new_device) final; + void ChangeSourceImpl(const MediaStreamDevice& new_device) final; private: // MediaStreamAudioSource implementation. @@ -53,9 +57,11 @@ void OnCaptureError(const std::string& message) final; void OnCaptureMuted(bool is_muted) final; - // The RenderFrame that will consume the audio data. Used when creating - // AudioInputDevices via the AudioDeviceFactory. - const int consumer_render_frame_id_; + // The WebLocalFrame that will consume the audio data. Used when creating + // AudioInputDevices via the AudioDeviceFactory (indirectly through + // blink::Platform). + class InternalFrame; + std::unique_ptr<InternalFrame> internal_consumer_frame_; // The device created by the AudioDeviceFactory in EnsureSourceIsStarted(). scoped_refptr<media::AudioCapturerSource> source_; @@ -70,6 +76,6 @@ DISALLOW_COPY_AND_ASSIGN(LocalMediaStreamAudioSource); }; -} // namespace content +} // namespace blink -#endif // CONTENT_RENDERER_MEDIA_STREAM_LOCAL_MEDIA_STREAM_AUDIO_SOURCE_H_ +#endif // THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_LOCAL_MEDIA_STREAM_AUDIO_SOURCE_H_
diff --git a/third_party/blink/renderer/bindings/BUILD.gn b/third_party/blink/renderer/bindings/BUILD.gn index 8b974c6..f52d1e4 100644 --- a/third_party/blink/renderer/bindings/BUILD.gn +++ b/third_party/blink/renderer/bindings/BUILD.gn
@@ -3,6 +3,7 @@ # found in the LICENSE file. import("//third_party/blink/renderer/bindings/scripts/scripts.gni") +import("//third_party/blink/renderer/build/scripts/scripts.gni") import("//third_party/blink/renderer/modules/modules_idl_files.gni") action("interfaces_info") { @@ -44,3 +45,32 @@ "//third_party/blink/renderer/bindings/modules:modules_global_objects", ] } + +blink_python_runner("web_idl_database") { + script = "$bindings_scripts_dir/build_web_idl_database.py" + + inputs = + [ + "$bindings_core_output_dir/web_idl_collection_for_core.pickle", + "$bindings_modules_output_dir/web_idl_collection_for_modules.pickle", + ] + web_idl_scripts + outputs = [ + "$bindings_output_dir/web_idl_database.pickle", + ] + + args = [ + "--output", + rebase_path("$bindings_output_dir/web_idl_database.pickle", root_build_dir), + "--", + rebase_path("$bindings_core_output_dir/web_idl_collection_for_core.pickle", + root_build_dir), + rebase_path( + "$bindings_modules_output_dir/web_idl_collection_for_modules.pickle", + root_build_dir), + ] + + deps = [ + "//third_party/blink/renderer/bindings/core:core_web_idl_collection", + "//third_party/blink/renderer/bindings/modules:modules_web_idl_collection", + ] +}
diff --git a/third_party/blink/renderer/bindings/scripts/build_web_idl_database.py b/third_party/blink/renderer/bindings/scripts/build_web_idl_database.py new file mode 100755 index 0000000..773130b --- /dev/null +++ b/third_party/blink/renderer/bindings/scripts/build_web_idl_database.py
@@ -0,0 +1,41 @@ +#!/usr/bin/python +# +# 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. + +"""Generates a data collection of IDL information per component. +This scripts parses IDL files and stores the result ASTs in a pickle file. +The output file may contain information about component, too. +""" + +import optparse +import utilities +from web_idl.idl_compiler import IdlCompiler +from web_idl import ir_builder +from web_idl.identifier_ir_map import IdentifierIRMap + + +def parse_options(): + parser = optparse.OptionParser() + parser.add_option('--output', type='string', + help='pickle file to write down') + options, args = parser.parse_args() + + if options.output is None: + parser.error('Must specify a pickle file to output using --output.') + + return options, args + + +def main(): + options, filepaths = parse_options() + ir_map = IdentifierIRMap() + ir_builder.load_and_register_idl_definitions(filepaths, ir_map) + idl_compiler = IdlCompiler(ir_map) + idl_database = idl_compiler.build_database() + utilities.write_pickle_file(options.output, idl_database) + + +if __name__ == '__main__': + main()
diff --git a/third_party/blink/renderer/bindings/scripts/generate_web_idl_database.py b/third_party/blink/renderer/bindings/scripts/generate_web_idl_database.py new file mode 100755 index 0000000..773130b --- /dev/null +++ b/third_party/blink/renderer/bindings/scripts/generate_web_idl_database.py
@@ -0,0 +1,41 @@ +#!/usr/bin/python +# +# 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. + +"""Generates a data collection of IDL information per component. +This scripts parses IDL files and stores the result ASTs in a pickle file. +The output file may contain information about component, too. +""" + +import optparse +import utilities +from web_idl.idl_compiler import IdlCompiler +from web_idl import ir_builder +from web_idl.identifier_ir_map import IdentifierIRMap + + +def parse_options(): + parser = optparse.OptionParser() + parser.add_option('--output', type='string', + help='pickle file to write down') + options, args = parser.parse_args() + + if options.output is None: + parser.error('Must specify a pickle file to output using --output.') + + return options, args + + +def main(): + options, filepaths = parse_options() + ir_map = IdentifierIRMap() + ir_builder.load_and_register_idl_definitions(filepaths, ir_map) + idl_compiler = IdlCompiler(ir_map) + idl_database = idl_compiler.build_database() + utilities.write_pickle_file(options.output, idl_database) + + +if __name__ == '__main__': + main()
diff --git a/third_party/blink/renderer/bindings/scripts/scripts.gni b/third_party/blink/renderer/bindings/scripts/scripts.gni index 2006df9..b9bf7b3 100644 --- a/third_party/blink/renderer/bindings/scripts/scripts.gni +++ b/third_party/blink/renderer/bindings/scripts/scripts.gni
@@ -68,16 +68,16 @@ "web_idl/enumeration.py", "web_idl/extended_attribute.py", "web_idl/identifier_ir_map.py", + "web_idl/idl_compiler.py", "web_idl/idl_reference_proxy.py", "web_idl/idl_types.py", "web_idl/includes.py", "web_idl/interface.py", + "web_idl/ir_builder.py", "web_idl/literal_token.py", "web_idl/namespace.py", "web_idl/operation.py", "web_idl/typedef.py", - "web_idl/utilities.py", - "web_idl/idl_definition_builder.py", ], "abspath")
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/common.py b/third_party/blink/renderer/bindings/scripts/web_idl/common.py index 152a27f..97f6da7 100644 --- a/third_party/blink/renderer/bindings/scripts/web_idl/common.py +++ b/third_party/blink/renderer/bindings/scripts/web_idl/common.py
@@ -16,6 +16,7 @@ identifier.""" def __init__(self, identifier): + assert isinstance(identifier, Identifier) self._identifier = identifier @property @@ -33,6 +34,8 @@ class can have extended attributes.""" def __init__(self, extended_attributes=None): + assert (extended_attributes is None + or isinstance(extended_attributes, ExtendedAttributes)) self._extended_attributes = extended_attributes or ExtendedAttributes() @property @@ -52,6 +55,8 @@ provide some information for code generators.""" def __init__(self, code_generator_info=None): + assert (code_generator_info is None + or isinstance(code_generator_info, CodeGeneratorInfo)) self._code_generator_info = code_generator_info or CodeGeneratorInfo() @property @@ -87,18 +92,19 @@ class WithComponent(object): - """WithComponent class is an interface to show which components this - object belongs to.""" + """ + Implements |components| which is a Blink-specific layering concept of + components, such as 'core' and 'modules'. - # The order of |_COMPONENTS| shows the order of their dependencies. - # DO NOT change the order. - _COMPONENTS = ( - 'core', - 'modules', - ) + A single IDL definition such as 'interface' may consist from multiple IDL + fragments like partial interfaces and mixins, which may exist across + Blink components. |components| is a list of Blink components of IDL + fragments that are involved into this object. + """ - def __init__(self, components): - self._components = components + def __init__(self, component): + assert isinstance(component, Component) + self._components = [component] @property def components(self): @@ -106,30 +112,75 @@ Returns a list of components' names where this definition is defined @return tuple(Component) """ - return self._components + return tuple(self._components) class DebugInfo(object): - """DebugInfo provides some information for debugging.""" + """Provides information useful for debugging.""" - def __init__(self, filepaths): - self._filepaths = tuple(filepaths) + class Location(object): + def __init__(self, filepath=None, line_number=None, + column_number=None): + assert filepath is None or isinstance(filepath, str) + assert line_number is None or isinstance(line_number, int) + assert column_number is None or isinstance(column_number, int) + self._filepath = filepath + self._line_number = line_number + self._column_number = column_number + + def __str__(self): + text = '{}'.format(self._filepath or '<<unknown path>>') + if self._line_number: + text += ':{}'.format(self._line_number) + if self._column_number: + text += ':{}'.format(self._column_number) + return text + + @property + def filepath(self): + return self._filepath + + @property + def line_number(self): + return self._line_number + + @property + def column_number(self): + return self._column_number + + def __init__(self, location=None): + assert location is None or isinstance(location, DebugInfo.Location) + location = location or DebugInfo.Location() + # The first entry is the primary location, e.g. location of non-partial + # interface. The rest is secondary locations, e.g. location of partial + # interfaces and mixins. + self._locations = [location] @property - def filepaths(self): + def location(self): """ - Returns a list of filepaths where this IDL definition comes from. - @return tuple(FilePath) + Returns the primary location, i.e. location of the main definition. + @return DebugInfo.Location """ - return self._filepaths + return self._locations[0] + + @property + def all_locations(self): + """ + Returns a list of locations of all related IDL definitions, including + partial definitions and mixins. + @return tuple(DebugInfo.Location) + """ + return tuple(self._locations) class WithDebugInfo(object): - """WithDebugInfo class is an interface that its inheritances can have DebugInfo.""" + """WithDebugInfo class is an interface that its inheritances can have + DebugInfo.""" def __init__(self, debug_info=None): - self._debug_info = debug_info or DebugInfo( - filepaths=('<<unspecified>>', )) + assert debug_info is None or isinstance(debug_info, DebugInfo) + self._debug_info = debug_info or DebugInfo() @property def debug_info(self): @@ -144,6 +195,7 @@ it points a function like object.""" def __init__(self, owner): + assert isinstance(owner, object) # None is okay self._owner = owner @property
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/enumeration.py b/third_party/blink/renderer/bindings/scripts/web_idl/enumeration.py index ef25fdb6..88cc4015 100644 --- a/third_party/blink/renderer/bindings/scripts/web_idl/enumeration.py +++ b/third_party/blink/renderer/bindings/scripts/web_idl/enumeration.py
@@ -19,6 +19,7 @@ WithComponent, WithDebugInfo): def __init__(self, identifier, + values, extended_attributes=None, code_generator_info=None, component=None, @@ -32,6 +33,9 @@ WithComponent.__init__(self, component) WithDebugInfo.__init__(self, debug_info) + assert isinstance(values, (list, tuple)) + self.values = tuple(values) + @property def values(self): """
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/identifier_ir_map.py b/third_party/blink/renderer/bindings/scripts/web_idl/identifier_ir_map.py index 03a20db9..9fb34cc 100644 --- a/third_party/blink/renderer/bindings/scripts/web_idl/identifier_ir_map.py +++ b/third_party/blink/renderer/bindings/scripts/web_idl/identifier_ir_map.py
@@ -128,8 +128,12 @@ irs = self.find_by_kind(ir.kind) assert ir not in irs[ir.identifier] else: - self.find_by_identifier(ir.identifier) - assert False + duplicated_ir = self.find_by_identifier(ir.identifier) + # We don't allow to declare a definition of an IDL definition in + # multiple places. + raise ValueError('{} {} is defined twice.\n {}\n {}'.format( + ir.kind, ir.identifier, ir.debug_info.location, + duplicated_ir.debug_info.location)) except KeyError: pass self.add(ir) @@ -153,8 +157,8 @@ else: assert identifier not in irs_per_kind, ( 'Duplicated definition: {}\n {}\n {}'.format( - identifier, ir.debug_info.filepaths, - irs_per_kind[identifier].debug_info.filepaths)) + identifier, ir.debug_info.location, + irs_per_kind[identifier].debug_info.location)) irs_per_kind[identifier] = ir def find_by_identifier(self, identifier, skip_current_phase=False):
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/idl_compiler.py b/third_party/blink/renderer/bindings/scripts/web_idl/idl_compiler.py new file mode 100644 index 0000000..898e506 --- /dev/null +++ b/third_party/blink/renderer/bindings/scripts/web_idl/idl_compiler.py
@@ -0,0 +1,78 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + + +class IdlCompiler(object): + """ + Compiles IRs of Web IDL definitions into a database. + + IdlCompiler works very closely with IRs. IdlCompiler resolves a lot of + things such as; merge partial definitions, merge mixins into an interface, + resolve inheritance, etc. These tasks must be done in order, and it's + represented with "(compilation) phase". + + IdlCompiler works proceeding one phase to next phase. A basic strategy is + like below. + + 1. prev_phase = self._ir_map.current_phase, next_phase = prev_phase + 1 + 2. for x = an IR in self._ir_map(phase=prev_phase) + 2.1. y = process_and_update(x.copy()) + 2.2. self._ir_map(phase=next_phase).add(y) + + Note that an old IR for 'x' remains internally. See IdentifierIRMap for + the details. + """ + + def __init__(self, ir_map): + self._ir_map = ir_map + + def build_database(self): + self._merge_partials() + self._merge_mixins() + self._resolve_inheritances() + self._resolve_exposures() + self._define_unions() + self._generate_database() + + def _generate_database(self): + """ + Returns an IDL database based on this compiler. + """ + pass + + def _merge_partials(self): + """ + Merges partial definitions with corresponding non-partial definitions. + """ + self._ir_map.move_to_new_phase() + # TODO(peria): Implement this. http:///crbug.com/839389 + + def _merge_mixins(self): + """ + Merges mixins with interfaces that connected with includes statements. + """ + self._ir_map.move_to_new_phase() + # TODO(peria): Implement this. http:///crbug.com/839389 + + def _resolve_inheritances(self): + """ + Resolves inheritances and [Unforgeable] + """ + self._ir_map.move_to_new_phase() + # TODO(peria): Implement this. http:///crbug.com/839389 + + def _resolve_exposures(self): + """ + Links [Exposed] interfaces/namespaces with [Global] interfaces + """ + self._ir_map.move_to_new_phase() + # TODO(peria): Implement this. http:///crbug.com/839389 + + def _define_unions(self): + """ + Create a definition of union, that is unique in union types that have + same flattened-like members. + """ + self._ir_map.move_to_new_phase() + # TODO(peria): Implement this. http:///crbug.com/839389
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/includes.py b/third_party/blink/renderer/bindings/scripts/web_idl/includes.py index 09ed9384..d0ed04a 100644 --- a/third_party/blink/renderer/bindings/scripts/web_idl/includes.py +++ b/third_party/blink/renderer/bindings/scripts/web_idl/includes.py
@@ -16,6 +16,7 @@ WithDebugInfo): def __init__(self, interface_identifier, + mixin_identifier, code_generator_info=None, component=None, debug_info=None): @@ -33,6 +34,9 @@ WithComponent.__init__(self, component) WithDebugInfo.__init__(self, debug_info) + self.interafce_identifier = interface_identifier + self.mixin_identifier = mixin_identifier + @property def interface(self): """
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/ir_builder.py b/third_party/blink/renderer/bindings/scripts/web_idl/ir_builder.py new file mode 100644 index 0000000..1eab6fc --- /dev/null +++ b/third_party/blink/renderer/bindings/scripts/web_idl/ir_builder.py
@@ -0,0 +1,133 @@ +# 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 idl_parser +import utilities +from .common import DebugInfo +from .interface import Interface +from .namespace import Namespace +from .dictionary import Dictionary +from .callback_interface import CallbackInterface +from .callback_function import CallbackFunction +from .enumeration import Enumeration +from .typedef import Typedef +from .includes import Includes + + +def load_and_register_idl_definitions(filepaths, ir_map): + """ + Registers IDL definitions' IRs into a IDL compiler + + Load ASTs from files, create IRs, and registers them into |ir_map|. + """ + asts_grouped_by_component = utilities.read_pickle_files(filepaths) + for asts_per_component in asts_grouped_by_component: + component = asts_per_component.component + for file_node in asts_per_component.asts: + assert isinstance(file_node, idl_parser.idl_node.IDLNode) + for definition_node in file_node.GetChildren(): + idl_definition = _convert_ast(component, definition_node) + ir_map.register(idl_definition) + + +def _convert_ast(component, ast): + def build_interface(node): + if node.GetProperty('CALLBACK'): + return build_callback_interface(node) + + interface = Interface.IR( + identifier=node.GetName(), + is_partial=bool(node.GetProperty('PARTIAL')), + is_mixin=bool(node.GetProperty('MIXIN')), + component=component, + debug_info=_build_debug_info(node)) + # TODO(peria): Build members and register them in |interface| + return interface + + def build_namespace(node): + namespace = Namespace.IR( + identifier=node.GetName(), + is_partial=bool(node.GetProperty('PARTIAL')), + component=component, + debug_info=_build_debug_info(node)) + # TODO(peria): Build members and register them in |namespace| + return namespace + + def build_dictionary(node): + dictionary = Dictionary.IR( + identifier=node.GetName(), + is_partial=bool(node.GetProperty('PARTIAL')), + component=component, + debug_info=_build_debug_info(node)) + # TODO(peria): Build members and register them in |dictionary| + return dictionary + + def build_callback_interface(node): + callback_interface = CallbackInterface.IR( + identifier=node.GetName(), + component=component, + debug_info=_build_debug_info(node)) + # TODO(peria): Build members and register them in |callback_interface| + return callback_interface + + def build_callback_function(node): + callback_function = CallbackFunction.IR( + identifier=node.GetName(), + component=component, + debug_info=_build_debug_info(node)) + # TODO(peria): Build members and register them in |callback_function| + return callback_function + + def build_enumeration(node): + enumeration = Enumeration.IR( + identifier=node.GetName(), + values=[child.GetName() for child in node.GetChildren()], + component=component, + debug_info=_build_debug_info(node)) + return enumeration + + def build_typedef(node): + typedef = Typedef.IR( + identifier=node.GetName(), + idl_type=dispatch_to_build_function(node.GetChildren()[0]), + component=component, + debug_info=_build_debug_info(node)) + return typedef + + def build_includes(node): + includes = Includes.IR( + interface_identifier=node.GetName(), + mixin_identifier=node.GetProperty('REFERENCE'), + component=component, + debug_info=_build_debug_info(node)) + return includes + + def dispatch_to_build_function(node): + node_class = node.GetClass() + # TODO(peria): Drop this if branch returning None, when all the build + # functions get implemented. It is only to avoid a build error in CQ. + if node_class not in build_functions: + return None + assert node_class in build_functions, '{} is unknown node class.'.format( + node_class) + return build_functions[node_class](node) + + build_functions = { + 'Callback': build_callback_function, + 'Dictionary': build_dictionary, + 'Enum': build_enumeration, + 'Includes': build_includes, + 'Interface': build_interface, + 'Namespace': build_namespace, + 'Typedef': build_typedef, + } + return dispatch_to_build_function(ast) + + +def _build_debug_info(node): + return DebugInfo( + location=DebugInfo.Location( + filepath=node.GetProperty('FILENAME'), + line_number=node.GetProperty('LINENO'), + column_number=node.GetProperty('POSITION')))
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/typedef.py b/third_party/blink/renderer/bindings/scripts/web_idl/typedef.py index 5f3151b..10ee0af 100644 --- a/third_party/blink/renderer/bindings/scripts/web_idl/typedef.py +++ b/third_party/blink/renderer/bindings/scripts/web_idl/typedef.py
@@ -17,6 +17,7 @@ WithDebugInfo): def __init__(self, identifier, + idl_type, code_generator_info=None, component=None, debug_info=None): @@ -28,6 +29,8 @@ WithComponent.__init__(self, component) WithDebugInfo.__init__(self, debug_info) + self.idl_type = idl_type + @property def idl_type(self): """
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/utilities.py b/third_party/blink/renderer/bindings/scripts/web_idl/utilities.py deleted file mode 100644 index 5484a6d..0000000 --- a/third_party/blink/renderer/bindings/scripts/web_idl/utilities.py +++ /dev/null
@@ -1,8 +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. - - -def assert_no_extra_args(kwargs): - if kwargs: - raise ValueError('Unknown parameters are passed: %s' % kwargs.keys())
diff --git a/third_party/blink/renderer/core/css/css_font_face_src_value.cc b/third_party/blink/renderer/core/css/css_font_face_src_value.cc index e6255e9..463397f 100644 --- a/third_party/blink/renderer/core/css/css_font_face_src_value.cc +++ b/third_party/blink/renderer/core/css/css_font_face_src_value.cc
@@ -85,8 +85,12 @@ FontResourceClient* client) const { if (!fetched_) { ResourceRequest resource_request(absolute_resource_); - resource_request.SetHttpReferrer(SecurityPolicy::GenerateReferrer( - referrer_.referrer_policy, resource_request.Url(), referrer_.referrer)); + resource_request.SetReferrerPolicy( + ReferrerPolicyResolveDefault(referrer_.referrer_policy), + ResourceRequest::SetReferrerPolicyLocation::kCSSFontFaceSrcValueFetch); + resource_request.SetReferrerString( + referrer_.referrer, + ResourceRequest::SetReferrerStringLocation::kCSSFontFaceSrcValueFetch); ResourceLoaderOptions options; options.initiator_info.name = fetch_initiator_type_names::kCSS; FetchParameters params(resource_request, options);
diff --git a/third_party/blink/renderer/core/css/css_image_set_value.cc b/third_party/blink/renderer/core/css/css_image_set_value.cc index a8cd7be2..8f44785 100644 --- a/third_party/blink/renderer/core/css/css_image_set_value.cc +++ b/third_party/blink/renderer/core/css/css_image_set_value.cc
@@ -64,9 +64,8 @@ ImageWithScale image; image.image_url = image_url; - image.referrer = SecurityPolicy::GenerateReferrer( - image_value.GetReferrer().referrer_policy, KURL(image_url), - image_value.GetReferrer().referrer); + image.referrer.referrer = image_value.GetReferrer().referrer; + image.referrer.referrer_policy = image_value.GetReferrer().referrer_policy; image.scale_factor = scale_factor; images_in_set_.push_back(image); ++i; @@ -114,7 +113,13 @@ // transforms. https://bugs.webkit.org/show_bug.cgi?id=81698 ImageWithScale image = BestImageForScaleFactor(device_scale_factor); ResourceRequest resource_request(document.CompleteURL(image.image_url)); - resource_request.SetHttpReferrer(image.referrer); + resource_request.SetReferrerPolicy( + ReferrerPolicyResolveDefault(image.referrer.referrer_policy), + ResourceRequest::SetReferrerPolicyLocation:: + kCSSImageSetValueCacheImage); + resource_request.SetReferrerString( + image.referrer.referrer, ResourceRequest::SetReferrerStringLocation:: + kCSSImageSetValueCacheImage); ResourceLoaderOptions options; options.initiator_info.name = parser_mode_ == kUASheetMode ? fetch_initiator_type_names::kUacss
diff --git a/third_party/blink/renderer/core/css/css_image_value.cc b/third_party/blink/renderer/core/css/css_image_value.cc index fe4de29..6ce4ffe 100644 --- a/third_party/blink/renderer/core/css/css_image_value.cc +++ b/third_party/blink/renderer/core/css/css_image_value.cc
@@ -66,8 +66,12 @@ if (absolute_url_.IsEmpty()) ReResolveURL(document); ResourceRequest resource_request(absolute_url_); - resource_request.SetHttpReferrer(SecurityPolicy::GenerateReferrer( - referrer_.referrer_policy, resource_request.Url(), referrer_.referrer)); + resource_request.SetReferrerPolicy( + ReferrerPolicyResolveDefault(referrer_.referrer_policy), + ResourceRequest::SetReferrerPolicyLocation::kCSSImageValueCacheImage); + resource_request.SetReferrerString( + referrer_.referrer, + ResourceRequest::SetReferrerStringLocation::kCSSImageValueCacheImage); ResourceLoaderOptions options; options.initiator_info.name = initiator_name_.IsEmpty() ? fetch_initiator_type_names::kCSS
diff --git a/third_party/blink/renderer/core/css/invalidation/style_invalidator.cc b/third_party/blink/renderer/core/css/invalidation/style_invalidator.cc index 92d9c68a..d8090492 100644 --- a/third_party/blink/renderer/core/css/invalidation/style_invalidator.cc +++ b/third_party/blink/renderer/core/css/invalidation/style_invalidator.cc
@@ -318,9 +318,10 @@ for (auto& distributed_node : slot.FlattenedAssignedNodes()) { if (distributed_node->NeedsStyleRecalc()) continue; - if (!distributed_node->IsElementNode()) + auto* element = DynamicTo<Element>(distributed_node.Get()); + if (!element) continue; - if (MatchesCurrentInvalidationSetsAsSlotted(ToElement(*distributed_node))) { + if (MatchesCurrentInvalidationSetsAsSlotted(*element)) { distributed_node->SetNeedsStyleRecalc( kLocalStyleChange, StyleChangeReasonForTracing::Create( style_change_reason::kStyleInvalidator));
diff --git a/third_party/blink/renderer/core/css/layout_tree_rebuild_root.cc b/third_party/blink/renderer/core/css/layout_tree_rebuild_root.cc index 8d1fd528..1d10553 100644 --- a/third_party/blink/renderer/core/css/layout_tree_rebuild_root.cc +++ b/third_party/blink/renderer/core/css/layout_tree_rebuild_root.cc
@@ -27,7 +27,7 @@ } if (!root_node || root_node->IsDocumentNode()) return *GetRootNode()->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_recalc_root.cc b/third_party/blink/renderer/core/css/style_recalc_root.cc index 8c88771..0a251fb 100644 --- a/third_party/blink/renderer/core/css/style_recalc_root.cc +++ b/third_party/blink/renderer/core/css/style_recalc_root.cc
@@ -31,7 +31,7 @@ } if (root_node->IsTextNode()) return *root_node->parentElement(); - return ToElement(*root_node); + return To<Element>(*root_node); } #if DCHECK_IS_ON()
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index d1234581..611ef13d 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -2483,9 +2483,9 @@ static void AssertLayoutTreeUpdated(Node& root) { Node* node = &root; while (node) { - if (RuntimeEnabledFeatures::DisplayLockingEnabled() && - node->IsElementNode() && - ToElement(node)->StyleRecalcBlockedByDisplayLock( + auto* element = DynamicTo<Element>(node); + if (element && RuntimeEnabledFeatures::DisplayLockingEnabled() && + element->StyleRecalcBlockedByDisplayLock( DisplayLockContext::kChildren)) { node = FlatTreeTraversal::NextSkippingChildren(*node); continue; @@ -2795,9 +2795,10 @@ (ancestor->NeedsAdjacentStyleRecalc() && !ignore_adjacent_style)) { return true; } - if (!ancestor->IsElementNode()) + auto* element = DynamicTo<Element>(ancestor); + if (!element) continue; - if (auto* context = ToElement(ancestor)->GetDisplayLockContext()) { + if (auto* context = element->GetDisplayLockContext()) { // Even if the ancestor is style-clean, we might've previously // blocked a style traversal going to the ancestor or its descendants. if (context->StyleTraversalWasBlocked()) { @@ -5206,8 +5207,8 @@ Node* node = sequential_focus_navigation_starting_point_->startContainer(); DCHECK_EQ(node, sequential_focus_navigation_starting_point_->endContainer()); - if (node->IsElementNode()) - return ToElement(node); + if (auto* element = DynamicTo<Element>(node)) + return element; if (Element* neighbor_element = type == kWebFocusTypeForward ? ElementTraversal::Previous(*node) : ElementTraversal::Next(*node)) @@ -5217,13 +5218,11 @@ // Range::selectNodeContents didn't select contents because the element had // no children. - if (sequential_focus_navigation_starting_point_->startContainer() - ->IsElementNode() && - !sequential_focus_navigation_starting_point_->startContainer() - ->hasChildren() && + auto* element = DynamicTo<Element>( + sequential_focus_navigation_starting_point_->startContainer()); + if (element && !element->hasChildren() && sequential_focus_navigation_starting_point_->startOffset() == 0) - return ToElement( - sequential_focus_navigation_starting_point_->startContainer()); + return element; // A node selected by Range::selectNodeContents was removed from the // document tree. @@ -5235,11 +5234,11 @@ // FocusController. Ideally we should find backward/forward focusable // elements before the starting point is disconnected. crbug.com/606582 if (type == kWebFocusTypeForward) { - Node* previous = next_node; - do { - previous = FlatTreeTraversal::Previous(*previous); - } while (previous && !previous->IsElementNode()); - return ToElement(previous); + Node* previous = FlatTreeTraversal::Previous(*next_node); + for (; previous; previous = FlatTreeTraversal::Previous(*previous)) { + if (auto* element = DynamicTo<Element>(previous)) + return element; + } } for (Node* next = next_node; next; next = FlatTreeTraversal::Next(*next)) { if (auto* element = DynamicTo<Element>(next)) @@ -6910,7 +6909,7 @@ EventListener* listener, const String& context_url, const WTF::OrdinalNumber& context_line) { - Element* element = node && node->IsElementNode() ? ToElement(node) : nullptr; + auto* element = DynamicTo<Element>(node); // https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-content-attributes // Step 5.1. If the Should element's inline behavior be blocked by Content @@ -7442,8 +7441,8 @@ new_hover_element) { Node* ancestor = FlatTreeTraversal::CommonAncestor(*old_hover_element, *new_hover_element); - if (ancestor && ancestor->IsElementNode()) - ancestor_element = ToElement(ancestor); + if (auto* element = DynamicTo<Element>(ancestor)) + ancestor_element = element; } HeapVector<Member<Element>, 32> elements_to_remove_from_chain;
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index 3fa50d3..c35262b2 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -283,7 +283,7 @@ return true; if (node.GetDocument().documentElement() == &node) return true; - if (const Element* element = ToElementOrNull(&node)) { + if (const Element* element = DynamicTo<Element>(&node)) { // Replaced elements are considered to create a new formatting context, in // the sense that they can't possibly have children that participate in the // same formatting context as their parent. @@ -3776,7 +3776,8 @@ bool found_bfc = false; for (Element* ancestor = this; !found_bfc;) { - ancestor = ToElementOrNull(LayoutTreeBuilderTraversal::Parent(*ancestor)); + ancestor = + DynamicTo<Element>(LayoutTreeBuilderTraversal::Parent(*ancestor)); if (!ancestor || ancestor->ShouldForceLegacyLayout()) break; const ComputedStyle* style = ancestor->GetComputedStyle(); @@ -3800,7 +3801,7 @@ // still going to fall back to legacy. Element* parent; for (Element* walker = this; walker; walker = parent) { - parent = ToElementOrNull(LayoutTreeBuilderTraversal::Parent(*walker)); + parent = DynamicTo<Element>(LayoutTreeBuilderTraversal::Parent(*walker)); if (!walker->GetComputedStyle()->SpecifiesColumns()) continue;
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h index 0d8e7058..ce27f74 100644 --- a/third_party/blink/renderer/core/dom/element.h +++ b/third_party/blink/renderer/core/dom/element.h
@@ -1266,12 +1266,12 @@ } inline bool IsDisabledFormControl(const Node* node) { - return node->IsElementNode() && ToElement(node)->IsDisabledFormControl(); + auto* element = DynamicTo<Element>(node); + return element && element->IsDisabledFormControl(); } inline Element* Node::parentElement() const { - ContainerNode* parent = parentNode(); - return parent && parent->IsElementNode() ? ToElement(parent) : nullptr; + return DynamicTo<Element>(parentNode()); } inline bool Element::FastHasAttribute(const QualifiedName& name) const {
diff --git a/third_party/blink/renderer/core/dom/slot_assignment_test.cc b/third_party/blink/renderer/core/dom/slot_assignment_test.cc index e5c4dea6..39054a0 100644 --- a/third_party/blink/renderer/core/dom/slot_assignment_test.cc +++ b/third_party/blink/renderer/core/dom/slot_assignment_test.cc
@@ -71,7 +71,7 @@ if (auto* text = DynamicTo<Text>(descendant)) { if (text->ContainsOnlyWhitespaceOrEmpty()) text->remove(); - } else if (Element* element = ToElementOrNull(descendant)) { + } else if (auto* element = DynamicTo<Element>(descendant)) { if (ShadowRoot* shadow_root = element->OpenShadowRoot()) RemoveWhiteSpaceOnlyTextNode(*shadow_root); }
diff --git a/third_party/blink/renderer/core/editing/editing_style_utilities.cc b/third_party/blink/renderer/core/editing/editing_style_utilities.cc index a2276f0..b25aba9 100644 --- a/third_party/blink/renderer/core/editing/editing_style_utilities.cc +++ b/third_party/blink/renderer/core/editing/editing_style_utilities.cc
@@ -118,7 +118,7 @@ break; if (node.IsStyledElement() && !IsMailHTMLBlockquoteElement(&node)) { wrapping_style->MergeInlineAndImplicitStyleOfElement( - ToElement(&node), EditingStyle::kDoNotOverrideValues, + To<Element>(&node), EditingStyle::kDoNotOverrideValues, EditingStyle::kEditingPropertiesInEffect); } }
diff --git a/third_party/blink/renderer/core/editing/editing_utilities.cc b/third_party/blink/renderer/core/editing/editing_utilities.cc index 6d11b16..cf155d1 100644 --- a/third_party/blink/renderer/core/editing/editing_utilities.cc +++ b/third_party/blink/renderer/core/editing/editing_utilities.cc
@@ -412,7 +412,7 @@ return true; } - if (auto* element = ToElementOrNull(const_cast<Node*>(&node))) + if (auto* element = DynamicTo<Element>(&node)) return EqualIgnoringASCIICase(element->getAttribute(kRoleAttr), "textbox"); return false;
diff --git a/third_party/blink/renderer/core/editing/layout_selection.cc b/third_party/blink/renderer/core/editing/layout_selection.cc index ea77044..4087870 100644 --- a/third_party/blink/renderer/core/editing/layout_selection.cc +++ b/third_party/blink/renderer/core/editing/layout_selection.cc
@@ -910,7 +910,7 @@ ostream << (void*)&node; if (node.IsTextNode()) ostream << "#text"; - else if (const Element* element = ToElementOrNull(node)) + else if (const auto* element = DynamicTo<Element>(node)) ostream << element->tagName().Utf8(); LayoutObject* layout_object = node.GetLayoutObject(); if (!layout_object) {
diff --git a/third_party/blink/renderer/core/editing/layout_selection_test.cc b/third_party/blink/renderer/core/editing/layout_selection_test.cc index c8fbb486..d24c62f 100644 --- a/third_party/blink/renderer/core/editing/layout_selection_test.cc +++ b/third_party/blink/renderer/core/editing/layout_selection_test.cc
@@ -83,7 +83,7 @@ wtf_size_t depth) { if (const Text* text = DynamicTo<Text>(node)) PrintText(ostream, *text); - else if (const Element* element = ToElementOrNull(node)) + else if (const auto* element = DynamicTo<Element>(node)) ostream << element->tagName().Utf8(); else ostream << node;
diff --git a/third_party/blink/renderer/core/editing/selection_editor.cc b/third_party/blink/renderer/core/editing/selection_editor.cc index a79885a..bc8ade5d 100644 --- a/third_party/blink/renderer/core/editing/selection_editor.cc +++ b/third_party/blink/renderer/core/editing/selection_editor.cc
@@ -173,7 +173,7 @@ #endif if (!container.ContainsIncludingHostElements(*node)) return position; - if (auto* element = ToElementOrNull(container)) { + if (auto* element = DynamicTo<Element>(container)) { if (auto* shadow_root = element->GetShadowRoot()) { // Removal of light children does not affect position in the // shadow tree.
diff --git a/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc b/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc index 36481ff..43c63a99 100644 --- a/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc +++ b/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc
@@ -359,7 +359,7 @@ } else { next = Strategy::Next(*n); if (IsEnclosingBlock(n) && CanHaveChildrenForEditing(n) && - next == past_end && !ContainsOnlyBRElement(ToElement(*n))) { + next == past_end && !ContainsOnlyBRElement(To<Element>(*n))) { // Don't write out empty block containers that aren't fully selected // unless the block container only contains br element. continue; @@ -375,7 +375,7 @@ // If node has no children, close the tag now. if (Strategy::HasChildren(*n)) { - if (next == past_end && ContainsOnlyBRElement(ToElement(*n))) { + if (next == past_end && ContainsOnlyBRElement(*element)) { // node is not fully selected and node contains only one br element // as child. Close the br tag now. AppendStartMarkup(*next);
diff --git a/third_party/blink/renderer/core/exported/web_layer_test.cc b/third_party/blink/renderer/core/exported/web_layer_test.cc index 0cb27052..1bb3a3a 100644 --- a/third_party/blink/renderer/core/exported/web_layer_test.cc +++ b/third_party/blink/renderer/core/exported/web_layer_test.cc
@@ -272,6 +272,15 @@ return Compositor().layer_tree_view().layer_tree_host()->property_trees(); } + cc::TransformNode* GetTransformNode(const cc::Layer* layer) { + return GetPropertyTrees()->transform_tree.Node( + layer->transform_tree_index()); + } + + cc::EffectNode* GetEffectNode(const cc::Layer* layer) { + return GetPropertyTrees()->effect_tree.Node(layer->effect_tree_index()); + } + PaintArtifactCompositor* paint_artifact_compositor() { return MainFrame().GetFrameView()->GetPaintArtifactCompositorForTesting(); } @@ -474,20 +483,29 @@ // Initially, no layer should have |subtree_property_changed| set. EXPECT_FALSE(outer_element_layer->subtree_property_changed()); + EXPECT_FALSE(GetTransformNode(outer_element_layer)->transform_changed); EXPECT_FALSE(inner_element_layer->subtree_property_changed()); + EXPECT_FALSE(GetTransformNode(inner_element_layer)->transform_changed); // Modifying the transform style should set |subtree_property_changed| on // both layers. outer_element->setAttribute(html_names::kStyleAttr, "transform: rotate(10deg)"); UpdateAllLifecyclePhases(); + // This is still set by the traditional GraphicsLayer::SetTransform(). EXPECT_TRUE(outer_element_layer->subtree_property_changed()); + // Set by blink::PropertyTreeManager. + EXPECT_TRUE(GetTransformNode(outer_element_layer)->transform_changed); + // TODO(wangxianzhu): Probably avoid setting this flag on transform change. EXPECT_TRUE(inner_element_layer->subtree_property_changed()); + EXPECT_FALSE(GetTransformNode(inner_element_layer)->transform_changed); // After a frame the |subtree_property_changed| value should be reset. Compositor().BeginFrame(); EXPECT_FALSE(outer_element_layer->subtree_property_changed()); + EXPECT_FALSE(GetTransformNode(outer_element_layer)->transform_changed); EXPECT_FALSE(inner_element_layer->subtree_property_changed()); + EXPECT_FALSE(GetTransformNode(inner_element_layer)->transform_changed); } // When a property tree change occurs that affects layer transform in a simple @@ -719,19 +737,28 @@ // Initially, no layer should have |subtree_property_changed| set. EXPECT_FALSE(outer_element_layer->subtree_property_changed()); + EXPECT_FALSE(GetEffectNode(outer_element_layer)->effect_changed); EXPECT_FALSE(inner_element_layer->subtree_property_changed()); + EXPECT_FALSE(GetEffectNode(inner_element_layer)->effect_changed); // Modifying the filter style should set |subtree_property_changed| on // both layers. outer_element->setAttribute(html_names::kStyleAttr, "filter: blur(20px)"); UpdateAllLifecyclePhases(); + // TODO(wangxianzhu): Probably avoid setting this flag on transform change. EXPECT_TRUE(outer_element_layer->subtree_property_changed()); + // Set by blink::PropertyTreeManager. + EXPECT_TRUE(GetEffectNode(outer_element_layer)->effect_changed); + // TODO(wangxianzhu): Probably avoid setting this flag on transform change. EXPECT_TRUE(inner_element_layer->subtree_property_changed()); + EXPECT_FALSE(GetEffectNode(inner_element_layer)->effect_changed); // After a frame the |subtree_property_changed| value should be reset. Compositor().BeginFrame(); EXPECT_FALSE(outer_element_layer->subtree_property_changed()); + EXPECT_FALSE(GetEffectNode(outer_element_layer)->effect_changed); EXPECT_FALSE(inner_element_layer->subtree_property_changed()); + EXPECT_FALSE(GetEffectNode(inner_element_layer)->effect_changed); } // This test is similar to |LayerSubtreeTransformPropertyChanged| but for
diff --git a/third_party/blink/renderer/core/fetch/fetch_manager.cc b/third_party/blink/renderer/core/fetch/fetch_manager.cc index bb46eba..df97cd9 100644 --- a/third_party/blink/renderer/core/fetch/fetch_manager.cc +++ b/third_party/blink/renderer/core/fetch/fetch_manager.cc
@@ -732,8 +732,12 @@ request.SetUseStreamOnResponse(true); request.SetExternalRequestStateFromRequestorAddressSpace( execution_context_->GetSecurityContext().AddressSpace()); - request.SetReferrerString(fetch_request_data_->ReferrerString()); - request.SetReferrerPolicy(fetch_request_data_->GetReferrerPolicy()); + request.SetReferrerString( + fetch_request_data_->ReferrerString(), + ResourceRequest::SetReferrerStringLocation::kPerformHTTPFetch); + request.SetReferrerPolicy( + fetch_request_data_->GetReferrerPolicy(), + ResourceRequest::SetReferrerPolicyLocation::kPerformHTTPFetch); request.SetSkipServiceWorker(is_isolated_world_);
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc index 21d9b7f..9208493 100644 --- a/third_party/blink/renderer/core/frame/local_dom_window.cc +++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -1495,7 +1495,8 @@ SecurityPolicy::GenerateReferrer( active_document->GetReferrerPolicy(), completed_url, window_features.noreferrer ? Referrer::NoReferrer() - : active_document->OutgoingReferrer())); + : active_document->OutgoingReferrer()), + ResourceRequest::SetHttpReferrerLocation::kLocalDomWindow); frame_request.GetResourceRequest().SetHasUserGesture( LocalFrame::HasTransientUserActivation(GetFrame()));
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 e55ac915..0a2181f 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
@@ -951,10 +951,12 @@ String referrer = referrer_url.IsEmpty() ? GetFrame()->GetDocument()->OutgoingReferrer() : String(referrer_url.GetString()); - request.ToMutableResourceRequest().SetHttpReferrer( - SecurityPolicy::GenerateReferrer( - GetFrame()->GetDocument()->GetReferrerPolicy(), request.Url(), - referrer)); + ResourceRequest& resource_request = request.ToMutableResourceRequest(); + resource_request.SetReferrerPolicy( + GetFrame()->GetDocument()->GetReferrerPolicy(), + ResourceRequest::SetReferrerPolicyLocation::kWebLocalFrameImpl); + resource_request.SetReferrerString( + referrer, ResourceRequest::SetReferrerStringLocation::kWebLocalFrameImpl); } WebAssociatedURLLoader* WebLocalFrameImpl::CreateAssociatedURLLoader( @@ -2329,7 +2331,7 @@ if (!node || !(IsHTMLCanvasElement(*node) || IsHTMLImageElement(*node))) return; - String url = ToElement(*node).ImageSourceURL(); + String url = To<Element>(*node).ImageSourceURL(); if (!KURL(NullURL(), url).ProtocolIsData()) return;
diff --git a/third_party/blink/renderer/core/html/custom/custom_element_upgrade_sorter.cc b/third_party/blink/renderer/core/html/custom/custom_element_upgrade_sorter.cc index 2d40f4d..f383846 100644 --- a/third_party/blink/renderer/core/html/custom/custom_element_upgrade_sorter.cc +++ b/third_party/blink/renderer/core/html/custom/custom_element_upgrade_sorter.cc
@@ -65,8 +65,9 @@ const ChildSet::iterator& it) { if (it == children.end()) return; - if (it->Get()->IsElementNode() && elements_->Contains(ToElement(*it))) - result->push_back(ToElement(*it)); + auto* element = DynamicTo<Element>(it->Get()); + if (element && elements_->Contains(element)) + result->push_back(*element); Sorted(result, *it); children.erase(it); }
diff --git a/third_party/blink/renderer/core/html/html_anchor_element.cc b/third_party/blink/renderer/core/html/html_anchor_element.cc index 51d9415..b1020a9 100644 --- a/third_party/blink/renderer/core/html/html_anchor_element.cc +++ b/third_party/blink/renderer/core/html/html_anchor_element.cc
@@ -381,7 +381,8 @@ !HasRel(kRelationNoReferrer)) { UseCounter::Count(GetDocument(), WebFeature::kHTMLAnchorElementReferrerPolicyAttribute); - request.SetReferrerPolicy(policy); + request.SetReferrerPolicy( + policy, ResourceRequest::SetReferrerPolicyLocation::kAnchorElement); } // Ignore the download attribute if we either can't read the content, or
diff --git a/third_party/blink/renderer/core/html/html_frame_owner_element.cc b/third_party/blink/renderer/core/html/html_frame_owner_element.cc index ace7634..60c5e0be 100644 --- a/third_party/blink/renderer/core/html/html_frame_owner_element.cc +++ b/third_party/blink/renderer/core/html/html_frame_owner_element.cc
@@ -421,7 +421,9 @@ KURL url_to_request = url.IsNull() ? BlankURL() : url; ResourceRequest request(url_to_request); - request.SetReferrerPolicy(ReferrerPolicyAttribute()); + request.SetReferrerPolicy(ReferrerPolicyAttribute(), + ResourceRequest::SetReferrerPolicyLocation:: + kFrameOwnerLoadOrRedirectSubframe); if (ContentFrame()) { // TODO(sclittle): Support lazily loading frame navigations.
diff --git a/third_party/blink/renderer/core/html/html_slot_element.cc b/third_party/blink/renderer/core/html/html_slot_element.cc index f64b6595..58d24cdc 100644 --- a/third_party/blink/renderer/core/html/html_slot_element.cc +++ b/third_party/blink/renderer/core/html/html_slot_element.cc
@@ -157,8 +157,8 @@ const HeapVector<Member<Element>> HTMLSlotElement::AssignedElements() { HeapVector<Member<Element>> elements; for (auto& node : AssignedNodes()) { - if (Element* element = ToElementOrNull(node)) - elements.push_back(element); + if (auto* element = DynamicTo<Element>(node.Get())) + elements.push_back(*element); } return elements; } @@ -167,8 +167,8 @@ const AssignedNodesOptions* options) { HeapVector<Member<Element>> elements; for (auto& node : AssignedNodesForBinding(options)) { - if (Element* element = ToElementOrNull(node)) - elements.push_back(element); + if (auto* element = DynamicTo<Element>(node.Get())) + elements.push_back(*element); } return elements; }
diff --git a/third_party/blink/renderer/core/html/html_source_element.cc b/third_party/blink/renderer/core/html/html_source_element.cc index 4ba9bf6f..0348f09 100644 --- a/third_party/blink/renderer/core/html/html_source_element.cc +++ b/third_party/blink/renderer/core/html/html_source_element.cc
@@ -107,8 +107,9 @@ void HTMLSourceElement::RemovedFrom(ContainerNode& removal_root) { Element* parent = parentElement(); - if (!parent && removal_root.IsElementNode()) - parent = ToElement(&removal_root); + auto* element = DynamicTo<Element>(&removal_root); + if (element && !parent) + parent = element; if (auto* media = ToHTMLMediaElementOrNull(parent)) media->SourceWasRemoved(this); if (auto* picture = ToHTMLPictureElementOrNull(parent)) {
diff --git a/third_party/blink/renderer/core/html/imports/link_import.cc b/third_party/blink/renderer/core/html/imports/link_import.cc index 73df690..f907e0f 100644 --- a/third_party/blink/renderer/core/html/imports/link_import.cc +++ b/third_party/blink/renderer/core/html/imports/link_import.cc
@@ -76,7 +76,8 @@ ResourceRequest resource_request(GetDocument().CompleteURL(url)); network::mojom::ReferrerPolicy referrer_policy = owner_->GetReferrerPolicy(); - resource_request.SetReferrerPolicy(referrer_policy); + resource_request.SetReferrerPolicy( + referrer_policy, ResourceRequest::SetReferrerPolicyLocation::kLinkImport); ResourceLoaderOptions options; options.initiator_info.name = owner_->localName();
diff --git a/third_party/blink/renderer/core/html/parser/html_construction_site.cc b/third_party/blink/renderer/core/html/parser/html_construction_site.cc index 4b2bf649..eb5b858 100644 --- a/third_party/blink/renderer/core/html/parser/html_construction_site.cc +++ b/third_party/blink/renderer/core/html/parser/html_construction_site.cc
@@ -124,12 +124,10 @@ DCHECK_EQ(task.operation, HTMLConstructionSiteTask::kInsert); Insert(task); - - if (task.child->IsElementNode()) { - Element& child = ToElement(*task.child); - child.BeginParsingChildren(); + if (auto* child = DynamicTo<Element>(task.child.Get())) { + child->BeginParsingChildren(); if (task.self_closing) - child.FinishParsingChildren(); + child->FinishParsingChildren(); } }
diff --git a/third_party/blink/renderer/core/html/parser/preload_request.cc b/third_party/blink/renderer/core/html/parser/preload_request.cc index 8302279..c9b3308b 100644 --- a/third_party/blink/renderer/core/html/parser/preload_request.cc +++ b/third_party/blink/renderer/core/html/parser/preload_request.cc
@@ -39,9 +39,14 @@ DCHECK(!url.ProtocolIsData()); ResourceRequest resource_request(url); - resource_request.SetReferrerPolicy(referrer_policy_); - if (referrer_source_ == kBaseUrlIsReferrer) - resource_request.SetReferrerString(base_url_.StrippedForUseAsReferrer()); + resource_request.SetReferrerPolicy( + referrer_policy_, + ResourceRequest::SetReferrerPolicyLocation::kPreloadRequestStart); + if (referrer_source_ == kBaseUrlIsReferrer) { + resource_request.SetReferrerString( + base_url_.StrippedForUseAsReferrer(), + ResourceRequest::SetReferrerStringLocation::kPreloadRequestStart); + } resource_request.SetRequestContext( ResourceFetcher::DetermineRequestContext(resource_type_, is_image_set_));
diff --git a/third_party/blink/renderer/core/input/pointer_event_manager.cc b/third_party/blink/renderer/core/input/pointer_event_manager.cc index 023053a..5161f35 100644 --- a/third_party/blink/renderer/core/input/pointer_event_manager.cc +++ b/third_party/blink/renderer/core/input/pointer_event_manager.cc
@@ -809,9 +809,9 @@ pointer_event->HasEventPath()) { for (const auto& context : pointer_event->GetEventPath().NodeEventContexts()) { - if (context.GetNode().IsElementNode() && - event_handling_util::IsInDocument(&context.GetNode())) { - mouse_target = ToElement(&context.GetNode()); + auto* element = DynamicTo<Element>(&context.GetNode()); + if (element && event_handling_util::IsInDocument(element)) { + mouse_target = element; break; } }
diff --git a/third_party/blink/renderer/core/inspector/dom_patch_support.cc b/third_party/blink/renderer/core/inspector/dom_patch_support.cc index 4caffa2..8da4b57 100644 --- a/third_party/blink/renderer/core/inspector/dom_patch_support.cc +++ b/third_party/blink/renderer/core/inspector/dom_patch_support.cc
@@ -443,9 +443,8 @@ digestor.UpdateUtf8(node->nodeName()); digestor.UpdateUtf8(node->nodeValue()); - if (node->IsElementNode()) { - Element& element = ToElement(*node); - Node* child = element.firstChild(); + if (auto* element = DynamicTo<Element>(node)) { + Node* child = element->firstChild(); while (child) { Digest* child_info = CreateDigest(child, unused_nodes_map); digestor.UpdateUtf8(child_info->sha1_); @@ -453,7 +452,7 @@ digest->children_.push_back(child_info); } - AttributeCollection attributes = element.AttributesWithoutUpdate(); + AttributeCollection attributes = element->AttributesWithoutUpdate(); if (!attributes.IsEmpty()) { Digestor attrs_digestor(kHashAlgorithmSha1); for (auto& attribute : attributes) {
diff --git a/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc b/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc index b53e403..5d0cf17 100644 --- a/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc
@@ -579,18 +579,17 @@ HashSet<String> unique_names; *class_names = std::make_unique<protocol::Array<String>>(); Node* parent_node = NodeForId(node_id); - if (!parent_node || - (!parent_node->IsElementNode() && !parent_node->IsDocumentNode() && - !parent_node->IsDocumentFragment())) + auto* parent_element = DynamicTo<Element>(parent_node); + if (!parent_element && !parent_node->IsDocumentNode() && + !parent_node->IsDocumentFragment()) return Response::Error("No suitable node with given id found"); for (Node* node = parent_node; node; node = FlatTreeTraversal::Next(*node, parent_node)) { - if (node->IsElementNode()) { - const Element& element = ToElement(*node); - if (!element.HasClass()) + if (const auto* element = DynamicTo<Element>(node)) { + if (!element->HasClass()) continue; - const SpaceSplitString& class_name_list = element.ClassNames(); + const SpaceSplitString& class_name_list = element->ClassNames(); for (unsigned i = 0; i < class_name_list.size(); ++i) unique_names.insert(class_name_list[i]); }
diff --git a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc index 1bffc8a..f664d848 100644 --- a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
@@ -860,7 +860,8 @@ // inside state_'s kExtraRequestHeaders, somewhere else. if (header_name.LowerASCII() == http_names::kReferer.LowerASCII()) { request.SetHttpReferrer( - Referrer(value, network::mojom::ReferrerPolicy::kAlways)); + Referrer(value, network::mojom::ReferrerPolicy::kAlways), + ResourceRequest::SetHttpReferrerLocation::kInspectorNetworkAgent); } else { request.SetHttpHeaderField(header_name, AtomicString(value)); }
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc index a1794ba..0c9af91 100644 --- a/third_party/blink/renderer/core/layout/layout_box.cc +++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -3777,7 +3777,10 @@ available_height -= root_margin_border_padding_height; - if (IsTable() && IsOutOfFlowPositioned()) + // LayoutNG already includes padding in + // OverrideContainingBlockContentLogicalHeight so we only need to add it here + // for legacy containing blocks. + if (IsTable() && IsOutOfFlowPositioned() && !cb->IsLayoutNGObject()) available_height += cb->PaddingLogicalHeight(); return available_height;
diff --git a/third_party/blink/renderer/core/layout/layout_shift_tracker.cc b/third_party/blink/renderer/core/layout/layout_shift_tracker.cc index 04efa65..e4eaa6d 100644 --- a/third_party/blink/renderer/core/layout/layout_shift_tracker.cc +++ b/third_party/blink/renderer/core/layout/layout_shift_tracker.cc
@@ -195,7 +195,7 @@ #if DCHECK_IS_ON() LocalFrame& frame = frame_view_->GetFrame(); - if (ShouldLog(frame)) { + if (!HadRecentInput() && ShouldLog(frame)) { DVLOG(2) << "in " << (frame.IsMainFrame() ? "" : "subframe ") << frame.GetDocument()->Url().GetString() << ", " << source.DebugName() << " moved from " << old_rect.ToString() @@ -314,8 +314,9 @@ if (!HadRecentInput() && ShouldLog(frame)) { DVLOG(1) << "in " << (frame.IsMainFrame() ? "" : "subframe ") << frame.GetDocument()->Url().GetString() << ", viewport was " - << (jank_fraction * 100) << "% janked; raising score to " - << score_; + << (jank_fraction * 100) << "% janked with distance fraction " + << move_distance_factor << "; raising score to " + << score_with_move_distance_; } #endif
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal.cc index 5e20fc2a..d9aa540 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal.cc
@@ -113,27 +113,6 @@ DISALLOW_COPY_AND_ASSIGN(DescendantCollector); }; -// The visitor emitting all visited fragments. -class InclusiveDescendantCollector final - : public NGPhysicalFragmentCollectorBase { - STACK_ALLOCATED(); - - public: - InclusiveDescendantCollector() = default; - - Vector<Result> CollectFrom(const NGPhysicalFragment& fragment) final { - return CollectInclusivelyFrom(fragment); - } - - private: - void Visit() final { - Emit(); - VisitChildren(); - } - - DISALLOW_COPY_AND_ASSIGN(InclusiveDescendantCollector); -}; - // The visitor emitting fragments generated from the given LayoutInline, // supporting culled inline. // Note: Since we apply culled inline per line, we have a fragment for @@ -182,66 +161,6 @@ DISALLOW_COPY_AND_ASSIGN(LayoutInlineCollector); }; -// The visitor emitting ancestors of the given fragment in bottom-up order. -class AncestorCollector : public NGPhysicalFragmentCollectorBase { - STACK_ALLOCATED(); - - public: - explicit AncestorCollector(const NGPhysicalFragment& target) - : target_(target) {} - - Vector<Result> CollectFrom(const NGPhysicalFragment& fragment) final { - // TODO(xiaochengh): Change this into CollectInclusivlyFrom() to include - // subtree root to align with NodeTraversal::AncestorsOf(). - return CollectExclusivelyFrom(fragment); - } - - private: - void Visit() final { - if (&GetFragment() == &target_) { - SetShouldStopTraversing(); - return; - } - - VisitChildren(); - if (HasStoppedTraversing()) - Emit(); - } - - const NGPhysicalFragment& target_; -}; - -// The visitor emitting inclusive ancestors of the given fragment in bottom-up -// order. -class InclusiveAncestorCollector : public NGPhysicalFragmentCollectorBase { - STACK_ALLOCATED(); - - public: - explicit InclusiveAncestorCollector(const NGPhysicalFragment& target) - : target_(target) {} - - Vector<Result> CollectFrom(const NGPhysicalFragment& fragment) final { - // TODO(xiaochengh): Change this into CollectInclusivlyFrom() to include - // subtree root to align with NodeTraversal::InclusiveAncestorsOf(). - return CollectExclusivelyFrom(fragment); - } - - private: - void Visit() final { - if (&GetFragment() == &target_) { - SetShouldStopTraversing(); - Emit(); - return; - } - - VisitChildren(); - if (HasStoppedTraversing()) - Emit(); - } - - const NGPhysicalFragment& target_; -}; - } // namespace // static @@ -271,24 +190,4 @@ return DescendantCollector().CollectFrom(container); } -// static -Vector<Result> NGInlineFragmentTraversal::InclusiveDescendantsOf( - const NGPhysicalFragment& root) { - return InclusiveDescendantCollector().CollectFrom(root); -} - -// static -Vector<Result> NGInlineFragmentTraversal::InclusiveAncestorsOf( - const NGPhysicalContainerFragment& container, - const NGPhysicalFragment& target) { - return InclusiveAncestorCollector(target).CollectFrom(container); -} - -// static -Vector<Result> NGInlineFragmentTraversal::AncestorsOf( - const NGPhysicalContainerFragment& container, - const NGPhysicalFragment& target) { - return AncestorCollector(target).CollectFrom(container); -} - } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal.h index dedf844..e2ec8c6 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal.h
@@ -20,28 +20,11 @@ STATIC_ONLY(NGInlineFragmentTraversal); public: - // Return list of ancestors from |target| to |container|. Offsets are relative - // to |container|. - static Vector<NGPhysicalFragmentWithOffset> AncestorsOf( - const NGPhysicalContainerFragment& container, - const NGPhysicalFragment& target); - - // Return list inclusive ancestors from |target| to |container|. Offsets are - // relative to |container|. - static Vector<NGPhysicalFragmentWithOffset> InclusiveAncestorsOf( - const NGPhysicalContainerFragment& container, - const NGPhysicalFragment& target); - // Returns list of descendants in preorder. Offsets are relative to // specified fragment. static Vector<NGPhysicalFragmentWithOffset> DescendantsOf( const NGPhysicalContainerFragment&); - // Returns list of inclusive descendants in preorder. Offsets are relative to - // specified fragment. - static Vector<NGPhysicalFragmentWithOffset> InclusiveDescendantsOf( - const NGPhysicalFragment&); - // Returns list of inline fragments produced from the specified LayoutObject. // The search is restricted in the subtree of |container|. // Note: When |target| is a LayoutInline, some/all of its own box fragments
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal_test.cc index b0751f82..43d13c4 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal_test.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal_test.cc
@@ -76,25 +76,6 @@ EXPECT_EQ(iter, descendants.end()); } -TEST_F(NGInlineFragmentTraversalTest, InclusiveDescendantsOf) { - SetBodyInnerHTML( - "<style>* { border: 1px solid}</style>" - "<div id=t>foo<b id=b>bar</b><br>baz</div>"); - auto descendants = NGInlineFragmentTraversal::InclusiveDescendantsOf( - GetRootFragmentById("t")); - auto* iter = descendants.begin(); - - EXPECT_NEXT_BOX(iter, "t"); - EXPECT_NEXT_LINE_BOX(iter); - EXPECT_NEXT_TEXT(iter, "foo"); - EXPECT_NEXT_BOX(iter, "b"); - EXPECT_NEXT_TEXT(iter, "bar"); - EXPECT_NEXT_TEXT(iter, "\n"); - EXPECT_NEXT_LINE_BOX(iter); - EXPECT_NEXT_TEXT(iter, "baz"); - EXPECT_EQ(iter, descendants.end()); -} - TEST_F(NGInlineFragmentTraversalTest, SelfFragmentsOf) { SetBodyInnerHTML( "<style>* { border: 1px solid}</style>" @@ -110,44 +91,4 @@ EXPECT_EQ(iter, descendants.end()); } -TEST_F(NGInlineFragmentTraversalTest, AncestorsOf) { - SetBodyInnerHTML( - "<style>* { border: 1px solid}</style>" - "<div id=t>x" - "<b id=b>y<i id=i>z<u id=target>foo</u>z</i>y</b>" - "x</div>"); - const NGPhysicalContainerFragment& root = GetRootFragmentById("t"); - const NGPhysicalFragment& target = - GetFragmentOfNode(root, GetElementById("target")->firstChild()); - auto ancestors = NGInlineFragmentTraversal::AncestorsOf(root, target); - auto* iter = ancestors.begin(); - - EXPECT_NEXT_BOX(iter, "target"); - EXPECT_NEXT_BOX(iter, "i"); - EXPECT_NEXT_BOX(iter, "b"); - EXPECT_NEXT_LINE_BOX(iter); - EXPECT_EQ(iter, ancestors.end()); -} - -TEST_F(NGInlineFragmentTraversalTest, InclusiveAncestorsOf) { - SetBodyInnerHTML( - "<style>* { border: 1px solid}</style>" - "<div id=t>x" - "<b id=b>y<i id=i>z<u id=target>foo</u>z</i>y</b>" - "x</div>"); - const NGPhysicalContainerFragment& root = GetRootFragmentById("t"); - const NGPhysicalFragment& target = - GetFragmentOfNode(root, GetElementById("target")->firstChild()); - auto ancestors = - NGInlineFragmentTraversal::InclusiveAncestorsOf(root, target); - auto* iter = ancestors.begin(); - - EXPECT_NEXT_TEXT(iter, "foo"); - EXPECT_NEXT_BOX(iter, "target"); - EXPECT_NEXT_BOX(iter, "i"); - EXPECT_NEXT_BOX(iter, "b"); - EXPECT_NEXT_LINE_BOX(iter); - EXPECT_EQ(iter, ancestors.end()); -} - } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc index 561f565..802c974 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc
@@ -19,15 +19,36 @@ namespace { +// Tables need special handling, unfortunately. The code in this file assumes +// that if an element has a height or width specified, that's what its final +// height/width will be. Tables don't follow this pattern though; they treat +// specified height/width as a second min-height or min-width. +bool IsTable(const ComputedStyle& style) { + return style.Display() == EDisplay::kTable || + style.Display() == EDisplay::kInlineTable; +} + +inline Length TableAwareHeight(const ComputedStyle& style) { + if (IsTable(style)) + return Length::Auto(); + return style.Height(); +} + +inline Length TableAwareWidth(const ComputedStyle& style) { + if (IsTable(style)) + return Length::Auto(); + return style.Width(); +} + bool AbsoluteHorizontalNeedsEstimate(const ComputedStyle& style) { - const Length& width = style.Width(); + const Length& width = TableAwareWidth(style); return width.IsIntrinsic() || style.MinWidth().IsIntrinsic() || style.MaxWidth().IsIntrinsic() || (width.IsAuto() && (style.Left().IsAuto() || style.Right().IsAuto())); } bool AbsoluteVerticalNeedsEstimate(const ComputedStyle& style) { - const Length& height = style.Height(); + const Length& height = TableAwareHeight(style); return height.IsIntrinsic() || style.MinHeight().IsIntrinsic() || style.MaxHeight().IsIntrinsic() || (height.IsAuto() && (style.Top().IsAuto() || style.Bottom().IsAuto())); @@ -56,15 +77,24 @@ LayoutUnit ResolveMinWidth(const NGConstraintSpace& space, const ComputedStyle& style, const NGBoxStrut& border_padding, - const base::Optional<MinMaxSize>& child_minmax, - const Length& width) { + const base::Optional<MinMaxSize>& child_minmax) { + const Length& min_width = style.MinWidth(); if (space.GetWritingMode() == WritingMode::kHorizontalTb) { - return ResolveMinInlineLength(space, style, border_padding, child_minmax, - width, LengthResolvePhase::kLayout); + LayoutUnit resolved_min_width = + ResolveMinInlineLength(space, style, border_padding, child_minmax, + min_width, LengthResolvePhase::kLayout); + if (!IsTable(style)) + return resolved_min_width; + Length table_width = style.Width(); + if (table_width.IsAuto()) + return resolved_min_width; + LayoutUnit resolved_width = ResolveMainInlineLength( + space, style, border_padding, child_minmax, table_width); + return std::max(resolved_min_width, resolved_width); } LayoutUnit computed_width = child_minmax.has_value() ? child_minmax->max_size : LayoutUnit(); - return ResolveMinBlockLength(space, style, border_padding, width, + return ResolveMinBlockLength(space, style, border_padding, min_width, computed_width, LengthResolvePhase::kLayout); } @@ -101,15 +131,21 @@ LayoutUnit ResolveMinHeight(const NGConstraintSpace& space, const ComputedStyle& style, const NGBoxStrut& border_padding, - const base::Optional<MinMaxSize>& child_minmax, - const Length& height) { + const base::Optional<MinMaxSize>& child_minmax) { + const Length& min_height = style.MinHeight(); if (space.GetWritingMode() != WritingMode::kHorizontalTb) { - return ResolveMinInlineLength(space, style, border_padding, child_minmax, - height, LengthResolvePhase::kLayout); + LayoutUnit resolved_min_height = + ResolveMinInlineLength(space, style, border_padding, child_minmax, + min_height, LengthResolvePhase::kLayout); + if (!IsTable(style)) + return resolved_min_height; + LayoutUnit resolved_height = ResolveMainInlineLength( + space, style, border_padding, child_minmax, style.Height()); + return std::max(resolved_min_height, resolved_height); } LayoutUnit computed_height = child_minmax.has_value() ? child_minmax->max_size : LayoutUnit(); - return ResolveMinBlockLength(space, style, border_padding, height, + return ResolveMinBlockLength(space, style, border_padding, min_height, computed_height, LengthResolvePhase::kLayout); } @@ -346,12 +382,12 @@ // If calculated width is outside of min/max constraints, // rerun the algorithm with constrained width. - LayoutUnit min = ResolveMinWidth(space, style, border_padding, child_minmax, - style.MinWidth()); + LayoutUnit min = ResolveMinWidth(space, style, border_padding, child_minmax); LayoutUnit max = ResolveMaxWidth(space, style, border_padding, child_minmax, style.MaxWidth()); - if (width != ConstrainByMinMax(*width, min, max)) { - width = ConstrainByMinMax(*width, min, max); + LayoutUnit constrained_width = ConstrainByMinMax(*width, min, max); + if (width != constrained_width) { + width = constrained_width; // Because this function only changes "width" when it's not already // set, it is safe to recursively call ourselves here because on the // second call it is guaranteed to be within min..max. @@ -512,8 +548,7 @@ // If calculated height is outside of min/max constraints, // rerun the algorithm with constrained width. - LayoutUnit min = ResolveMinHeight(space, style, border_padding, child_minmax, - style.MinHeight()); + LayoutUnit min = ResolveMinHeight(space, style, border_padding, child_minmax); LayoutUnit max = ResolveMaxHeight(space, style, border_padding, child_minmax, style.MaxHeight()); if (height != ConstrainByMinMax(*height, min, max)) { @@ -619,7 +654,7 @@ NGAbsolutePhysicalPosition position; if (style.IsHorizontalWritingMode()) { base::Optional<LayoutUnit> width; - if (!style.Width().IsAuto()) { + if (!TableAwareWidth(style).IsAuto()) { width = ResolveMainWidth(space, style, border_padding, child_minmax, style.Width()); } else if (replaced_size.has_value()) { @@ -630,7 +665,7 @@ container_writing_mode, container_direction, &position); } else { base::Optional<LayoutUnit> height; - if (!style.Height().IsAuto()) { + if (!TableAwareHeight(style).IsAuto()) { height = ResolveMainHeight(space, style, border_padding, child_minmax, style.Height()); } else if (replaced_size.has_value()) { @@ -663,7 +698,7 @@ } if (style.IsHorizontalWritingMode()) { base::Optional<LayoutUnit> height; - if (!style.Height().IsAuto()) { + if (!TableAwareHeight(style).IsAuto()) { height = ResolveMainHeight(space, style, border_padding, child_minmax, style.Height()); } else if (replaced_size.has_value()) { @@ -674,7 +709,7 @@ container_writing_mode, container_direction, position); } else { base::Optional<LayoutUnit> width; - if (!style.Width().IsAuto()) { + if (!TableAwareWidth(style).IsAuto()) { width = ResolveMainWidth(space, style, border_padding, child_minmax, style.Width()); } else if (replaced_size.has_value()) {
diff --git a/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc index 8f1a91af..9bf6cbb 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc
@@ -380,17 +380,26 @@ const NGBoxStrut& border_padding, const MinMaxSizeInput& input) { LayoutBox* box = node.GetLayoutBox(); - if (!box->PreferredLogicalWidthsDirty() && - !box->NeedsPreferredWidthsRecalculation()) { + // If we've already populated the legacy preferred logical widths cache for + // this node at the bottom of this function, use those cached results here. + // Or, if we're working on a table, use the legacy preferred widths code + // instead of ComputeMinAndMaxContentContribution below because + // ComputeMinAndMaxContentContribution assumes that if an element has a + // specified size, that's its final size, which tables don't follow. + if ((!box->PreferredLogicalWidthsDirty() && + !box->NeedsPreferredWidthsRecalculation()) || + box->IsTable()) { return MinMaxSize{box->MinPreferredLogicalWidth(), box->MaxPreferredLogicalWidth()}; } + // Compute the intrinsic sizes without regard to the specified sizes. MinMaxSize result = node.ComputeMinMaxSize(node.Style().GetWritingMode(), input, &constraint_space); - // Cache these computed values. + // Apply the specified min, main, max sizes. MinMaxSize contribution = ComputeMinAndMaxContentContribution( node.Style().GetWritingMode(), node.Style(), border_padding, result); + // Cache these computed values. box->SetPreferredLogicalWidthsFromNG(contribution); return result; }
diff --git a/third_party/blink/renderer/core/loader/frame_load_request.cc b/third_party/blink/renderer/core/loader/frame_load_request.cc index 1b788678..f04f0034 100644 --- a/third_party/blink/renderer/core/loader/frame_load_request.cc +++ b/third_party/blink/renderer/core/loader/frame_load_request.cc
@@ -37,7 +37,8 @@ // TODO(domfarolino): Stop storing ResourceRequest's generated referrer as a // header and instead use a separate member. See https://crbug.com/850813. - request.SetHttpReferrer(referrer); + request.SetHttpReferrer( + referrer, ResourceRequest::SetHttpReferrerLocation::kFrameLoadRequest); request.SetHTTPOriginToMatchReferrerIfNeeded(); }
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc index 3e36506..ba0149f 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.cc +++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -156,9 +156,11 @@ // header and instead use a separate member. See https://crbug.com/850813. if (client_redirect_policy == ClientRedirectPolicy::kClientRedirect) { request.SetHttpReferrer(SecurityPolicy::GenerateReferrer( - frame_->GetDocument()->GetReferrerPolicy(), - frame_->GetDocument()->Url(), - frame_->GetDocument()->OutgoingReferrer())); + frame_->GetDocument()->GetReferrerPolicy(), + frame_->GetDocument()->Url(), + frame_->GetDocument()->OutgoingReferrer()), + ResourceRequest::SetHttpReferrerLocation:: + kFrameLoaderResourceRequestForReload); } request.SetSkipServiceWorker(frame_load_type ==
diff --git a/third_party/blink/renderer/core/loader/history_item.cc b/third_party/blink/renderer/core/loader/history_item.cc index 9bf4ae2..2c77a07c 100644 --- a/third_party/blink/renderer/core/loader/history_item.cc +++ b/third_party/blink/renderer/core/loader/history_item.cc
@@ -151,9 +151,12 @@ ResourceRequest HistoryItem::GenerateResourceRequest( mojom::FetchCacheMode cache_mode) { ResourceRequest request(url_string_); - // TODO(domfarolino): Stop storing ResourceRequest's generated referrer as a - // header and instead use a separate member. See https://crbug.com/850813. - request.SetHttpReferrer(referrer_); + request.SetReferrerString( + referrer_.referrer, + ResourceRequest::SetReferrerStringLocation::kHistoryItem); + request.SetReferrerPolicy( + referrer_.referrer_policy, + ResourceRequest::SetReferrerPolicyLocation::kHistoryItem); request.SetCacheMode(cache_mode); if (form_data_) { request.SetHttpMethod(http_names::kPOST);
diff --git a/third_party/blink/renderer/core/loader/image_loader.cc b/third_party/blink/renderer/core/loader/image_loader.cc index abb548d..8ba1d7d9 100644 --- a/third_party/blink/renderer/core/loader/image_loader.cc +++ b/third_party/blink/renderer/core/loader/image_loader.cc
@@ -555,7 +555,9 @@ resource_request.SetPreviewsState(WebURLRequest::kPreviewsNoTransform); } - resource_request.SetReferrerPolicy(referrer_policy); + resource_request.SetReferrerPolicy( + referrer_policy, + ResourceRequest::SetReferrerPolicyLocation::kImageLoader); // Correct the RequestContext if necessary. if (IsHTMLPictureElement(GetElement()->parentNode()) ||
diff --git a/third_party/blink/renderer/core/loader/link_loader.cc b/third_party/blink/renderer/core/loader/link_loader.cc index e8c9a52..cdb64f1 100644 --- a/third_party/blink/renderer/core/loader/link_loader.cc +++ b/third_party/blink/renderer/core/loader/link_loader.cc
@@ -226,7 +226,9 @@ Document& document, ResourceClient* link_client) { ResourceRequest resource_request(document.CompleteURL(params.href)); - resource_request.SetReferrerPolicy(params.referrer_policy); + resource_request.SetReferrerPolicy( + params.referrer_policy, + ResourceRequest::SetReferrerPolicyLocation::kLoadStylesheet); mojom::FetchImportanceMode importance_mode = GetFetchImportanceAttributeValue(params.importance);
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_script_loader.cc b/third_party/blink/renderer/core/loader/modulescript/module_script_loader.cc index 29a5405..9e76c02c 100644 --- a/third_party/blink/renderer/core/loader/modulescript/module_script_loader.cc +++ b/third_party/blink/renderer/core/loader/modulescript/module_script_loader.cc
@@ -161,12 +161,9 @@ // <spec label="SMSR">... its referrer policy to options's referrer // policy.</spec> - // - // Note: For now this is done below with SetHttpReferrer() - network::mojom::ReferrerPolicy referrer_policy = - module_request.Options().GetReferrerPolicy(); - if (referrer_policy == network::mojom::ReferrerPolicy::kDefault) - referrer_policy = fetch_client_settings_object.GetReferrerPolicy(); + fetch_params.MutableResourceRequest().SetReferrerPolicy( + module_request.Options().GetReferrerPolicy(), + ResourceRequest::SetReferrerPolicyLocation::kModuleLoader); // <spec step="5">... mode is "cors", ...</spec> // @@ -177,18 +174,9 @@ options_.CredentialsMode()); // <spec step="5">... referrer is referrer, ...</spec> - // - // Note: For now this is done below with SetHttpReferrer() - String referrer_string = module_request.ReferrerString(); - if (referrer_string == Referrer::ClientReferrerString()) - referrer_string = fetch_client_settings_object.GetOutgoingReferrer(); - - // TODO(domfarolino): Stop storing ResourceRequest's referrer as a - // blink::Referrer (https://crbug.com/850813). - fetch_params.MutableResourceRequest().SetHttpReferrer( - SecurityPolicy::GenerateReferrer(referrer_policy, - fetch_params.GetResourceRequest().Url(), - referrer_string)); + fetch_params.MutableResourceRequest().SetReferrerString( + module_request.ReferrerString(), + ResourceRequest::SetReferrerStringLocation::kModuleScriptLoader); // Priority Hints and a request's "importance" are currently non-standard, but // we can assume the following (see https://crbug.com/821464):
diff --git a/third_party/blink/renderer/core/loader/ping_loader.cc b/third_party/blink/renderer/core/loader/ping_loader.cc index 4c1cd9a..2451d28 100644 --- a/third_party/blink/renderer/core/loader/ping_loader.cc +++ b/third_party/blink/renderer/core/loader/ping_loader.cc
@@ -228,8 +228,12 @@ request.SetKeepalive(true); // TODO(domfarolino): Add WPTs ensuring that pings do not have a referrer // header. - request.SetReferrerString(Referrer::NoReferrer()); - request.SetReferrerPolicy(network::mojom::ReferrerPolicy::kNever); + request.SetReferrerString( + Referrer::NoReferrer(), + ResourceRequest::SetReferrerStringLocation::kPingLoader); + request.SetReferrerPolicy( + network::mojom::ReferrerPolicy::kNever, + ResourceRequest::SetReferrerPolicyLocation::kPingLoader); request.SetRequestContext(mojom::RequestContextType::PING); FetchParameters params(request); params.MutableOptions().initiator_info.name =
diff --git a/third_party/blink/renderer/core/loader/preload_helper.cc b/third_party/blink/renderer/core/loader/preload_helper.cc index c19ecc5f..7c5fe741 100644 --- a/third_party/blink/renderer/core/loader/preload_helper.cc +++ b/third_party/blink/renderer/core/loader/preload_helper.cc
@@ -280,7 +280,9 @@ resource_request.SetRequestContext(ResourceFetcher::DetermineRequestContext( resource_type.value(), ResourceFetcher::kImageNotImageSet)); - resource_request.SetReferrerPolicy(params.referrer_policy); + resource_request.SetReferrerPolicy( + params.referrer_policy, + ResourceRequest::SetReferrerPolicyLocation::kPreloadIfNeeded); resource_request.SetFetchImportanceMode( GetFetchImportanceAttributeValue(params.importance)); @@ -462,7 +464,9 @@ UseCounter::Count(document, WebFeature::kLinkRelPrefetch); ResourceRequest resource_request(params.href); - resource_request.SetReferrerPolicy(params.referrer_policy); + resource_request.SetReferrerPolicy( + params.referrer_policy, + ResourceRequest::SetReferrerPolicyLocation::kPrefetchIfNeeded); resource_request.SetFetchImportanceMode( GetFetchImportanceAttributeValue(params.importance));
diff --git a/third_party/blink/renderer/core/loader/threadable_loader.cc b/third_party/blink/renderer/core/loader/threadable_loader.cc index c216056..315de07f 100644 --- a/third_party/blink/renderer/core/loader/threadable_loader.cc +++ b/third_party/blink/renderer/core/loader/threadable_loader.cc
@@ -169,8 +169,14 @@ preflight_request->SetRequestContext(request.GetRequestContext()); preflight_request->SetCredentialsMode(network::mojom::CredentialsMode::kOmit); preflight_request->SetSkipServiceWorker(true); - preflight_request->SetReferrerString(request.ReferrerString()); - preflight_request->SetReferrerPolicy(request.GetReferrerPolicy()); + preflight_request->SetReferrerString( + request.ReferrerString(), + ResourceRequest::SetReferrerStringLocation:: + kThreadableLoaderCreateAccessControlPreflightRequest); + preflight_request->SetReferrerPolicy( + request.GetReferrerPolicy(), + ResourceRequest::SetReferrerPolicyLocation:: + kThreadableLoaderCreateAccessControlPreflightRequest); if (request.IsExternalRequest()) { preflight_request->SetHttpHeaderField( @@ -341,10 +347,14 @@ if (GetSecurityOrigin()) request.SetHTTPOrigin(GetSecurityOrigin()); - // TODO(domfarolino): Stop setting the HTTPReferrer header, and instead use - // ResourceRequest::referrer_. See https://crbug.com/850813. - if (override_referrer_) - request.SetHttpReferrer(referrer_after_redirect_); + if (override_referrer_) { + request.SetReferrerString(referrer_after_redirect_.referrer, + ResourceRequest::SetReferrerStringLocation:: + kThreadableLoaderPrepareCrossOriginRequest); + request.SetReferrerPolicy(referrer_after_redirect_.referrer_policy, + ResourceRequest::SetReferrerPolicyLocation:: + kThreadableLoaderPrepareCrossOriginRequest); + } } void ThreadableLoader::LoadPreflightRequest(
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc index 2770d44..4ac1e0f 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
@@ -6533,7 +6533,7 @@ properties->Effect()->GetCompositorElementId()); ASSERT_TRUE(cc_effect); EXPECT_FLOAT_EQ(cc_effect->opacity, 0.5f); - EXPECT_FALSE(cc_effect->effect_changed); + EXPECT_TRUE(cc_effect->effect_changed); EXPECT_FALSE(GetChromeClient() .layer_tree_host() ->property_trees()
diff --git a/third_party/blink/renderer/modules/locks/lock.cc b/third_party/blink/renderer/modules/locks/lock.cc index 515ce51..330079cb 100644 --- a/third_party/blink/renderer/modules/locks/lock.cc +++ b/third_party/blink/renderer/modules/locks/lock.cc
@@ -87,6 +87,10 @@ Lock::~Lock() = default; +void Lock::Dispose() { + handle_.reset(); +} + String Lock::mode() const { return ModeToString(mode_); }
diff --git a/third_party/blink/renderer/modules/locks/lock.h b/third_party/blink/renderer/modules/locks/lock.h index f5fe9d4..749569c 100644 --- a/third_party/blink/renderer/modules/locks/lock.h +++ b/third_party/blink/renderer/modules/locks/lock.h
@@ -22,7 +22,7 @@ class Lock final : public ScriptWrappable, public ContextLifecycleObserver { DEFINE_WRAPPERTYPEINFO(); USING_GARBAGE_COLLECTED_MIXIN(Lock); - + USING_PRE_FINALIZER(Lock, Dispose); public: static Lock* Create(ScriptState*, const String& name, @@ -38,7 +38,8 @@ ~Lock() override; void Trace(blink::Visitor*) override; - EAGERLY_FINALIZE(); + + void Dispose(); // Lock.idl String name() const { return name_; }
diff --git a/third_party/blink/renderer/modules/locks/lock_manager.cc b/third_party/blink/renderer/modules/locks/lock_manager.cc index 2ee7e0ab..bae478c4 100644 --- a/third_party/blink/renderer/modules/locks/lock_manager.cc +++ b/third_party/blink/renderer/modules/locks/lock_manager.cc
@@ -56,7 +56,7 @@ : public GarbageCollectedFinalized<LockRequestImpl>, public NameClient, public mojom::blink::LockRequest { - EAGERLY_FINALIZE(); + USING_PRE_FINALIZER(LockManager::LockRequestImpl, Dispose); public: LockRequestImpl(V8LockGrantedCallback* callback, @@ -78,6 +78,12 @@ ~LockRequestImpl() override = default; + void Dispose() { + // This Impl might still be bound to a LockRequest, so we close + // the binding before destroying the object. + binding_.Close(); + } + void Trace(blink::Visitor* visitor) { visitor->Trace(resolver_); visitor->Trace(manager_);
diff --git a/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.cc b/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.cc index 2ef0997..e82074b 100644 --- a/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.cc +++ b/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.cc
@@ -119,16 +119,10 @@ audio_codec_id_(AudioTrackRecorder::CodecId::LAST), recording_(false), recorder_(nullptr), - task_runner_(std::move(task_runner)), - weak_factory_(this) {} + task_runner_(std::move(task_runner)) {} MediaRecorderHandler::~MediaRecorderHandler() = default; -void MediaRecorderHandler::Dispose() { - webm_muxer_.reset(); - task_runner_.reset(); -} - bool MediaRecorderHandler::CanSupportMimeType(const String& type, const String& web_codecs) { DCHECK(IsMainThread()); @@ -259,7 +253,7 @@ CodecIdToMediaAudioCodec(audio_codec_id_), use_video_tracks, use_audio_tracks, WTF::BindRepeating(&MediaRecorderHandler::WriteData, - weak_factory_.GetWeakPtr()))); + WrapWeakPersistent(this)))); if (use_video_tracks) { // TODO(mcasas): The muxer API supports only one video track. Extend it to @@ -272,7 +266,7 @@ const VideoTrackRecorder::OnEncodedVideoCB on_encoded_video_cb = media::BindToCurrentLoop(WTF::BindRepeating( - &MediaRecorderHandler::OnEncodedVideo, weak_factory_.GetWeakPtr())); + &MediaRecorderHandler::OnEncodedVideo, WrapWeakPersistent(this))); video_recorders_.emplace_back(MakeGarbageCollected<VideoTrackRecorder>( video_codec_id_, video_tracks_[0], on_encoded_video_cb, @@ -290,7 +284,7 @@ const AudioTrackRecorder::OnEncodedAudioCB on_encoded_audio_cb = media::BindToCurrentLoop(base::Bind( - &MediaRecorderHandler::OnEncodedAudio, weak_factory_.GetWeakPtr())); + &MediaRecorderHandler::OnEncodedAudio, WrapWeakPersistent(this))); audio_recorders_.emplace_back(MakeGarbageCollected<AudioTrackRecorder>( audio_codec_id_, audio_tracks_[0], std::move(on_encoded_audio_cb), @@ -305,7 +299,6 @@ DCHECK(IsMainThread()); // Don't check |recording_| since we can go directly from pause() to stop(). - weak_factory_.InvalidateWeakPtrs(); recording_ = false; timeslice_ = base::TimeDelta::FromMilliseconds(0); video_recorders_.clear(); @@ -465,6 +458,9 @@ bool is_key_frame) { DCHECK(IsMainThread()); + if (video_recorders_.IsEmpty()) + return; + if (UpdateTracksAndCheckIfChanged()) { recorder_->OnError("Amount of tracks in MediaStream has changed."); return; @@ -484,6 +480,9 @@ base::TimeTicks timestamp) { DCHECK(IsMainThread()); + if (audio_recorders_.IsEmpty()) + return; + if (UpdateTracksAndCheckIfChanged()) { recorder_->OnError("Amount of tracks in MediaStream has changed."); return;
diff --git a/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h b/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h index b5f413b..7c3da873 100644 --- a/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h +++ b/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h
@@ -8,7 +8,6 @@ #include <memory> #include "base/macros.h" -#include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" #include "base/strings/string_piece.h" #include "base/threading/thread_checker.h" @@ -45,7 +44,6 @@ // guarantee this, since VideoTrackRecorder sends back frames on IO thread.) class MODULES_EXPORT MediaRecorderHandler : public GarbageCollectedFinalized<MediaRecorderHandler> { - USING_PRE_FINALIZER(MediaRecorderHandler, Dispose); public: static MediaRecorderHandler* Create( @@ -82,8 +80,6 @@ OnMediaCapabilitiesEncodingInfoCallback cb); String ActualMimeType(); - void Dispose(); - void Trace(blink::Visitor*); private: @@ -143,8 +139,6 @@ scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - base::WeakPtrFactory<MediaRecorderHandler> weak_factory_; - DISALLOW_COPY_AND_ASSIGN(MediaRecorderHandler); };
diff --git a/third_party/blink/renderer/modules/mediastream/BUILD.gn b/third_party/blink/renderer/modules/mediastream/BUILD.gn index 44a6c33..59cffa5 100644 --- a/third_party/blink/renderer/modules/mediastream/BUILD.gn +++ b/third_party/blink/renderer/modules/mediastream/BUILD.gn
@@ -12,6 +12,7 @@ "dom_window_media_stream.h", "input_device_info.cc", "input_device_info.h", + "local_media_stream_audio_source.cc", "media_constraints_impl.cc", "media_constraints_impl.h", "media_device_info.cc",
diff --git a/third_party/blink/renderer/modules/mediastream/DEPS b/third_party/blink/renderer/modules/mediastream/DEPS index e47c304..de4a7a0 100644 --- a/third_party/blink/renderer/modules/mediastream/DEPS +++ b/third_party/blink/renderer/modules/mediastream/DEPS
@@ -3,6 +3,7 @@ # migrated to WTF types in mediastream. "+base/strings/utf_string_conversions.h", "+base/strings/string_number_conversions.h", + "+base/strings/stringprintf.h", "+base/containers/flat_map.h", "+base/callback_helpers.h", @@ -12,6 +13,7 @@ "+base/threading/thread_task_runner_handle.h", "+base/trace_event/trace_event.h", + "+media/audio", "+media/base", "+media/capture", "+media/mojo/interfaces",
diff --git a/content/renderer/media/stream/local_media_stream_audio_source.cc b/third_party/blink/renderer/modules/mediastream/local_media_stream_audio_source.cc similarity index 63% rename from content/renderer/media/stream/local_media_stream_audio_source.cc rename to third_party/blink/renderer/modules/mediastream/local_media_stream_audio_source.cc index f13deb03e..3a1fead 100644 --- a/content/renderer/media/stream/local_media_stream_audio_source.cc +++ b/third_party/blink/renderer/modules/mediastream/local_media_stream_audio_source.cc
@@ -2,28 +2,50 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/renderer/media/stream/local_media_stream_audio_source.h" +#include "third_party/blink/public/web/modules/mediastream/local_media_stream_audio_source.h" #include <utility> -#include "content/renderer/media/audio/audio_device_factory.h" -#include "content/renderer/render_frame_impl.h" +#include "base/strings/stringprintf.h" +#include "media/audio/audio_source_parameters.h" #include "third_party/blink/public/mojom/mediastream/media_stream.mojom-shared.h" #include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h" +#include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/web/web_local_frame.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" -namespace content { +namespace blink { + +class LocalMediaStreamAudioSource::InternalFrame { + public: + explicit InternalFrame(WebLocalFrame* web_frame) + : frame_(web_frame ? static_cast<LocalFrame*>( + WebLocalFrame::ToCoreFrame(*web_frame)) + : nullptr) {} + + LocalFrame* frame() { return frame_.Get(); } + WebLocalFrame* web_frame() { + if (!frame_) + return nullptr; + + return static_cast<WebLocalFrame*>(WebFrame::FromFrame(frame())); + } + + private: + WeakPersistent<LocalFrame> frame_; +}; LocalMediaStreamAudioSource::LocalMediaStreamAudioSource( - int consumer_render_frame_id, - const blink::MediaStreamDevice& device, + WebLocalFrame* web_frame, + const MediaStreamDevice& device, const int* requested_buffer_size, bool disable_local_echo, ConstraintsRepeatingCallback started_callback, scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : blink::MediaStreamAudioSource(std::move(task_runner), - true /* is_local_source */, - disable_local_echo), - consumer_render_frame_id_(consumer_render_frame_id), + : MediaStreamAudioSource(std::move(task_runner), + true /* is_local_source */, + disable_local_echo), + internal_consumer_frame_(std::make_unique<InternalFrame>(web_frame)), started_callback_(std::move(started_callback)) { DVLOG(1) << "LocalMediaStreamAudioSource::LocalMediaStreamAudioSource()"; SetDevice(device); @@ -35,7 +57,7 @@ // If the device buffer size was not provided, use a default. if (frames_per_buffer <= 0) { frames_per_buffer = - (device.input.sample_rate() * blink::kFallbackAudioLatencyMs) / 1000; + (device.input.sample_rate() * kFallbackAudioLatencyMs) / 1000; } // Set audio format and take into account the special case where a discrete @@ -63,27 +85,26 @@ return true; std::string str = base::StringPrintf( - "LocalMediaStreamAudioSource::EnsureSourceIsStarted. render_frame_id=%d" - ", channel_layout=%d, sample_rate=%d, buffer_size=%d" + "LocalMediaStreamAudioSource::EnsureSourceIsStarted." + " channel_layout=%d, sample_rate=%d, buffer_size=%d" ", session_id=%d, effects=%d. ", - consumer_render_frame_id_, device().input.channel_layout(), - device().input.sample_rate(), device().input.frames_per_buffer(), - device().session_id, device().input.effects()); - blink::WebRtcLogMessage(str); + device().input.channel_layout(), device().input.sample_rate(), + device().input.frames_per_buffer(), device().session_id, + device().input.effects()); + WebRtcLogMessage(str); DVLOG(1) << str; - // Sanity-check that the consuming RenderFrame still exists. This is required - // by AudioDeviceFactory. - if (!RenderFrameImpl::FromRoutingID(consumer_render_frame_id_)) + // Sanity-check that the consuming WebLocalFrame still exists. + // This is required by AudioDeviceFactory. + if (!internal_consumer_frame_->web_frame()) return false; VLOG(1) << "Starting local audio input device (session_id=" - << device().session_id << ") for render frame " - << consumer_render_frame_id_ << " with audio parameters={" + << device().session_id << ") with audio parameters={" << GetAudioParameters().AsHumanReadableString() << "}."; - source_ = AudioDeviceFactory::NewAudioCapturerSource( - consumer_render_frame_id_, + source_ = Platform::Current()->NewAudioCapturerSource( + internal_consumer_frame_->web_frame(), media::AudioSourceParameters(device().session_id)); source_->Initialize(GetAudioParameters(), this); source_->Start(); @@ -100,13 +121,12 @@ source_ = nullptr; VLOG(1) << "Stopped local audio input device (session_id=" - << device().session_id << ") for render frame " - << consumer_render_frame_id_ << " with audio parameters={" + << device().session_id << ") with audio parameters={" << GetAudioParameters().AsHumanReadableString() << "}."; } void LocalMediaStreamAudioSource::OnCaptureStarted() { - started_callback_.Run(this, blink::mojom::MediaStreamRequestResult::OK, ""); + started_callback_.Run(this, mojom::MediaStreamRequestResult::OK, ""); } void LocalMediaStreamAudioSource::Capture(const media::AudioBus* audio_bus, @@ -123,8 +143,7 @@ } void LocalMediaStreamAudioSource::OnCaptureError(const std::string& why) { - blink::WebRtcLogMessage("LocalMediaStreamAudioSource::OnCaptureError: " + - why); + WebRtcLogMessage("LocalMediaStreamAudioSource::OnCaptureError: " + why); StopSourceOnError(why); } @@ -133,8 +152,8 @@ } void LocalMediaStreamAudioSource::ChangeSourceImpl( - const blink::MediaStreamDevice& new_device) { - blink::WebRtcLogMessage( + const MediaStreamDevice& new_device) { + WebRtcLogMessage( "LocalMediaStreamAudioSource::ChangeSourceImpl(new_device = " + new_device.id + ")"); EnsureSourceIsStopped(); @@ -142,4 +161,4 @@ EnsureSourceIsStarted(); } -} // namespace content +} // namespace blink
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index 6864404..1f179ec 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -1632,6 +1632,7 @@ "bindings/runtime_call_stats_test.cc", "exported/file_path_conversion_test.cc", "exported/mediastream/media_stream_audio_processor_options_test.cc", + "exported/mediastream/media_stream_audio_test.cc", "exported/mediastream/webrtc_uma_histograms_test.cc", "exported/web_canonical_cookie_test.cc", "exported/web_string_test.cc",
diff --git a/third_party/blink/renderer/platform/exported/mediastream/DEPS b/third_party/blink/renderer/platform/exported/mediastream/DEPS index 731f240..0544038 100644 --- a/third_party/blink/renderer/platform/exported/mediastream/DEPS +++ b/third_party/blink/renderer/platform/exported/mediastream/DEPS
@@ -1,10 +1,9 @@ - include_rules = [ - # TODO(crbug.com/923394): Remove these dependencies once std types are - # migrated to WTF types in mediastream. - "+base/strings/utf_string_conversions.h", - "+base/strings/string_number_conversions.h", - "+base/strings/string_split.h", - "+media/base", ] + +specific_include_rules = { + "media_stream_audio_test\.cc" : [ + "+base/threading/platform_thread.h", + ], +}
diff --git a/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_processor_options.cc b/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_processor_options.cc index 18c87df1..c70fc40c 100644 --- a/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_processor_options.cc +++ b/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_processor_options.cc
@@ -14,10 +14,7 @@ #include "base/logging.h" #include "base/macros.h" #include "base/metrics/histogram_macros.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_split.h" #include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "build/build_config.h" #include "media/base/audio_parameters.h"
diff --git a/content/renderer/media/stream/media_stream_audio_unittest.cc b/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_test.cc similarity index 82% rename from content/renderer/media/stream/media_stream_audio_unittest.cc rename to third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_test.cc index 8311e76..7cb47ded 100644 --- a/content/renderer/media/stream/media_stream_audio_unittest.cc +++ b/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_test.cc
@@ -4,7 +4,6 @@ #include <stdint.h> -#include "base/atomicops.h" #include "base/synchronization/lock.h" #include "base/synchronization/waitable_event.h" #include "base/test/scoped_task_environment.h" @@ -21,7 +20,7 @@ #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/web/web_heap.h" -namespace content { +namespace blink { namespace { @@ -35,41 +34,40 @@ // emits audio samples with monotonically-increasing sample values. Includes // hooks for the unit tests to confirm lifecycle status and to change audio // format. -class FakeMediaStreamAudioSource : public blink::MediaStreamAudioSource, +class FakeMediaStreamAudioSource : public MediaStreamAudioSource, public base::PlatformThread::Delegate { public: FakeMediaStreamAudioSource() - : blink::MediaStreamAudioSource( - blink::scheduler::GetSingleThreadTaskRunnerForTesting(), - true), + : MediaStreamAudioSource(scheduler::GetSingleThreadTaskRunnerForTesting(), + true), stop_event_(base::WaitableEvent::ResetPolicy::MANUAL, base::WaitableEvent::InitialState::NOT_SIGNALED), next_buffer_size_(kBufferSize), sample_count_(0) {} ~FakeMediaStreamAudioSource() final { - CHECK(main_thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); EnsureSourceIsStopped(); } bool was_started() const { - CHECK(main_thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); return !thread_.is_null(); } bool was_stopped() const { - CHECK(main_thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); return stop_event_.IsSignaled(); } void SetBufferSize(int new_buffer_size) { - CHECK(main_thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); base::subtle::NoBarrier_Store(&next_buffer_size_, new_buffer_size); } protected: bool EnsureSourceIsStarted() final { - CHECK(main_thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); if (was_started()) return true; if (was_stopped()) @@ -80,7 +78,7 @@ } void EnsureSourceIsStopped() final { - CHECK(main_thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); if (was_stopped()) return; stop_event_.Signal(); @@ -93,7 +91,7 @@ // If needed, notify of the new format and re-create |audio_bus_|. const int buffer_size = base::subtle::NoBarrier_Load(&next_buffer_size_); if (!audio_bus_ || audio_bus_->frames() != buffer_size) { - blink::MediaStreamAudioSource::SetFormat(media::AudioParameters( + MediaStreamAudioSource::SetFormat(media::AudioParameters( media::AudioParameters::AUDIO_PCM_LOW_LATENCY, media::CHANNEL_LAYOUT_MONO, kSampleRate, buffer_size)); audio_bus_ = media::AudioBus::Create(1, buffer_size); @@ -105,8 +103,8 @@ for (int i = 0; i < buffer_size; ++i) data[i] = ++sample_count_; CHECK_LT(sample_count_, kMaxValueSafelyConvertableToFloat); - blink::MediaStreamAudioSource::DeliverDataToTracks( - *audio_bus_, base::TimeTicks::Now()); + MediaStreamAudioSource::DeliverDataToTracks(*audio_bus_, + base::TimeTicks::Now()); // Sleep before producing the next chunk of audio. base::PlatformThread::Sleep(base::TimeDelta::FromMicroseconds( @@ -115,7 +113,7 @@ } private: - base::ThreadChecker main_thread_checker_; + THREAD_CHECKER(main_thread_checker_); base::PlatformThreadHandle thread_; mutable base::WaitableEvent stop_event_; @@ -127,20 +125,16 @@ DISALLOW_COPY_AND_ASSIGN(FakeMediaStreamAudioSource); }; -// A simple blink::WebMediaStreamAudioSink that consumes audio and confirms the +// A simple WebMediaStreamAudioSink that consumes audio and confirms the // sample values. Includes hooks for the unit tests to monitor the format and // flow of audio, whether the audio is silent, and the propagation of the // "enabled" state. -class FakeMediaStreamAudioSink : public blink::WebMediaStreamAudioSink { +class FakeMediaStreamAudioSink : public WebMediaStreamAudioSink { public: - enum EnableState { - NO_ENABLE_NOTIFICATION, - WAS_ENABLED, - WAS_DISABLED - }; + enum EnableState { NO_ENABLE_NOTIFICATION, WAS_ENABLED, WAS_DISABLED }; FakeMediaStreamAudioSink() - : blink::WebMediaStreamAudioSink(), + : WebMediaStreamAudioSink(), expected_sample_count_(-1), num_on_data_calls_(0), audio_is_silent_(true), @@ -148,32 +142,32 @@ enable_state_(NO_ENABLE_NOTIFICATION) {} ~FakeMediaStreamAudioSink() final { - CHECK(main_thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); } media::AudioParameters params() const { - CHECK(main_thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); base::AutoLock auto_lock(params_lock_); return params_; } int num_on_data_calls() const { - CHECK(main_thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); return base::subtle::NoBarrier_Load(&num_on_data_calls_); } bool is_audio_silent() const { - CHECK(main_thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); return !!base::subtle::NoBarrier_Load(&audio_is_silent_); } bool was_ended() const { - CHECK(main_thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); return was_ended_; } EnableState enable_state() const { - CHECK(main_thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); return enable_state_; } @@ -214,20 +208,19 @@ base::subtle::NoBarrier_AtomicIncrement(&num_on_data_calls_, 1); } - void OnReadyStateChanged( - blink::WebMediaStreamSource::ReadyState state) final { - CHECK(main_thread_checker_.CalledOnValidThread()); - if (state == blink::WebMediaStreamSource::kReadyStateEnded) + void OnReadyStateChanged(WebMediaStreamSource::ReadyState state) final { + DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); + if (state == WebMediaStreamSource::kReadyStateEnded) was_ended_ = true; } void OnEnabledChanged(bool enabled) final { - CHECK(main_thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); enable_state_ = enabled ? WAS_ENABLED : WAS_DISABLED; } private: - base::ThreadChecker main_thread_checker_; + THREAD_CHECKER(main_thread_checker_); mutable base::Lock params_lock_; media::AudioParameters params_; @@ -246,10 +239,9 @@ class MediaStreamAudioTest : public ::testing::Test { protected: void SetUp() override { - blink_audio_source_.Initialize(blink::WebString::FromUTF8("audio_id"), - blink::WebMediaStreamSource::kTypeAudio, - blink::WebString::FromUTF8("audio_track"), - false /* remote */); + blink_audio_source_.Initialize( + WebString::FromUTF8("audio_id"), WebMediaStreamSource::kTypeAudio, + WebString::FromUTF8("audio_track"), false /* remote */); blink_audio_track_.Initialize(blink_audio_source_.Id(), blink_audio_source_); } @@ -257,20 +249,20 @@ void TearDown() override { blink_audio_track_.Reset(); blink_audio_source_.Reset(); - blink::WebHeap::CollectAllGarbageForTesting(); + WebHeap::CollectAllGarbageForTesting(); } FakeMediaStreamAudioSource* source() const { return static_cast<FakeMediaStreamAudioSource*>( - blink::MediaStreamAudioSource::From(blink_audio_source_)); + MediaStreamAudioSource::From(blink_audio_source_)); } - blink::MediaStreamAudioTrack* track() const { - return blink::MediaStreamAudioTrack::From(blink_audio_track_); + MediaStreamAudioTrack* track() const { + return MediaStreamAudioTrack::From(blink_audio_track_); } - blink::WebMediaStreamSource blink_audio_source_; - blink::WebMediaStreamTrack blink_audio_track_; + WebMediaStreamSource blink_audio_source_; + WebMediaStreamTrack blink_audio_track_; base::test::ScopedTaskEnvironment task_environment_; }; @@ -335,19 +327,19 @@ // Now, connect another track. ConnectToTrack() will return false, but there // should be a MediaStreamAudioTrack instance created and owned by the - // blink::WebMediaStreamTrack. - blink::WebMediaStreamTrack another_blink_track; + // WebMediaStreamTrack. + WebMediaStreamTrack another_blink_track; another_blink_track.Initialize(blink_audio_source_.Id(), blink_audio_source_); - EXPECT_FALSE(blink::MediaStreamAudioTrack::From(another_blink_track)); + EXPECT_FALSE(MediaStreamAudioTrack::From(another_blink_track)); EXPECT_FALSE(source()->ConnectToTrack(another_blink_track)); - EXPECT_TRUE(blink::MediaStreamAudioTrack::From(another_blink_track)); + EXPECT_TRUE(MediaStreamAudioTrack::From(another_blink_track)); } // Tests that a sink is immediately "ended" when connected to a stopped track. TEST_F(MediaStreamAudioTest, AddSinkToStoppedTrack) { // Create a track and stop it. Then, when adding a sink, the sink should get // the ReadyStateEnded notification immediately. - blink::MediaStreamAudioTrack track(true); + MediaStreamAudioTrack track(true); track.Stop(); FakeMediaStreamAudioSink sink; EXPECT_FALSE(sink.was_ended()); @@ -428,13 +420,12 @@ // Create a second track and a second sink, but this time the track starts out // disabled. Expect the sink to be notified at the start that the track is // disabled. - blink::WebMediaStreamTrack another_blink_track; + WebMediaStreamTrack another_blink_track; another_blink_track.Initialize(blink_audio_source_.Id(), blink_audio_source_); EXPECT_TRUE(source()->ConnectToTrack(another_blink_track)); - blink::MediaStreamAudioTrack::From(another_blink_track)->SetEnabled(false); + MediaStreamAudioTrack::From(another_blink_track)->SetEnabled(false); FakeMediaStreamAudioSink another_sink; - blink::MediaStreamAudioTrack::From(another_blink_track) - ->AddSink(&another_sink); + MediaStreamAudioTrack::From(another_blink_track)->AddSink(&another_sink); EXPECT_EQ(FakeMediaStreamAudioSink::WAS_DISABLED, another_sink.enable_state()); @@ -446,7 +437,7 @@ EXPECT_TRUE(another_sink.is_audio_silent()); // Now, enable the second track and expect the second sink to be notified. - blink::MediaStreamAudioTrack::From(another_blink_track)->SetEnabled(true); + MediaStreamAudioTrack::From(another_blink_track)->SetEnabled(true); EXPECT_EQ(FakeMediaStreamAudioSink::WAS_ENABLED, another_sink.enable_state()); // Wait until non-silent audio reaches the second sink. @@ -459,9 +450,8 @@ EXPECT_EQ(FakeMediaStreamAudioSink::WAS_DISABLED, sink.enable_state()); EXPECT_TRUE(sink.is_audio_silent()); - blink::MediaStreamAudioTrack::From(another_blink_track) - ->RemoveSink(&another_sink); + MediaStreamAudioTrack::From(another_blink_track)->RemoveSink(&another_sink); track()->RemoveSink(&sink); } -} // namespace content +} // namespace blink
diff --git a/third_party/blink/renderer/platform/exported/web_url_request.cc b/third_party/blink/renderer/platform/exported/web_url_request.cc index 2f47655e..d2530d9c 100644 --- a/third_party/blink/renderer/platform/exported/web_url_request.cc +++ b/third_party/blink/renderer/platform/exported/web_url_request.cc
@@ -172,7 +172,9 @@ web_referrer.IsEmpty() ? Referrer::NoReferrer() : String(web_referrer); // TODO(domfarolino): Stop storing ResourceRequest's generated referrer as a // header and instead use a separate member. See https://crbug.com/850813. - resource_request_->SetHttpReferrer(Referrer(referrer, referrer_policy)); + resource_request_->SetHttpReferrer( + Referrer(referrer, referrer_policy), + ResourceRequest::SetHttpReferrerLocation::kWebURLRequest); } void WebURLRequest::AddHttpHeaderField(const WebString& name,
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc index 8277835..4c596286 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
@@ -114,8 +114,12 @@ } const cc::TransformNode& GetTransformNode(const cc::Layer* layer) { - auto* property_trees = layer_tree_->layer_tree_host()->property_trees(); - return *property_trees->transform_tree.Node(layer->transform_tree_index()); + return *GetPropertyTrees().transform_tree.Node( + layer->transform_tree_index()); + } + + const cc::EffectNode& GetEffectNode(const cc::Layer* layer) { + return *GetPropertyTrees().effect_tree.Node(layer->effect_tree_index()); } const cc::LayerTreeHost& GetLayerTreeHost() { @@ -317,6 +321,7 @@ Pointee(DrawsRectangle(FloatRect(0, 0, 100, 100), Color::kWhite))); EXPECT_EQ(Translation(50, -50), child->ScreenSpaceTransform()); EXPECT_EQ(gfx::Size(100, 100), child->bounds()); + EXPECT_FALSE(GetTransformNode(child).transform_changed); } TEST_P(PaintArtifactCompositorTest, OneTransform) { @@ -336,6 +341,7 @@ ASSERT_EQ(2u, ContentLayerCount()); { const cc::Layer* layer = ContentLayerAt(0); + EXPECT_TRUE(GetTransformNode(layer).transform_changed); Vector<RectWithColor> rects_with_color; rects_with_color.push_back( @@ -351,6 +357,7 @@ } { const cc::Layer* layer = ContentLayerAt(1); + EXPECT_FALSE(GetTransformNode(layer).transform_changed); EXPECT_THAT( layer->GetPicture(), Pointee(DrawsRectangle(FloatRect(0, 0, 100, 100), Color::kGray))); @@ -376,6 +383,7 @@ ASSERT_EQ(2u, ContentLayerCount()); { const cc::Layer* layer = ContentLayerAt(0); + EXPECT_TRUE(GetTransformNode(layer).transform_changed); Vector<RectWithColor> rects_with_color; rects_with_color.push_back( @@ -391,6 +399,7 @@ } { const cc::Layer* layer = ContentLayerAt(1); + EXPECT_FALSE(GetTransformNode(layer).transform_changed); EXPECT_THAT( layer->GetPicture(), Pointee(DrawsRectangle(FloatRect(0, 0, 100, 100), Color::kGray))); @@ -417,6 +426,7 @@ ASSERT_EQ(2u, ContentLayerCount()); { const cc::Layer* layer = ContentLayerAt(0); + EXPECT_TRUE(GetTransformNode(layer).transform_changed); EXPECT_THAT( layer->GetPicture(), Pointee(DrawsRectangle(FloatRect(0, 0, 300, 200), Color::kWhite))); @@ -426,6 +436,7 @@ } { const cc::Layer* layer = ContentLayerAt(1); + EXPECT_TRUE(GetTransformNode(layer).transform_changed); EXPECT_THAT( layer->GetPicture(), Pointee(DrawsRectangle(FloatRect(0, 0, 300, 200), Color::kBlack))); @@ -4597,4 +4608,155 @@ EXPECT_EQ(cc_effect->clip_id, cc_clip->parent_id); } +TEST_P(PaintArtifactCompositorTest, TransformChange) { + auto t1 = Create2DTranslation(t0(), 10, 20); + TransformPaintPropertyNode::State t2_state{TransformationMatrix().Rotate(45)}; + t2_state.direct_compositing_reasons = CompositingReason::k3DTransform; + auto t2 = TransformPaintPropertyNode::Create(*t1, std::move(t2_state)); + + Update(TestPaintArtifact() + .Chunk(1) + .Properties(*t2, c0(), e0()) + .RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack) + .Build()); + ASSERT_EQ(1u, ContentLayerCount()); + cc::Layer* layer = ContentLayerAt(0); + + // Change t1 but not t2. + layer->ClearSubtreePropertyChangedForTesting(); + t2->ClearChangedToRoot(); + t1->Update(t0(), TransformPaintPropertyNode::State{FloatSize(20, 30)}); + EXPECT_EQ(PaintPropertyChangeType::kChangedOnlySimpleValues, + t1->NodeChanged()); + EXPECT_EQ(PaintPropertyChangeType::kUnchanged, t2->NodeChanged()); + Update(TestPaintArtifact() + .Chunk(1) + .Properties(*t2, c0(), e0()) + .RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack) + .Build()); + + ASSERT_EQ(1u, ContentLayerCount()); + ASSERT_EQ(layer, ContentLayerAt(0)); + // TODO(wangxianzhu): Probably avoid setting this flag on transform change. + EXPECT_TRUE(layer->subtree_property_changed()); + // This is set by cc when propagating ancestor change flag to descendants. + EXPECT_TRUE(GetTransformNode(layer).transform_changed); + // This is set by PropertyTreeManager. + EXPECT_TRUE(GetPropertyTrees() + .transform_tree.Node(GetTransformNode(layer).parent_id) + ->transform_changed); + + // Change t2 but not t1. + layer->ClearSubtreePropertyChangedForTesting(); + t2->ClearChangedToRoot(); + t2_state.transform_and_origin = TransformationMatrix().Rotate(135); + t2->Update(*t1, std::move(t2_state)); + EXPECT_EQ(PaintPropertyChangeType::kUnchanged, t1->NodeChanged()); + EXPECT_EQ(PaintPropertyChangeType::kChangedOnlySimpleValues, + t2->NodeChanged()); + Update(TestPaintArtifact() + .Chunk(1) + .Properties(*t2, c0(), e0()) + .RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack) + .Build()); + + ASSERT_EQ(1u, ContentLayerCount()); + ASSERT_EQ(layer, ContentLayerAt(0)); + // TODO(wangxianzhu): Probably avoid setting this flag on transform change. + EXPECT_TRUE(layer->subtree_property_changed()); + EXPECT_TRUE(GetTransformNode(layer).transform_changed); + EXPECT_FALSE(GetPropertyTrees() + .transform_tree.Node(GetTransformNode(layer).parent_id) + ->transform_changed); + + // Change t2 to be 2d translation which will be decomposited. + layer->ClearSubtreePropertyChangedForTesting(); + t2->ClearChangedToRoot(); + t2_state.transform_and_origin = FloatSize(20, 30); + t2->Update(*t1, std::move(t2_state)); + EXPECT_EQ(PaintPropertyChangeType::kUnchanged, t1->NodeChanged()); + EXPECT_EQ(PaintPropertyChangeType::kChangedOnlyValues, t2->NodeChanged()); + Update(TestPaintArtifact() + .Chunk(1) + .Properties(*t2, c0(), e0()) + .RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack) + .Build()); + + ASSERT_EQ(1u, ContentLayerCount()); + ASSERT_EQ(layer, ContentLayerAt(0)); + // The new transform is decomposited, so there is no transform_changed, but + // we set subtree_property_changed because offset_from_transform_parent + // (calculated from the decomposited transforms) changed. + EXPECT_TRUE(layer->subtree_property_changed()); + EXPECT_FALSE(GetTransformNode(layer).transform_changed); +} + +TEST_P(PaintArtifactCompositorTest, EffectChange) { + auto e1 = CreateOpacityEffect(e0(), t0(), nullptr, 0.5f); + auto e2 = CreateOpacityEffect(*e1, t0(), nullptr, 0.6f, + CompositingReason::kWillChangeOpacity); + + Update(TestPaintArtifact() + .Chunk(1) + .Properties(t0(), c0(), *e2) + .RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack) + .Build()); + ASSERT_EQ(1u, ContentLayerCount()); + cc::Layer* layer = ContentLayerAt(0); + + // Change e1 but not e2. + layer->ClearSubtreePropertyChangedForTesting(); + e2->ClearChangedToRoot(); + + EffectPaintPropertyNode::State e1_state{&t0()}; + e1_state.opacity = 0.8f; + e1_state.compositor_element_id = e1->GetCompositorElementId(); + e1->Update(e0(), std::move(e1_state)); + EXPECT_EQ(PaintPropertyChangeType::kChangedOnlySimpleValues, + e1->NodeChanged()); + EXPECT_EQ(PaintPropertyChangeType::kUnchanged, e2->NodeChanged()); + Update(TestPaintArtifact() + .Chunk(1) + .Properties(t0(), c0(), *e2) + .RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack) + .Build()); + + ASSERT_EQ(1u, ContentLayerCount()); + ASSERT_EQ(layer, ContentLayerAt(0)); + // TODO(wangxianzhu): Probably avoid setting this flag on Effect change. + EXPECT_TRUE(layer->subtree_property_changed()); + // This is set by cc when propagating ancestor change flag to descendants. + EXPECT_TRUE(GetEffectNode(layer).effect_changed); + // This is set by PropertyTreeManager. + EXPECT_TRUE(GetPropertyTrees() + .effect_tree.Node(GetEffectNode(layer).parent_id) + ->effect_changed); + + // Change e2 but not e1. + layer->ClearSubtreePropertyChangedForTesting(); + e2->ClearChangedToRoot(); + EffectPaintPropertyNode::State e2_state{&t0()}; + e2_state.opacity = 0.9f; + e2_state.direct_compositing_reasons = CompositingReason::kWillChangeOpacity; + e2_state.compositor_element_id = e2->GetCompositorElementId(); + e2->Update(*e1, std::move(e2_state)); + EXPECT_EQ(PaintPropertyChangeType::kUnchanged, e1->NodeChanged()); + EXPECT_EQ(PaintPropertyChangeType::kChangedOnlySimpleValues, + e2->NodeChanged()); + Update(TestPaintArtifact() + .Chunk(1) + .Properties(t0(), c0(), *e2) + .RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack) + .Build()); + + ASSERT_EQ(1u, ContentLayerCount()); + ASSERT_EQ(layer, ContentLayerAt(0)); + // TODO(wangxianzhu): Probably avoid setting this flag on Effect change. + EXPECT_TRUE(layer->subtree_property_changed()); + EXPECT_TRUE(GetEffectNode(layer).effect_changed); + EXPECT_FALSE(GetPropertyTrees() + .effect_tree.Node(GetEffectNode(layer).parent_id) + ->effect_changed); +} + } // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc index 674d927..d34a180 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
@@ -106,7 +106,6 @@ origin.Z()); } compositor_node.needs_local_transform_update = true; - compositor_node.transform_changed = true; } static void AdjustPageScaleToUsePostLocal(cc::TransformNode& page_scale) { @@ -118,7 +117,6 @@ page_scale.post_local.matrix() = page_scale.local.matrix(); page_scale.pre_local.matrix().setIdentity(); page_scale.local.matrix().setIdentity(); - page_scale.transform_changed = true; } static void SetTransformTreePageScaleFactor( @@ -178,6 +176,7 @@ property_trees->scroll_tree.SetScrollOffset( scroll_node->GetCompositorElementId(), cc_transform->scroll_offset); + cc_transform->transform_changed = true; property_trees->transform_tree.set_needs_update(true); property_trees->scroll_tree.set_needs_update(true); return true; @@ -202,6 +201,7 @@ // flag, we should clear it to let the compositor respect the new value. cc_transform->is_currently_animating = false; + cc_transform->transform_changed = true; property_trees->transform_tree.set_needs_update(true); return true; } @@ -221,6 +221,7 @@ SetTransformTreePageScaleFactor(&property_trees->transform_tree, cc_transform); + cc_transform->transform_changed = true; property_trees->transform_tree.set_needs_update(true); return true; } @@ -416,6 +417,9 @@ compositor_node.source_node_id = parent_id; UpdateCcTransformLocalMatrix(compositor_node, transform_node); + compositor_node.transform_changed = + transform_node.NodeChanged() >= + PaintPropertyChangeType::kChangedOnlySimpleValues; compositor_node.flattens_inherited_transform = transform_node.FlattensInheritedTransform(); compositor_node.sorting_context_id = transform_node.RenderingContextId(); @@ -1088,6 +1092,8 @@ } effect_node.blend_mode = blend_mode; effect_node.double_sided = !effect.LocalTransformSpace().IsBackfaceHidden(); + effect_node.effect_changed = + effect.NodeChanged() >= PaintPropertyChangeType::kChangedOnlySimpleValues; } } // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h b/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h index 12bb0ff..b75dca0 100644 --- a/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h +++ b/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h
@@ -146,6 +146,8 @@ cc_node_id_ = id; } + PaintPropertyChangeType NodeChanged() const { return changed_; } + #if DCHECK_IS_ON() String ToTreeString() const; @@ -176,7 +178,6 @@ DCHECK(!IsRoot()); changed_ = std::max(changed_, changed); } - PaintPropertyChangeType NodeChanged() const { return changed_; } private: friend class PaintPropertyNodeTest;
diff --git a/third_party/blink/renderer/platform/heap/BUILD.gn b/third_party/blink/renderer/platform/heap/BUILD.gn index 910928f..f270653 100644 --- a/third_party/blink/renderer/platform/heap/BUILD.gn +++ b/third_party/blink/renderer/platform/heap/BUILD.gn
@@ -28,6 +28,8 @@ "blink_gc.h", "blink_gc_memory_dump_provider.cc", "blink_gc_memory_dump_provider.h", + "cancelable_task_scheduler.cc", + "cancelable_task_scheduler.h", "finalizer_traits.h", "garbage_collected.h", "gc_info.cc", @@ -104,6 +106,7 @@ sources = [ "address_cache_test.cc", "blink_gc_memory_dump_provider_test.cc", + "cancelable_task_scheduler_test.cc", "gc_info_test.cc", "heap_compact_test.cc", "heap_stats_collector_test.cc",
diff --git a/third_party/blink/renderer/platform/heap/DEPS b/third_party/blink/renderer/platform/heap/DEPS index 5ed63eb..da681b9 100644 --- a/third_party/blink/renderer/platform/heap/DEPS +++ b/third_party/blink/renderer/platform/heap/DEPS
@@ -10,6 +10,7 @@ "+base/bits.h", "+base/sampling_heap_profiler/poisson_allocation_sampler.h", "+base/synchronization/lock.h", + "+base/task_runner.h", "+third_party/blink/renderer/platform/bindings", "+third_party/blink/renderer/platform/histogram.h", @@ -18,6 +19,7 @@ "+third_party/blink/renderer/platform/platform_export.h", "+third_party/blink/renderer/platform/runtime_enabled_features.h", "+third_party/blink/renderer/platform/scheduler/public", + "+third_party/blink/renderer/platform/scheduler/test", "+third_party/blink/renderer/platform/testing", "+third_party/blink/renderer/platform/web_task_runner.h", "+third_party/blink/renderer/platform/wtf",
diff --git a/third_party/blink/renderer/platform/heap/cancelable_task_scheduler.cc b/third_party/blink/renderer/platform/heap/cancelable_task_scheduler.cc new file mode 100644 index 0000000..e0af134 --- /dev/null +++ b/third_party/blink/renderer/platform/heap/cancelable_task_scheduler.cc
@@ -0,0 +1,134 @@ +// 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/platform/heap/cancelable_task_scheduler.h" + +#include "base/logging.h" +#include "base/macros.h" +#include "base/task_runner.h" +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" +#include "third_party/blink/renderer/platform/wtf/vector.h" + +namespace blink { + +class CancelableTaskScheduler::TaskData { + USING_FAST_MALLOC(TaskData); + DISALLOW_COPY_AND_ASSIGN(TaskData); + + public: + TaskData(Task task, CancelableTaskScheduler* scheduler) + : task_(std::move(task)), scheduler_(scheduler), status_(kWaiting) {} + + ~TaskData() { + // The task runner is responsible for unregistering the task in case the + // task hasn't been cancelled. The first check returns true if the task + // hasn't been executed, the second returns true if it has. + Status previous; + if (TryRun(&previous) || previous == kRunning) { + scheduler_->UnregisterAndSignal(this); + } + } + + void Run() { + if (TryRun()) { + std::move(task_).Run(); + } + } + + bool TryCancel() { + Status expected = kWaiting; + return status_.compare_exchange_strong(expected, kCancelled, + std::memory_order_acq_rel, + std::memory_order_acquire); + } + + private: + // Identifies the state a cancelable task is in: + // |kWaiting|: The task is scheduled and waiting to be executed. {TryRun} will + // succeed. + // |kCancelled|: The task has been cancelled. {TryRun} will fail. + // |kRunning|: The task is currently running and cannot be canceled anymore. + enum Status : uint8_t { kWaiting, kCancelled, kRunning }; + + friend size_t RemoveCancelledTasks(WTF::HashSet<TaskData*>*); + + bool TryRun(Status* previous = nullptr) { + Status expected = kWaiting; + const bool success = status_.compare_exchange_strong( + expected, kRunning, std::memory_order_acq_rel, + std::memory_order_acquire); + if (previous) { + *previous = expected; + } + return success; + } + + Task task_; + CancelableTaskScheduler* const scheduler_; + std::atomic<Status> status_; +}; + +CancelableTaskScheduler::CancelableTaskScheduler( + scoped_refptr<base::TaskRunner> task_runner) + : cond_var_(&lock_), task_runner_(std::move(task_runner)) {} + +CancelableTaskScheduler::~CancelableTaskScheduler() { + base::AutoLock lock(lock_); + CHECK(tasks_.IsEmpty()); +} + +void CancelableTaskScheduler::ScheduleTask(Task task) { + std::unique_ptr<TaskData> task_data = Register(std::move(task)); + task_runner_->PostTask(FROM_HERE, + base::BindOnce(&TaskData::Run, std::move(task_data))); +} + +size_t CancelableTaskScheduler::CancelAndWait() { + size_t result = 0; + base::AutoLock lock(lock_); + while (!tasks_.IsEmpty()) { + result += RemoveCancelledTasks(); + if (!tasks_.IsEmpty()) { + cond_var_.Wait(); + } + } + return result; +} + +std::unique_ptr<CancelableTaskScheduler::TaskData> +CancelableTaskScheduler::Register(Task task) { + base::AutoLock lock(lock_); + auto task_data = std::make_unique<TaskData>(std::move(task), this); + tasks_.insert(task_data.get()); + return task_data; +} + +void CancelableTaskScheduler::UnregisterAndSignal(TaskData* task_data) { + base::AutoLock lock(lock_); + CHECK(tasks_.Contains(task_data)); + tasks_.erase(task_data); + cond_var_.Signal(); +} + +// This function is needed because WTF::HashSet::erase function invalidates +// all iterators. Returns number of removed tasks. +size_t CancelableTaskScheduler::RemoveCancelledTasks() { + WTF::Vector<TaskData*> to_be_removed; + // Assume worst case. + to_be_removed.ReserveCapacity(tasks_.size()); + for (TaskData* task : tasks_) { + if (task->TryCancel()) { + to_be_removed.push_back(task); + } + } + tasks_.RemoveAll(to_be_removed); + return to_be_removed.size(); +} + +size_t CancelableTaskScheduler::NumberOfTasksForTesting() const { + base::AutoLock lock(lock_); + return tasks_.size(); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/cancelable_task_scheduler.h b/third_party/blink/renderer/platform/heap/cancelable_task_scheduler.h new file mode 100644 index 0000000..dacd97d --- /dev/null +++ b/third_party/blink/renderer/platform/heap/cancelable_task_scheduler.h
@@ -0,0 +1,59 @@ +// 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_PLATFORM_HEAP_CANCELABLE_TASK_SCHEDULER_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_CANCELABLE_TASK_SCHEDULER_H_ + +#include <memory> + +#include "base/memory/scoped_refptr.h" +#include "base/synchronization/condition_variable.h" +#include "base/synchronization/lock.h" +#include "third_party/blink/renderer/platform/platform_export.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" +#include "third_party/blink/renderer/platform/wtf/hash_set.h" + +namespace base { +class TaskRunner; +} + +namespace blink { + +// CancelableTaskScheduler allows for scheduling tasks that can be cancelled +// before they are invoked. User is responsible for synchronizing completion of +// tasks and destruction of CancelableTaskScheduler. +class PLATFORM_EXPORT CancelableTaskScheduler final { + public: + using Task = WTF::CrossThreadOnceFunction<void()>; + + explicit CancelableTaskScheduler(scoped_refptr<base::TaskRunner>); + ~CancelableTaskScheduler(); + + // Schedules task to run on TaskRunner. + void ScheduleTask(Task); + // Cancels all not yet started tasks and waits for running ones to complete. + // Returns number of cancelled (not executed) tasks. + size_t CancelAndWait(); + + private: + class TaskData; + template <class T> + friend class CancelableTaskSchedulerTest; + + std::unique_ptr<TaskData> Register(Task); + void UnregisterAndSignal(TaskData*); + + size_t RemoveCancelledTasks(); + + size_t NumberOfTasksForTesting() const; + + WTF::HashSet<TaskData*> tasks_; + mutable base::Lock lock_; + base::ConditionVariable cond_var_; + scoped_refptr<base::TaskRunner> task_runner_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_CANCELABLE_TASK_SCHEDULER_H_
diff --git a/third_party/blink/renderer/platform/heap/cancelable_task_scheduler_test.cc b/third_party/blink/renderer/platform/heap/cancelable_task_scheduler_test.cc new file mode 100644 index 0000000..a7deef5 --- /dev/null +++ b/third_party/blink/renderer/platform/heap/cancelable_task_scheduler_test.cc
@@ -0,0 +1,97 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/platform/heap/cancelable_task_scheduler.h" + +#include <atomic> + +#include "base/memory/scoped_refptr.h" +#include "base/task_runner.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/platform/scheduler/public/worker_pool.h" +#include "third_party/blink/renderer/platform/scheduler/test/fake_task_runner.h" +#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" + +namespace blink { + +class ParallelTaskRunner : public base::TaskRunner { + public: + bool PostDelayedTask(const base::Location& location, + base::OnceClosure task, + base::TimeDelta) override { + worker_pool::PostTask(location, WTF::CrossThreadBindOnce(std::move(task))); + return true; + } + + bool RunsTasksInCurrentSequence() const override { return false; } + + void RunUntilIdle() {} +}; + +template <class Runner> +class CancelableTaskSchedulerTest : public ::testing::Test { + public: + using Task = CancelableTaskScheduler::Task; + + void ScheduleTask(Task callback) { + scheduler_.ScheduleTask(std::move(callback)); + } + + void RunTaskRunner() { task_runner_->RunUntilIdle(); } + size_t CancelAndWait() { return scheduler_.CancelAndWait(); } + + size_t NumberOfRegisteredTasks() const { + return scheduler_.NumberOfTasksForTesting(); + } + + private: + scoped_refptr<Runner> task_runner_ = base::MakeRefCounted<Runner>(); + CancelableTaskScheduler scheduler_{task_runner_}; +}; + +using RunnerTypes = + ::testing::Types<scheduler::FakeTaskRunner, ParallelTaskRunner>; +TYPED_TEST_SUITE(CancelableTaskSchedulerTest, RunnerTypes); + +TYPED_TEST(CancelableTaskSchedulerTest, EmptyCancelTasks) { + const size_t cancelled = this->CancelAndWait(); + EXPECT_EQ(0u, cancelled); + EXPECT_EQ(0u, this->NumberOfRegisteredTasks()); +} + +TYPED_TEST(CancelableTaskSchedulerTest, RunAndCancelTasks) { + static constexpr size_t kNumberOfTasks = 10u; + + const auto callback = [](std::atomic<int>* i) { ++(*i); }; + std::atomic<int> var{0}; + + for (size_t i = 0; i < kNumberOfTasks; ++i) { + this->ScheduleTask( + WTF::CrossThreadBindOnce(callback, WTF::CrossThreadUnretained(&var))); + EXPECT_GE(i + 1, this->NumberOfRegisteredTasks()); + } + + this->RunTaskRunner(); + // Tasks will remove themselves after running + EXPECT_LE(0u, this->NumberOfRegisteredTasks()); + + const size_t cancelled = this->CancelAndWait(); + EXPECT_EQ(0u, this->NumberOfRegisteredTasks()); + EXPECT_EQ(kNumberOfTasks, var + cancelled); +} + +TEST(CancelableTaskSchedulerTest, RemoveTasksFromQueue) { + auto task_runner = base::MakeRefCounted<scheduler::FakeTaskRunner>(); + CancelableTaskScheduler scheduler{task_runner}; + int var = 0; + scheduler.ScheduleTask(WTF::CrossThreadBindOnce( + [](int* var) { ++(*var); }, WTF::CrossThreadUnretained(&var))); + auto tasks = task_runner->TakePendingTasksForTesting(); + // Clearing the task queue should destroy all cancelable closures, which in + // turn will notify CancelableTaskScheduler to remove corresponding tasks. + tasks.clear(); + EXPECT_EQ(0, var); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc index b7009907..5cd19d5 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -263,11 +263,11 @@ return value; } +// This function corresponds with step 2 substep 7 of +// https://fetch.spec.whatwg.org/#main-fetch. void SetReferrer( ResourceRequest& request, const FetchClientSettingsObject& fetch_client_settings_object) { - // TODO(domfarolino): we can probably *just set* the HTTP `Referer` here - // no matter what now. if (!request.DidSetHttpReferrer()) { String referrer_to_use = request.ReferrerString(); network::mojom::ReferrerPolicy referrer_policy_to_use = @@ -276,20 +276,38 @@ if (referrer_to_use == Referrer::ClientReferrerString()) referrer_to_use = fetch_client_settings_object.GetOutgoingReferrer(); - if (referrer_policy_to_use == network::mojom::ReferrerPolicy::kDefault) { + if (referrer_policy_to_use == network::mojom::ReferrerPolicy::kDefault) referrer_policy_to_use = fetch_client_settings_object.GetReferrerPolicy(); - } + request.SetReferrerString( + referrer_to_use, + ResourceRequest::SetReferrerStringLocation::kResourceFetcher); + request.SetReferrerPolicy( + referrer_policy_to_use, + ResourceRequest::SetReferrerPolicyLocation::kResourceFetcher); // TODO(domfarolino): Stop storing ResourceRequest's referrer as a header // and store it elsewhere. See https://crbug.com/850813. - request.SetHttpReferrer(SecurityPolicy::GenerateReferrer( - referrer_policy_to_use, request.Url(), referrer_to_use)); + request.SetHttpReferrer( + SecurityPolicy::GenerateReferrer(referrer_policy_to_use, request.Url(), + referrer_to_use), + ResourceRequest::SetHttpReferrerLocation::kResourceFetcher); } else { - CHECK_EQ( - SecurityPolicy::GenerateReferrer(request.GetReferrerPolicy(), - request.Url(), request.HttpReferrer()) - .referrer, - request.HttpReferrer()); + // In the case of stale requests that are being revalidated, these requests + // will already have their HttpReferrer set, and we will end up here. We + // won't regenerate the referrer, but instead check that it's still correct. + Referrer generated_referrer = SecurityPolicy::GenerateReferrer( + request.GetReferrerPolicy(), request.Url(), request.ReferrerString()); + if (generated_referrer.referrer != request.HttpReferrer()) { + const auto set_http_referrer_location = request.HttpReferrerLocation(); + const auto set_referrer_string_location = + request.ReferrerStringLocation(); + const auto set_referrer_policy_location = + request.ReferrerPolicyLocation(); + base::debug::Alias(&set_http_referrer_location); + base::debug::Alias(&set_referrer_string_location); + base::debug::Alias(&set_referrer_policy_location); + CHECK(false); + } } }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request.cc b/third_party/blink/renderer/platform/loader/fetch/resource_request.cc index 187e0e7..a02cfb3a 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_request.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.cc
@@ -103,7 +103,8 @@ new_referrer.IsEmpty() ? Referrer::NoReferrer() : String(new_referrer); // TODO(domfarolino): Stop storing ResourceRequest's generated referrer as a // header and instead use a separate member. See https://crbug.com/850813. - request->SetHttpReferrer(Referrer(referrer, new_referrer_policy)); + request->SetHttpReferrer(Referrer(referrer, new_referrer_policy), + SetHttpReferrerLocation::kCreateRedirectRequest); request->SetSkipServiceWorker(skip_service_worker); request->SetRedirectStatus(RedirectStatus::kFollowedRedirect); @@ -218,7 +219,10 @@ http_header_fields_.Set(name, value); } -void ResourceRequest::SetHttpReferrer(const Referrer& referrer) { +void ResourceRequest::SetHttpReferrer( + const Referrer& referrer, + SetHttpReferrerLocation set_http_referrer_location) { + set_http_referrer_location_ = set_http_referrer_location; if (referrer.referrer.IsEmpty()) http_header_fields_.Remove(http_names::kReferer); else
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request.h b/third_party/blink/renderer/platform/loader/fetch/resource_request.h index 45814eb..80d73c3 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_request.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.h
@@ -67,6 +67,51 @@ public: enum class RedirectStatus : uint8_t { kFollowedRedirect, kNoRedirect }; + enum class SetHttpReferrerLocation : uint8_t { + kCreateRedirectRequest, + kFrameLoaderResourceRequestForReload, + kFrameLoadRequest, + kInspectorNetworkAgent, + kLocalDomWindow, + kResourceFetcher, + kWebURLRequest, + }; + enum class SetReferrerStringLocation : uint8_t { + kCSSFontFaceSrcValueFetch, + kCSSImageSetValueCacheImage, + kCSSImageValueCacheImage, + kHistoryItem, + kModuleScriptLoader, + kPerformHTTPFetch, + kPingLoader, + kPreloadRequestStart, + kResourceFetcher, + kThreadableLoaderCreateAccessControlPreflightRequest, + kThreadableLoaderPrepareCrossOriginRequest, + kWebLocalFrameImpl, + }; + enum class SetReferrerPolicyLocation : uint8_t { + kAnchorElement, + kCSSFontFaceSrcValueFetch, + kCSSImageSetValueCacheImage, + kCSSImageValueCacheImage, + kFrameOwnerLoadOrRedirectSubframe, + kHistoryItem, + kImageLoader, + kLinkImport, + kLoadStylesheet, + kModuleLoader, + kPerformHTTPFetch, + kPingLoader, + kPrefetchIfNeeded, + kPreloadIfNeeded, + kPreloadRequestStart, + kResourceFetcher, + kSFOCreateFetchParameters, + kThreadableLoaderCreateAccessControlPreflightRequest, + kThreadableLoaderPrepareCrossOriginRequest, + kWebLocalFrameImpl, + }; ResourceRequest(); explicit ResourceRequest(const String& url_string); @@ -151,21 +196,36 @@ const AtomicString& HttpReferrer() const { return HttpHeaderField(http_names::kReferer); } - void SetHttpReferrer(const Referrer&); + SetHttpReferrerLocation HttpReferrerLocation() const { + return set_http_referrer_location_; + } + void SetHttpReferrer(const Referrer&, SetHttpReferrerLocation); bool DidSetHttpReferrer() const { return did_set_http_referrer_; } void ClearHTTPReferrer(); - void SetReferrerPolicy(network::mojom::ReferrerPolicy referrer_policy) { + void SetReferrerPolicy( + network::mojom::ReferrerPolicy referrer_policy, + SetReferrerPolicyLocation set_referrer_policy_location) { referrer_policy_ = referrer_policy; + set_referrer_policy_location_ = set_referrer_policy_location; } network::mojom::ReferrerPolicy GetReferrerPolicy() const { return referrer_policy_; } + SetReferrerPolicyLocation ReferrerPolicyLocation() const { + return set_referrer_policy_location_; + } - void SetReferrerString(const String& referrer_string) { + void SetReferrerString( + const String& referrer_string, + SetReferrerStringLocation set_referrer_string_location) { referrer_string_ = referrer_string; + set_referrer_string_location_ = set_referrer_string_location; } const String& ReferrerString() const { return referrer_string_; } + SetReferrerStringLocation ReferrerStringLocation() const { + return set_referrer_string_location_; + } const AtomicString& HttpOrigin() const { return HttpHeaderField(http_names::kOrigin); @@ -497,6 +557,11 @@ bool is_external_request_; network::mojom::CorsPreflightPolicy cors_preflight_policy_; RedirectStatus redirect_status_; + // TODO(domfarolino): Remove these after crash debugging is complete. + SetHttpReferrerLocation set_http_referrer_location_; + SetReferrerStringLocation set_referrer_string_location_; + SetReferrerPolicyLocation set_referrer_policy_location_; + base::Optional<String> suggested_filename_; mutable CacheControlHeader cache_control_header_cache_;
diff --git a/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.cc b/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.cc index f5aebce..ae486e1 100644 --- a/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.cc +++ b/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.cc
@@ -55,7 +55,9 @@ params.MutableResourceRequest().SetFetchImportanceMode(importance_); // its referrer policy to options's referrer policy. [spec text] - params.MutableResourceRequest().SetReferrerPolicy(referrer_policy_); + params.MutableResourceRequest().SetReferrerPolicy( + referrer_policy_, + ResourceRequest::SetReferrerPolicyLocation::kSFOCreateFetchParameters); params.SetCharset(encoding);
diff --git a/third_party/blink/renderer/platform/weborigin/security_policy.cc b/third_party/blink/renderer/platform/weborigin/security_policy.cc index f8122bf..28062e71 100644 --- a/third_party/blink/renderer/platform/weborigin/security_policy.cc +++ b/third_party/blink/renderer/platform/weborigin/security_policy.cc
@@ -68,6 +68,20 @@ return safelist; } +network::mojom::ReferrerPolicy ReferrerPolicyResolveDefault( + network::mojom::ReferrerPolicy referrer_policy) { + if (referrer_policy == network::mojom::ReferrerPolicy::kDefault) { + if (RuntimeEnabledFeatures::ReducedReferrerGranularityEnabled()) { + return network::mojom::ReferrerPolicy:: + kNoReferrerWhenDowngradeOriginWhenCrossOrigin; + } else { + return network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade; + } + } + + return referrer_policy; +} + void SecurityPolicy::Init() { TrustworthyOriginSafelist(); } @@ -93,16 +107,8 @@ network::mojom::ReferrerPolicy referrer_policy, const KURL& url, const String& referrer) { - network::mojom::ReferrerPolicy referrer_policy_no_default = referrer_policy; - if (referrer_policy_no_default == network::mojom::ReferrerPolicy::kDefault) { - if (RuntimeEnabledFeatures::ReducedReferrerGranularityEnabled()) { - referrer_policy_no_default = network::mojom::ReferrerPolicy:: - kNoReferrerWhenDowngradeOriginWhenCrossOrigin; - } else { - referrer_policy_no_default = - network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade; - } - } + network::mojom::ReferrerPolicy referrer_policy_no_default = + ReferrerPolicyResolveDefault(referrer_policy); if (referrer == Referrer::NoReferrer()) return Referrer(Referrer::NoReferrer(), referrer_policy_no_default); DCHECK(!referrer.IsEmpty());
diff --git a/third_party/blink/renderer/platform/weborigin/security_policy.h b/third_party/blink/renderer/platform/weborigin/security_policy.h index d041d1d9..cb4e4bd 100644 --- a/third_party/blink/renderer/platform/weborigin/security_policy.h +++ b/third_party/blink/renderer/platform/weborigin/security_policy.h
@@ -46,6 +46,14 @@ kDoNotSupportReferrerPolicyLegacyKeywords, }; +// The ReferrerPolicy enum contains a member kDefault, which not a real referrer +// policy, but instead a value Blink uses to fallback to +// kNoReferrerWhenDowngrade at certain times. The function below is provided so +// that a referrer policy which may be kDefault can be resolved to a valid +// value. +PLATFORM_EXPORT network::mojom::ReferrerPolicy ReferrerPolicyResolveDefault( + network::mojom::ReferrerPolicy); + class PLATFORM_EXPORT SecurityPolicy { STATIC_ONLY(SecurityPolicy);
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-blink-features=LayoutNG b/third_party/blink/web_tests/FlagExpectations/disable-blink-features=LayoutNG index b042f560..0ab2b6b 100644 --- a/third_party/blink/web_tests/FlagExpectations/disable-blink-features=LayoutNG +++ b/third_party/blink/web_tests/FlagExpectations/disable-blink-features=LayoutNG
@@ -285,3 +285,5 @@ ### virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/ crbug.com/591099 virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/registration-updateviacache.https.html [ Failure ] + +crbug.com/591099 external/wpt/css/css-tables/absolute-tables-002.html [ Failure ]
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests index 42431dc..b3187e0 100644 --- a/third_party/blink/web_tests/NeverFixTests +++ b/third_party/blink/web_tests/NeverFixTests
@@ -2253,6 +2253,7 @@ # We don't plan to support this use-case in the near future. crbug.com/940797 external/wpt/signed-exchange/appcache/sxg-served-from-appcache.tentative.https.html [ WontFix ] crbug.com/940797 virtual/sxg-with-network-service/external/wpt/signed-exchange/appcache/sxg-served-from-appcache.tentative.https.html [ WontFix ] +crbug.com/940797 virtual/sxg-subresource/external/wpt/signed-exchange/appcache/sxg-served-from-appcache.tentative.https.html [ WontFix ] external/wpt/css/css-overscroll-behavior/overscrollBehavior-manual.html [ WontFix ] external/wpt/html/semantics/forms/the-input-element/event-select-manual.html [ WontFix ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index fada6727..b14a2ae 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -551,6 +551,11 @@ "args": ["--enable-features=NetworkService"] }, { + "prefix": "sxg-subresource", + "base": "external/wpt/signed-exchange", + "args": ["--enable-features=SignedExchangeSubresourcePrefetch"] + }, + { "prefix": "omt-worker-fetch", "base": "external/wpt/content-security-policy/inside-worker", "args": ["--enable-features=OffMainThreadDedicatedWorkerScriptFetch,PlzDedicatedWorker,OffMainThreadServiceWorkerScriptFetch,OffMainThreadSharedWorkerScriptFetch"]
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 3a9fb448..048dc368 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
@@ -113645,6 +113645,18 @@ {} ] ], + "html/semantics/embedded-content/the-iframe-element/iframe-modify-scrolling-attr-to-yes.html": [ + [ + "html/semantics/embedded-content/the-iframe-element/iframe-modify-scrolling-attr-to-yes.html", + [ + [ + "/html/semantics/embedded-content/the-iframe-element/iframe-modify-scrolling-attr-to-yes-ref.html", + "==" + ] + ], + {} + ] + ], "html/semantics/embedded-content/the-iframe-element/iframe-with-base.html": [ [ "html/semantics/embedded-content/the-iframe-element/iframe-with-base.html", @@ -140099,6 +140111,12 @@ "css/css-tables/OWNERS": [ [] ], + "css/css-tables/absolute-tables-003-expected.txt": [ + [] + ], + "css/css-tables/absolute-tables-005-expected.txt": [ + [] + ], "css/css-tables/anonymous-table-ws-001-ref.html": [ [] ], @@ -142283,9 +142301,6 @@ "css/css-transforms/matrix/reference/svg-matrix-four-color-ref.html": [ [] ], - "css/css-transforms/parsing/scale-parsing-valid-expected.txt": [ - [] - ], "css/css-transforms/parsing/transform-box-valid-expected.txt": [ [] ], @@ -157823,6 +157838,9 @@ "html/semantics/embedded-content/the-iframe-element/iframe-load-event-expected.txt": [ [] ], + "html/semantics/embedded-content/the-iframe-element/iframe-modify-scrolling-attr-to-yes-ref.html": [ + [] + ], "html/semantics/embedded-content/the-iframe-element/iframe-with-base-ref.html": [ [] ], @@ -157889,6 +157907,9 @@ "html/semantics/embedded-content/the-iframe-element/support/iframe-trying-to-navigate-itself.html": [ [] ], + "html/semantics/embedded-content/the-iframe-element/support/iframe-which-content-height-equals-400px.html": [ + [] + ], "html/semantics/embedded-content/the-iframe-element/support/iframe_sandbox_001.htm": [ [] ], @@ -165236,6 +165257,9 @@ "resources/webidl2/lib/webidl2.js": [ [] ], + "resources/webidl2/lib/webidl2.js.headers": [ + [] + ], "screen-capture/META.yml": [ [] ], @@ -198412,6 +198436,18 @@ {} ] ], + "css/css-animations/responsive/column-rule-color-001.html": [ + [ + "css/css-animations/responsive/column-rule-color-001.html", + {} + ] + ], + "css/css-animations/responsive/column-width-001.html": [ + [ + "css/css-animations/responsive/column-width-001.html", + {} + ] + ], "css/css-animations/style-animation-parsing.html": [ [ "css/css-animations/style-animation-parsing.html", @@ -205870,6 +205906,36 @@ {} ] ], + "css/css-tables/absolute-tables-001.html": [ + [ + "css/css-tables/absolute-tables-001.html", + {} + ] + ], + "css/css-tables/absolute-tables-002.html": [ + [ + "css/css-tables/absolute-tables-002.html", + {} + ] + ], + "css/css-tables/absolute-tables-003.html": [ + [ + "css/css-tables/absolute-tables-003.html", + {} + ] + ], + "css/css-tables/absolute-tables-004.html": [ + [ + "css/css-tables/absolute-tables-004.html", + {} + ] + ], + "css/css-tables/absolute-tables-005.html": [ + [ + "css/css-tables/absolute-tables-005.html", + {} + ] + ], "css/css-tables/border-spacing-included-in-sizes-001.html": [ [ "css/css-tables/border-spacing-included-in-sizes-001.html", @@ -217749,6 +217815,12 @@ {} ] ], + "element-timing/retrievability.html": [ + [ + "element-timing/retrievability.html", + {} + ] + ], "element-timing/supported-element-type.html": [ [ "element-timing/supported-element-type.html", @@ -340185,6 +340257,14 @@ "fb74d7fa7d062d60153d47913df9eb2b0c7267c8", "testharness" ], + "css/css-animations/responsive/column-rule-color-001.html": [ + "9953db43545990d9f6e0941ee89f10dc83e46438", + "testharness" + ], + "css/css-animations/responsive/column-width-001.html": [ + "7697eec324064dd6bd1fd75f16fdff5d3050315d", + "testharness" + ], "css/css-animations/style-animation-parsing.html": [ "792fda33ed8b0bacf355e62066ec05d54cc5c729", "testharness" @@ -370769,6 +370849,34 @@ "1cc9d5b6637083e2dcb65280083edb82e4aea251", "support" ], + "css/css-tables/absolute-tables-001.html": [ + "dd401c237907bb9166df85e290bd3d7980644a93", + "testharness" + ], + "css/css-tables/absolute-tables-002.html": [ + "a72e2f170e36d5b9dcf37b631e0357f82b13e333", + "testharness" + ], + "css/css-tables/absolute-tables-003-expected.txt": [ + "f1b3b491d2f32de0d7ef044ed951266ef87c563c", + "support" + ], + "css/css-tables/absolute-tables-003.html": [ + "352d8cd6270c3c731aad09a3e8a62b5583a23b9c", + "testharness" + ], + "css/css-tables/absolute-tables-004.html": [ + "a74d7dfbd02f2675ede3754e90f912399df2a2f7", + "testharness" + ], + "css/css-tables/absolute-tables-005-expected.txt": [ + "9ceaa9a0684c2c12d7ca931785b1e82b850c9da4", + "support" + ], + "css/css-tables/absolute-tables-005.html": [ + "57c3f0dea3a56f0281a44e6be019c3ecc9866937", + "testharness" + ], "css/css-tables/anonymous-table-cell-margin-collapsing.html": [ "23b467ebacc983122a632f4d5971c8daca569420", "reftest" @@ -379745,12 +379853,8 @@ "1072d1d6b1ecc46142ffbdd2ad62b87079651672", "testharness" ], - "css/css-transforms/parsing/scale-parsing-valid-expected.txt": [ - "acffcc24da2b3553daf280ae7070603d22d4c0f0", - "support" - ], "css/css-transforms/parsing/scale-parsing-valid.html": [ - "b9afbc848a3b5ff3033d070b4f080245e0d822c5", + "2ae12222f1361b6b0016ce235fad92d03b3bff45", "testharness" ], "css/css-transforms/parsing/transform-box-invalid.html": [ @@ -410173,6 +410277,10 @@ "4d51ac4b4633f0a24155f331ee63035e62b6dbe1", "support" ], + "element-timing/retrievability.html": [ + "3ac04d8278512ae9b35913c215ffd4ace97a9f8b", + "testharness" + ], "element-timing/supported-element-type.html": [ "15733d46f95c9079acfec06cdd25f70ca0e056a6", "testharness" @@ -412442,7 +412550,7 @@ "support" ], "event-timing/retrievability.html": [ - "3a762e7aa79f2a1d95ad9f916d67e25f94378101", + "cdb47c6a50480087b92a35ce86c621e28f23d8a7", "testharness" ], "event-timing/retrieve-firstInput.html": [ @@ -429085,6 +429193,14 @@ "d245bf0b96451b3419e0e69bda86fe4859c9cbfe", "testharness" ], + "html/semantics/embedded-content/the-iframe-element/iframe-modify-scrolling-attr-to-yes-ref.html": [ + "3758ea2cab4096beccb3722a1cc534b71c662a64", + "support" + ], + "html/semantics/embedded-content/the-iframe-element/iframe-modify-scrolling-attr-to-yes.html": [ + "9d85aa543d2d1732b8534fcdfa62a42d11716586", + "reftest" + ], "html/semantics/embedded-content/the-iframe-element/iframe-nosrc.html": [ "57189a0b884d3a55e4bb2ba1a1d3aa83066c0eb3", "testharness" @@ -429445,6 +429561,10 @@ "6755d295aa179992b4cf958ee2ad8456e729677c", "support" ], + "html/semantics/embedded-content/the-iframe-element/support/iframe-which-content-height-equals-400px.html": [ + "bb3dbd31182e91f43c3caa0cb8bb7ffbad485177", + "support" + ], "html/semantics/embedded-content/the-iframe-element/support/iframe_sandbox_001.htm": [ "051ca5ecd78a17f499d3df76b0bd8f1b6a9dbade", "support" @@ -438706,7 +438826,7 @@ "testharness" ], "layout-instability/buffer-layout-shift.html": [ - "c55f1e88d4cd7084322813102bfe82dc1d14c7a7", + "216cafd45de0785b27a0ca7fa009352de7887e23", "testharness" ], "layout-instability/observe-layout-shift.html": [ @@ -462837,6 +462957,10 @@ "d909c30ff07eda519f969a22a0bae6836550c2d8", "support" ], + "resources/webidl2/lib/webidl2.js.headers": [ + "6805c323df5a975231648b830e33ce183c3cbbd3", + "support" + ], "screen-capture/META.yml": [ "47882d3275f1cc928555045b2def8fc90f6bcdb0", "support" @@ -477930,7 +478054,7 @@ "support" ], "web-animations/animation-model/animation-types/accumulation-per-property-expected.txt": [ - "0bebfffddc249cb8e7b275b6af1273693e62ac7d", + "9e2090927c86d149fbfa25aa4ed30a0ac14d125a", "support" ], "web-animations/animation-model/animation-types/accumulation-per-property.html": [ @@ -477938,7 +478062,7 @@ "testharness" ], "web-animations/animation-model/animation-types/addition-per-property-expected.txt": [ - "4f01f2596e52492b186ab100033c2a7839afc23b", + "260c457085f23f4a14491349dbddb58d8878a8b3", "support" ], "web-animations/animation-model/animation-types/addition-per-property.html": [ @@ -477950,7 +478074,7 @@ "testharness" ], "web-animations/animation-model/animation-types/interpolation-per-property-expected.txt": [ - "286b089e58ddfadc3b66379ec1b059f2ac05aee5", + "c611fb484228cdc280bc1e24e5b47aa2b81b54c2", "support" ], "web-animations/animation-model/animation-types/interpolation-per-property.html": [ @@ -479150,7 +479274,7 @@ "testharness" ], "webaudio/the-audio-api/the-audioparam-interface/automation-rate-testing.js": [ - "73892dd845887d731779b3794a14df3f6bd36cba", + "43279f91d68d3c5e2d7a086c739c838b31dc7335", "support" ], "webaudio/the-audio-api/the-audioparam-interface/automation-rate.html": [ @@ -479182,7 +479306,7 @@ "testharness" ], "webaudio/the-audio-api/the-audioparam-interface/k-rate-oscillator.html": [ - "1672f0d975f2b2e2fd0c127663b403745b669265", + "6803f55eab00bbfb9766cc044a7240e6b4a0fda0", "testharness" ], "webaudio/the-audio-api/the-audioparam-interface/k-rate-panner.html": [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-tables/absolute-tables-001.html b/third_party/blink/web_tests/external/wpt/css/css-tables/absolute-tables-001.html new file mode 100644 index 0000000..dd401c2 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-tables/absolute-tables-001.html
@@ -0,0 +1,90 @@ +<!doctype html> +<script src='/resources/testharness.js'></script> +<script src='/resources/testharnessreport.js'></script> +<script src='/resources/check-layout-th.js'></script> +<link rel="author" title="Anders Ruud" href="mailto:andruud@chromium.org"> +<link rel="author" title="David Grogan" href="mailto:dgrogan@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/CSS22/visudet.html#the-width-property" title="See Note in <percentage>"> +<meta name="flags" content="" /> +<meta name="assert" content="percent lengths of an abspos table are resolved against the padding box of the parent" /> +<style> + main div { + position: relative; + border: 5px solid black; + height: 60px; + width: 60px; + padding: 5px 7px 11px 13px; + margin: 10px; + } + + .tbl { + display: table; + background-color: skyblue; + position: absolute; + width: 50%; + height: 50%; + } + + .cell { + display: table-cell; + outline: 1px dashed blue; + } + + .topleft { left: 0; top: 0; } + .topright { right: 0; top: 0; } + .bottomright { right: 0; bottom: 0; } + .bottomleft { left: 0; bottom: 0; } + + .vertical { writing-mode: vertical-lr; } + +</style> +<p>Tests that percent lengths of an absolutely positioned table is resolved +against the <em>padding box</em> of the parent. +<hr> +<output id="log"></output> +<main> +<div> + <span class="tbl topleft" data-expected-client-width=40 data-expected-client-height=38 data-offset-x=0 data-offset-y=0> + <span class="cell" data-expected-client-width=40 data-expected-client-height=38>abc</span> + </span> +</div> +<div> + <span class="tbl topright" data-expected-client-width=40 data-expected-client-height=38 data-offset-x=40 data-offset-y=0> + <span class="cell" data-expected-client-width=40 data-expected-client-height=38>abc</span> + </span> +</div> +<div> + <span class="tbl bottomright" data-expected-client-width=40 data-expected-client-height=38 data-offset-x=40 data-offset-y=38> + <span class="cell" data-expected-client-width=40 data-expected-client-height=38>abc</span> + </span> +</div> +<div> + <span class="tbl bottomleft" data-expected-client-width=40 data-expected-client-height=38 data-offset-x=0 data-offset-y=38> + <span class="cell" data-expected-client-width=40 data-expected-client-height=38>abc</span> + </span> +</div> + +<div class="vertical"> + <span class="tbl topleft" data-expected-client-width=40 data-expected-client-height=38 data-offset-x=0 data-offset-y=0> + <span class="cell" data-expected-client-width=40 data-expected-client-height=38>abc</span> + </span> +</div> +<div class="vertical"> + <span class="tbl topright" data-expected-client-width=40 data-expected-client-height=38 data-offset-x=40 data-offset-y=0> + <span class="cell" data-expected-client-width=40 data-expected-client-height=38>abc</span> + </span> +</div> +<div class="vertical"> + <span class="tbl bottomright" data-expected-client-width=40 data-expected-client-height=38 data-offset-x=40 data-offset-y=38> + <span class="cell" data-expected-client-width=40 data-expected-client-height=38>abc</span> + </span> +</div> +<div class="vertical"> + <span class="tbl bottomleft" data-expected-client-width=40 data-expected-client-height=38 data-offset-x=0 data-offset-y=38> + <span class="cell" data-expected-client-width=40 data-expected-client-height=38>abc</span> + </span> +</div> +</main> +<script> + checkLayout(".tbl"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-tables/absolute-tables-002.html b/third_party/blink/web_tests/external/wpt/css/css-tables/absolute-tables-002.html new file mode 100644 index 0000000..a72e2f17 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-tables/absolute-tables-002.html
@@ -0,0 +1,79 @@ +<!doctype html> +<script src='/resources/testharness.js'></script> +<script src='/resources/testharnessreport.js'></script> +<script src='/resources/check-layout-th.js'></script> +<link rel="author" title="David Grogan" href="mailto:dgrogan@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-tables-3/#used-width-of-table"> +<meta name="flags" content="" /> +<meta name="assert" content="When sizing and positioning abspos tables, the intrinsic width is obeyed when the intrinsic width is larger than specified width" /> +<style> +.cb { + position: relative; + height: 200px; + width: 200px; + outline: 2px dashed lightblue; +} + +.table { + background-color: orange; + position: absolute; + width: 50px; + right: 0px; +} + +.cell { + border: 1px solid green; + width: 100px; +} + +.cell > div { + width: 200px; +} + +.vertical { writing-mode: vertical-lr; } +.horizontal { writing-mode: horizontal-tb; } +</style> + +<output id="log"></output> + +<main> +<div class="cb"> + <table class="table" data-expected-width=208 data-offset-x="-8"> + <tr> + <td class="cell"> + <div></div> + </td> + </tr> + </table> +</div> +<div class="cb vertical"> + <table class="table horizontal" data-expected-width=208 data-offset-x="-8"> + <tr> + <td class="cell"> + <div></div> + </td> + </tr> + </table> +</div> +<div class="cb"> + <table class="table vertical" data-expected-width=208 data-offset-x="-8"> + <tr> + <td class="cell"> + <div></div> + </td> + </tr> + </table> +</div> +<div class="cb vertical"> + <table class="table vertical" data-expected-width=208 data-offset-x="-8"> + <tr> + <td class="cell"> + <div></div> + </td> + </tr> + </table> +</div> +</main> +<script> + checkLayout(".table"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-tables/absolute-tables-003-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-tables/absolute-tables-003-expected.txt new file mode 100644 index 0000000..f1b3b49 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-tables/absolute-tables-003-expected.txt
@@ -0,0 +1,23 @@ +This is a testharness.js-based test. +PASS .table 1 +PASS .table 2 +FAIL .table 3 assert_equals: +<table class="table vertical" data-expected-width="50" data-offset-x="150"> + <tbody><tr> + <td class="cell" data-expected-width="46"> + <div></div> + </td> + </tr> + </tbody></table> +width expected 50 but got 108 +FAIL .table 4 assert_equals: +<table class="table vertical" data-expected-width="50" data-offset-x="150"> + <tbody><tr> + <td class="cell" data-expected-width="46"> + <div></div> + </td> + </tr> + </tbody></table> +width expected 50 but got 108 +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/css/css-tables/absolute-tables-003.html b/third_party/blink/web_tests/external/wpt/css/css-tables/absolute-tables-003.html new file mode 100644 index 0000000..352d8cd62 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-tables/absolute-tables-003.html
@@ -0,0 +1,79 @@ +<!doctype html> +<script src='/resources/testharness.js'></script> +<script src='/resources/testharnessreport.js'></script> +<script src='/resources/check-layout-th.js'></script> +<link rel="author" title="David Grogan" href="mailto:dgrogan@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-tables-3/#used-width-of-table"> +<meta name="flags" content="" /> +<meta name="assert" content="When sizing and positioning abspos tables, the specified width is obeyed when the intrinsic width is smaller" /> +<style> +.cb { + position: relative; + height: 200px; + width: 200px; + outline: 2px dashed lightblue; +} + +.table { + background-color: orange; + position: absolute; + width: 50px; + right: 0px; +} + +.cell { + border: 1px solid green; + width: 100px; +} + +.cell > div { + width: 20px; +} + +.vertical { writing-mode: vertical-lr; } +.horizontal { writing-mode: horizontal-tb; } +</style> + +<output id="log"></output> + +<main> +<div class="cb"> + <table class="table" data-expected-width=50 data-offset-x="150"> + <tr> + <td class="cell" data-expected-width=46> + <div></div> + </td> + </tr> + </table> +</div> +<div class="cb vertical"> + <table class="table horizontal" data-expected-width=50 data-offset-x="150"> + <tr> + <td class="cell" data-expected-width=46> + <div></div> + </td> + </tr> + </table> +</div> +<div class="cb"> + <table class="table vertical" data-expected-width=50 data-offset-x="150"> + <tr> + <td class="cell" data-expected-width=46> + <div></div> + </td> + </tr> + </table> +</div> +<div class="cb vertical"> + <table class="table vertical" data-expected-width=50 data-offset-x="150"> + <tr> + <td class="cell" data-expected-width=46> + <div></div> + </td> + </tr> + </table> +</div> +</main> +<script> + checkLayout(".table"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-tables/absolute-tables-004.html b/third_party/blink/web_tests/external/wpt/css/css-tables/absolute-tables-004.html new file mode 100644 index 0000000..a74d7df --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-tables/absolute-tables-004.html
@@ -0,0 +1,79 @@ +<!doctype html> +<script src='/resources/testharness.js'></script> +<script src='/resources/testharnessreport.js'></script> +<script src='/resources/check-layout-th.js'></script> +<link rel="author" title="David Grogan" href="mailto:dgrogan@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-tables-3/#computing-the-table-height"> +<meta name="flags" content="" /> +<meta name="assert" content="When sizing and positioning abspos tables, the intrinsic height is obeyed when the intrinsic height is larger than specified height" /> +<style> +.cb { + position: relative; + height: 200px; + width: 200px; + outline: 2px dashed lightblue; +} + +.table { + background-color: orange; + position: absolute; + height: 50px; + right: 0px; +} + +.cell { + border: 1px solid green; + height: 100px; +} + +.cell > div { + height: 200px; +} + +.vertical { writing-mode: vertical-lr; } +.horizontal { writing-mode: horizontal-tb; } +</style> + +<output id="log"></output> + +<main> +<div class="cb"> + <table class="table" data-expected-width=8 data-expected-height=208 data-offset-x="192"> + <tr> + <td class="cell"> + <div></div> + </td> + </tr> + </table> +</div> +<div class="cb vertical"> + <table class="table horizontal" data-expected-width=8 data-expected-height=208 data-offset-x="192"> + <tr> + <td class="cell"> + <div></div> + </td> + </tr> + </table> +</div> +<div class="cb"> + <table class="table vertical" data-expected-width=8 data-expected-height=208 data-offset-x="192"> + <tr> + <td class="cell"> + <div></div> + </td> + </tr> + </table> +</div> +<div class="cb vertical"> + <table class="table vertical" data-expected-width=8 data-expected-height=208 data-offset-x="192"> + <tr> + <td class="cell"> + <div></div> + </td> + </tr> + </table> +</div> +</main> +<script> + checkLayout(".table"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-tables/absolute-tables-005-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-tables/absolute-tables-005-expected.txt new file mode 100644 index 0000000..9ceaa9a0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-tables/absolute-tables-005-expected.txt
@@ -0,0 +1,23 @@ +This is a testharness.js-based test. +PASS .table 1 +PASS .table 2 +FAIL .table 3 assert_equals: +<table class="table vertical" data-expected-width="8" data-expected-height="108" data-offset-x="192"> + <tbody><tr> + <td class="cell"> + <div></div> + </td> + </tr> + </tbody></table> +height expected 108 but got 50 +FAIL .table 4 assert_equals: +<table class="table vertical" data-expected-width="8" data-expected-height="108" data-offset-x="192"> + <tbody><tr> + <td class="cell"> + <div></div> + </td> + </tr> + </tbody></table> +height expected 108 but got 50 +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/css/css-tables/absolute-tables-005.html b/third_party/blink/web_tests/external/wpt/css/css-tables/absolute-tables-005.html new file mode 100644 index 0000000..57c3f0de --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-tables/absolute-tables-005.html
@@ -0,0 +1,79 @@ +<!doctype html> +<script src='/resources/testharness.js'></script> +<script src='/resources/testharnessreport.js'></script> +<script src='/resources/check-layout-th.js'></script> +<link rel="author" title="David Grogan" href="mailto:dgrogan@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-tables-3/#computing-the-table-height"> +<meta name="flags" content="" /> +<meta name="assert" content="When sizing and positioning abspos tables, the specified height is obeyed when the intrinsic height is smaller" /> +<style> +.cb { + position: relative; + height: 200px; + width: 200px; + outline: 2px dashed lightblue; +} + +.table { + background-color: orange; + position: absolute; + height: 50px; + right: 0px; +} + +.cell { + border: 1px solid green; + height: 100px; +} + +.cell > div { + height: 20px; +} + +.vertical { writing-mode: vertical-lr; } +.horizontal { writing-mode: horizontal-tb; } +</style> + +<output id="log"></output> + +<main> +<div class="cb"> + <table class="table" data-expected-width=8 data-expected-height=108 data-offset-x="192"> + <tr> + <td class="cell"> + <div></div> + </td> + </tr> + </table> +</div> +<div class="cb vertical"> + <table class="table horizontal" data-expected-width=8 data-expected-height=108 data-offset-x="192"> + <tr> + <td class="cell"> + <div></div> + </td> + </tr> + </table> +</div> +<div class="cb"> + <table class="table vertical" data-expected-width=8 data-expected-height=108 data-offset-x="192"> + <tr> + <td class="cell"> + <div></div> + </td> + </tr> + </table> +</div> +<div class="cb vertical"> + <table class="table vertical" data-expected-width=8 data-expected-height=108 data-offset-x="192"> + <tr> + <td class="cell"> + <div></div> + </td> + </tr> + </table> +</div> +</main> +<script> + checkLayout(".table"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/resources/webidl2/lib/webidl2.js.headers b/third_party/blink/web_tests/external/wpt/resources/webidl2/lib/webidl2.js.headers new file mode 100644 index 0000000..6805c323 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/resources/webidl2/lib/webidl2.js.headers
@@ -0,0 +1 @@ +Content-Type: text/javascript; charset=utf-8
diff --git a/third_party/blink/web_tests/external/wpt/signed-exchange/resources/generate-test-sxgs.sh b/third_party/blink/web_tests/external/wpt/signed-exchange/resources/generate-test-sxgs.sh index 16750f2..81a5e04 100755 --- a/third_party/blink/web_tests/external/wpt/signed-exchange/resources/generate-test-sxgs.sh +++ b/third_party/blink/web_tests/external/wpt/signed-exchange/resources/generate-test-sxgs.sh
@@ -15,7 +15,7 @@ set -e -for cmd in gen-signedexchange gen-certurl; do +for cmd in gen-signedexchange gen-certurl dump-signedexchange; do if ! command -v $cmd > /dev/null 2>&1; then echo "$cmd is not installed. Please run:" echo " go get -u github.com/WICG/webpackage/go/signedexchange/cmd/..." @@ -540,4 +540,40 @@ -o sxg/sxg-data-cert-url.sxg \ -miRecordSize 100 +# Generate the signed exchange file of sxg-subresource-script-inner.js. +gen-signedexchange \ + -version $sxg_version \ + -uri $inner_url_origin/signed-exchange/resources/sxg-subresource-script.js \ + -status 200 \ + -content sxg-subresource-script-inner.js \ + -certificate $certfile \ + -certUrl $cert_url_origin/signed-exchange/resources/$certfile.cbor \ + -validityUrl $inner_url_origin/signed-exchange/resources/resource.validity.msg \ + -privateKey $keyfile \ + -date 2030-04-01T00:00:00Z \ + -expire 168h \ + -o sxg/sxg-subresource-script.sxg \ + -miRecordSize 100 + +# Get the header integrity hash value of sxg-subresource-script.sxg. +header_integrity=$(dump-signedexchange -i sxg/sxg-subresource-script.sxg | \ + grep -o "header integrity: sha256-.*" | \ + grep -o "sha256-.*$") + +# Generate the signed exchange file of signed exchange subresource test. +gen-signedexchange \ + -version $sxg_version \ + -uri $inner_url_origin/signed-exchange/resources/sxg-subresource-sxg.html \ + -status 200 \ + -content sxg-subresource-sxg-inner.html \ + -certificate $certfile \ + -certUrl $cert_url_origin/signed-exchange/resources/$certfile.cbor \ + -validityUrl $inner_url_origin/signed-exchange/resources/resource.validity.msg \ + -privateKey $keyfile \ + -date 2030-04-01T00:00:00Z \ + -expire 168h \ + -o sxg/sxg-subresource.sxg \ + -miRecordSize 100 \ + -responseHeader "link:<$inner_url_origin/signed-exchange/resources/sxg-subresource-script.js>;rel=allowed-alt-sxg;header-integrity=\"$header_integrity\",<$inner_url_origin/signed-exchange/resources/sxg-subresource-script.js>;rel=preload;as=script" + rm -fr $tmpdir
diff --git a/third_party/blink/web_tests/external/wpt/signed-exchange/resources/sxg-subresource-iframe.html b/third_party/blink/web_tests/external/wpt/signed-exchange/resources/sxg-subresource-iframe.html new file mode 100644 index 0000000..bd81285 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/signed-exchange/resources/sxg-subresource-iframe.html
@@ -0,0 +1,29 @@ +<!DOCTYPE html> +<body> +<script> +(async () => { + const sxg_path = 'sxg/sxg-subresource.sxg'; + const scipt_sxg_path = 'sxg/sxg-subresource-script.sxg'; + const scipt_path = 'sxg-subresource-script.js'; + const wait_for_prefetch = new Promise((resolve) => { + new PerformanceObserver((list) => { + for (let e of list.getEntries()) { + if (e.name.endsWith(scipt_sxg_path)) { + resolve(); + } else if (e.name.endsWith(scipt_path)) { + window.parent.postMessage( + scipt_path + ' should not be prefetched', '*'); + } + } + }).observe({ entryTypes: ['resource'] }); + }); + + const link = document.createElement('link'); + link.rel = 'prefetch'; + link.href = sxg_path; + document.body.appendChild(link); + await wait_for_prefetch; + location.href = sxg_path; +})() +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/signed-exchange/resources/sxg-subresource-script-inner.js b/third_party/blink/web_tests/external/wpt/signed-exchange/resources/sxg-subresource-script-inner.js new file mode 100644 index 0000000..dcc7a356 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/signed-exchange/resources/sxg-subresource-script-inner.js
@@ -0,0 +1,4 @@ +// Usually the alternate resource should have the same content as the original +// one (sxg-subresource-script.js), but for now we use differentiated content +// for easy testing. +window.parent.postMessage('from signed exchange', '*');
diff --git a/third_party/blink/web_tests/external/wpt/signed-exchange/resources/sxg-subresource-script.js b/third_party/blink/web_tests/external/wpt/signed-exchange/resources/sxg-subresource-script.js new file mode 100644 index 0000000..c730568f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/signed-exchange/resources/sxg-subresource-script.js
@@ -0,0 +1 @@ +window.parent.postMessage('from server', '*');
diff --git a/third_party/blink/web_tests/external/wpt/signed-exchange/resources/sxg-subresource-sxg-inner.html b/third_party/blink/web_tests/external/wpt/signed-exchange/resources/sxg-subresource-sxg-inner.html new file mode 100644 index 0000000..9dfff56 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/signed-exchange/resources/sxg-subresource-sxg-inner.html
@@ -0,0 +1,2 @@ +<!DOCTYPE html> +<script src="sxg-subresource-script.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/signed-exchange/resources/sxg/sxg-subresource-script.sxg b/third_party/blink/web_tests/external/wpt/signed-exchange/resources/sxg/sxg-subresource-script.sxg new file mode 100644 index 0000000..6a6f37e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/signed-exchange/resources/sxg/sxg-subresource-script.sxg Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/signed-exchange/resources/sxg/sxg-subresource.sxg b/third_party/blink/web_tests/external/wpt/signed-exchange/resources/sxg/sxg-subresource.sxg new file mode 100644 index 0000000..05be42a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/signed-exchange/resources/sxg/sxg-subresource.sxg Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/signed-exchange/resources/sxg/sxg-subresource.sxg.sub.headers b/third_party/blink/web_tests/external/wpt/signed-exchange/resources/sxg/sxg-subresource.sxg.sub.headers new file mode 100644 index 0000000..8bc3938d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/signed-exchange/resources/sxg/sxg-subresource.sxg.sub.headers
@@ -0,0 +1 @@ +Link: <https://{{host}}:{{ports[https][0]}}/signed-exchange/resources/sxg/sxg-subresource-script.sxg>;rel=alternate;type="application/signed-exchange;v=b3";anchor="https://127.0.0.1:8444/signed-exchange/resources/sxg-subresource-script.js";
diff --git a/third_party/blink/web_tests/external/wpt/signed-exchange/subresource/sxg-subresource.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/signed-exchange/subresource/sxg-subresource.tentative-expected.txt new file mode 100644 index 0000000..ee54a8c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/signed-exchange/subresource/sxg-subresource.tentative-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Subresource signed exchange prefetch. assert_equals: expected "from signed exchange" but got "sxg-subresource-script.js should not be prefetched" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/signed-exchange/subresource/sxg-subresource.tentative.html b/third_party/blink/web_tests/external/wpt/signed-exchange/subresource/sxg-subresource.tentative.html new file mode 100644 index 0000000..8ca12b4c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/signed-exchange/subresource/sxg-subresource.tentative.html
@@ -0,0 +1,23 @@ +<!DOCTYPE html> +<title>Subresource signed exchange prefetch.</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script src="../resources/sxg-util.js"></script> +<body> +<script> +promise_test(async (t) => { + const iframe_path = get_host_info().HTTPS_ORIGIN + '/signed-exchange/resources/sxg-subresource-iframe.html'; + const wait_message = (new Promise((resolve) => { + const on_message = (event) => { + window.removeEventListener('message', on_message); + resolve(event.data); + }; + window.addEventListener('message', on_message); + })); + withIframe(iframe_path); + const message = await wait_message; + assert_equals(message, 'from signed exchange'); +}, 'Subresource signed exchange prefetch.'); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioparam-interface/automation-rate-testing.js b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioparam-interface/automation-rate-testing.js index 73892dd..43279f91 100644 --- a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioparam-interface/automation-rate-testing.js +++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioparam-interface/automation-rate-testing.js
@@ -45,7 +45,7 @@ // The promise from |startRendering| is returned. function doTest(context, should, options) { let merger = new ChannelMergerNode( - context, {numberOfInputs: context.destination.numberOfChannels}); + context, {numberOfInputs: context.destination.channelCount}); merger.connect(context.destination); let src = null;
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioparam-interface/k-rate-oscillator.html b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioparam-interface/k-rate-oscillator.html index 1672f0d..6803f55 100644 --- a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioparam-interface/k-rate-oscillator.html +++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioparam-interface/k-rate-oscillator.html
@@ -32,7 +32,7 @@ }); let merger = new ChannelMergerNode( - context, {numberOfInputs: context.numberOfChannels}); + context, {numberOfInputs: context.destination.channelCount}); merger.connect(context.destination); let inverter = new GainNode(context, {gain: -1}); inverter.connect(merger, 0, 2);
diff --git a/third_party/blink/web_tests/fast/table/absolute-table-percent-lengths.html b/third_party/blink/web_tests/fast/table/absolute-table-percent-lengths.html deleted file mode 100644 index 3b54201..0000000 --- a/third_party/blink/web_tests/fast/table/absolute-table-percent-lengths.html +++ /dev/null
@@ -1,48 +0,0 @@ -<!doctype html> -<style> - div { - position: relative; - border: 5px solid black; - height: 60px; - width: 60px; - padding: 20px; - margin: 10px; - } - - .tbl { - display: table; - background-color: skyblue; - position: absolute; - width: 50%; - height: 50%; - } - - .cell { display: table-cell; } - - .topleft { left: 0; top: 0; } - .topright { right: 0; top: 0; } - .bottomright { right: 0; bottom: 0; } - .bottomleft { left: 0; bottom: 0; } - - .vertical { -webkit-writing-mode: vertical-lr; } - -</style> -<script src="../../resources/check-layout.js"></script> -<p>Tests that percent lengths of an absolutely positioned table is resolved -against the <em>padding box</em> of the parent. -<hr> -<output id="output"></output> -<hr> -<div><span class="tbl topleft" data-expected-client-width=50 data-expected-client-height=50><span class="cell">abc</span></span></div> -<div><span class="tbl topright" data-expected-client-width=50 data-expected-client-height=50><span class="cell">abc</span></span></div> -<div><span class="tbl bottomright" data-expected-client-width=50 data-expected-client-height=50><span class="cell">abc</span></span></div> -<div><span class="tbl bottomleft" data-expected-client-width=50 data-expected-client-height=50><span class="cell">abc</span></span></div> - -<div class="vertical"><span class="tbl topleft" data-expected-client-width=50 data-expected-client-height=50><span class="cell">abc</span></span></div> -<div class="vertical"><span class="tbl topright" data-expected-client-width=50 data-expected-client-height=50><span class="cell">abc</span></span></div> -<div class="vertical"><span class="tbl bottomright" data-expected-client-width=50 data-expected-client-height=50><span class="cell">abc</span></span></div> -<div class="vertical"><span class="tbl bottomleft" data-expected-client-width=50 data-expected-client-height=50><span class="cell">abc</span></span></div> - -<script> - checkLayout(".tbl", output); -</script>
diff --git a/third_party/blink/web_tests/http/tests/security/referrer-policy-conflicting-policies-font-face-expected.html b/third_party/blink/web_tests/http/tests/security/referrer-policy-conflicting-policies-font-face-expected.html new file mode 100644 index 0000000..5c68ea1 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/security/referrer-policy-conflicting-policies-font-face-expected.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<style> +@font-face { + font-family: 'Test Font'; + src: url(http://127.0.0.1:8000/security/resources/opensans.woff2) format('woff2'); +} + +body { + font-family: 'Test Font'; +} +</style> +<body> +<p> +Checks that a font face that was created before a referrer policy was set is +loaded with the correct referrer, in this case, without a referrer. +</p> +<p> +The test passes, a normal font will be loaded. +</p> +</body>
diff --git a/third_party/blink/web_tests/http/tests/security/referrer-policy-conflicting-policies-font-face.html b/third_party/blink/web_tests/http/tests/security/referrer-policy-conflicting-policies-font-face.html new file mode 100644 index 0000000..47ef8b1 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/security/referrer-policy-conflicting-policies-font-face.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<script> +if (window.testRunner) + testRunner.waitUntilDone(); + +// For documentation on this test, see +// referrer-policy-conflicting-policies.html. +document.location = "https://127.0.0.1:8443/security/resources/referrer-policy-conflicting-policies-font-face.html"; +</script>
diff --git a/third_party/blink/web_tests/http/tests/security/referrer-policy-conflicting-policies-image-set-expected.html b/third_party/blink/web_tests/http/tests/security/referrer-policy-conflicting-policies-image-set-expected.html new file mode 100644 index 0000000..c42f349 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/security/referrer-policy-conflicting-policies-image-set-expected.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<style> +div { + content: -webkit-image-set(url("http://127.0.0.1:8080/security/resources/green250x50.png") 1x); +} +</style> +<body> +<p> +Checks that a CSS image that was created from an image-set before a referrer +policy was set is loaded with the correct referrer, in this case, without a +referrer. +</p> +<p> +The test passes, if a green rectangle is displayed below. +</p> +<div></div> +</body>
diff --git a/third_party/blink/web_tests/http/tests/security/referrer-policy-conflicting-policies-image-set.html b/third_party/blink/web_tests/http/tests/security/referrer-policy-conflicting-policies-image-set.html new file mode 100644 index 0000000..e0a896a --- /dev/null +++ b/third_party/blink/web_tests/http/tests/security/referrer-policy-conflicting-policies-image-set.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<script> +if (window.testRunner) + testRunner.waitUntilDone(); + +// For documentation on this test, see +// referrer-policy-conflicting-policies.html. +document.location = "https://127.0.0.1:8443/security/resources/referrer-policy-conflicting-policies-image-set.html"; +</script>
diff --git a/third_party/blink/web_tests/http/tests/security/referrer-policy-conflicting-policies.html b/third_party/blink/web_tests/http/tests/security/referrer-policy-conflicting-policies.html index 380d564..25407a3d 100644 --- a/third_party/blink/web_tests/http/tests/security/referrer-policy-conflicting-policies.html +++ b/third_party/blink/web_tests/http/tests/security/referrer-policy-conflicting-policies.html
@@ -2,5 +2,14 @@ <script> if (window.testRunner) testRunner.waitUntilDone(); + +// The following test works by loading a page over HTTPS, which requests a +// resource over HTTP when the document has the default referrer policy +// (interpreted as no-referrer-when-downgrade). After the request is +// prepared/made, the document's referrer policy is set to 'origin'. The test +// asserts that the referrer associated with the request when the document's +// referrer policy was no-referrer-when-downgrade is empty, and not the origin. +// This test is similar to +// referrer-policy-conflicting-policies-{font-face,image-set}.html document.location = "https://127.0.0.1:8443/security/resources/referrer-policy-conflicting-policies.html"; </script>
diff --git a/third_party/blink/web_tests/http/tests/security/resources/montez.woff2 b/third_party/blink/web_tests/http/tests/security/resources/montez.woff2 new file mode 100644 index 0000000..b2f3be6 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/security/resources/montez.woff2 Binary files differ
diff --git a/third_party/blink/web_tests/http/tests/security/resources/normal-font-if-no-referrer.php b/third_party/blink/web_tests/http/tests/security/resources/normal-font-if-no-referrer.php new file mode 100644 index 0000000..9461235 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/security/resources/normal-font-if-no-referrer.php
@@ -0,0 +1,10 @@ +<?php +header("Content-Type: font/woff2"); +header("Access-Control-Allow-Origin: *"); +if ($_SERVER['HTTP_REFERER'] != '') { + $font = 'montez.woff2'; +} else { + $font = 'opensans.woff2'; +} +echo file_get_contents($font); +?>
diff --git a/third_party/blink/web_tests/http/tests/security/resources/opensans.woff2 b/third_party/blink/web_tests/http/tests/security/resources/opensans.woff2 new file mode 100644 index 0000000..e9f58b7 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/security/resources/opensans.woff2 Binary files differ
diff --git a/third_party/blink/web_tests/http/tests/security/resources/referrer-policy-conflicting-policies-font-face.html b/third_party/blink/web_tests/http/tests/security/resources/referrer-policy-conflicting-policies-font-face.html new file mode 100644 index 0000000..551dcd3 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/security/resources/referrer-policy-conflicting-policies-font-face.html
@@ -0,0 +1,28 @@ +<!DOCTYPE html> +<script> +function done() +{ + if (window.testRunner) + testRunner.notifyDone(); +} +</script> +<style> +@font-face { + font-family: 'Test Font'; + src: url("http://127.0.0.1:8080/security/resources/normal-font-if-no-referrer.php") format('woff2'); +} + +body { + font-family: 'Test Font'; +} +</style> +<meta name="referrer" content="origin"> +<body onload="done();"> +<p> +Checks that a font face that was created before a referrer policy was set is +loaded with the correct referrer, in this case, without a referrer. +</p> +<p> +The test passes, a normal font will be loaded. +</p> +</body>
diff --git a/third_party/blink/web_tests/http/tests/security/resources/referrer-policy-conflicting-policies-image-set.html b/third_party/blink/web_tests/http/tests/security/resources/referrer-policy-conflicting-policies-image-set.html new file mode 100644 index 0000000..1750b22 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/security/resources/referrer-policy-conflicting-policies-image-set.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<script> +function done() +{ + if (window.testRunner) + testRunner.notifyDone(); +} +</script> +<style> +div { + content: -webkit-image-set(url("http://127.0.0.1:8080/security/resources/green-if-no-referrer.php") 1x); +} +</style> +<meta name="referrer" content="origin"> +<body onload="done();"> +<p> +Checks that a CSS image that was created from an image-set before a referrer +policy was set is loaded with the correct referrer, in this case, without a +referrer. +</p> +<p> +The test passes, if a green rectangle is displayed below. +</p> +<div></div> +</body>
diff --git a/third_party/blink/web_tests/http/tests/security/resources/referrer-policy-conflicting-policies.html b/third_party/blink/web_tests/http/tests/security/resources/referrer-policy-conflicting-policies.html index 535cd46..3a38380 100644 --- a/third_party/blink/web_tests/http/tests/security/resources/referrer-policy-conflicting-policies.html +++ b/third_party/blink/web_tests/http/tests/security/resources/referrer-policy-conflicting-policies.html
@@ -11,7 +11,7 @@ content: url("http://127.0.0.1:8080/security/resources/green-if-no-referrer.php"); } </style> -<meta name="referrer" content="origin" /> +<meta name="referrer" content="origin"> <body onload="done();"> <p> Checks that an CSS image that was created before a referrer policy was set is
diff --git a/third_party/blink/web_tests/virtual/sxg-subresource/external/wpt/signed-exchange/README.txt b/third_party/blink/web_tests/virtual/sxg-subresource/external/wpt/signed-exchange/README.txt new file mode 100644 index 0000000..d01256d --- /dev/null +++ b/third_party/blink/web_tests/virtual/sxg-subresource/external/wpt/signed-exchange/README.txt
@@ -0,0 +1 @@ +This directory is for testing the SignedExchangeSubresourcePrefetch feature.
diff --git a/third_party/blink/web_tests/virtual/sxg-subresource/external/wpt/signed-exchange/subresource/sxg-subresource.tentative-expected.txt b/third_party/blink/web_tests/virtual/sxg-subresource/external/wpt/signed-exchange/subresource/sxg-subresource.tentative-expected.txt new file mode 100644 index 0000000..943287c --- /dev/null +++ b/third_party/blink/web_tests/virtual/sxg-subresource/external/wpt/signed-exchange/subresource/sxg-subresource.tentative-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +PASS Subresource signed exchange prefetch. +Harness: the test ran to completion. +
diff --git a/tools/grit/grit/format/policy_templates_json_unittest.py b/tools/grit/grit/format/policy_templates_json_unittest.py index d3816ad30..94b6028 100755 --- a/tools/grit/grit/format/policy_templates_json_unittest.py +++ b/tools/grit/grit/format/policy_templates_json_unittest.py
@@ -123,7 +123,7 @@ grd_string_io = StringIO.StringIO(grd_text) # Parse the grit tree and load the policies' JSON with a gatherer. - grd = grd_reader.Parse(grd_string_io, dir=tmp_dir_name) + grd = grd_reader.Parse(grd_string_io, dir=tmp_dir_name, defines={'_google_chrome': True}) grd.SetOutputLanguage('en') grd.RunGatherers()
diff --git a/tools/grit/grit/gather/policy_json.py b/tools/grit/grit/gather/policy_json.py index 6e67212..825e713 100644 --- a/tools/grit/grit/gather/policy_json.py +++ b/tools/grit/grit/gather/policy_json.py
@@ -57,9 +57,15 @@ if example_text == []: # In such cases the original text is okay for an example. example_text = text + + replacedText = self.Escape(''.join(text).strip()) + replacedText = replacedText.replace('$1', self._config['app_name']) + replacedText = replacedText.replace('$2', self._config['os_name']) + replacedText = replacedText.replace('$3', self._config['frame_name']) + msg.AppendPlaceholder(tclib.Placeholder( placeholder.attributes['name'].value, - self.Escape(''.join(text).strip()), + replacedText, ''.join(example_text).strip())) def _ParseMessage(self, string, desc): @@ -293,3 +299,21 @@ def Escape(self, text): return json.dumps(text, ensure_ascii=False)[1:-1] + + def SetDefines(self, defines): + if '_chromium' in defines: + self._config = { + 'build': 'chromium', + 'app_name': 'Chromium', + 'frame_name': 'Chromium Frame', + 'os_name': 'Chromium OS', + } + elif '_google_chrome' in defines: + self._config = { + 'build': 'chrome', + 'app_name': 'Google Chrome', + 'frame_name': 'Google Chrome Frame', + 'os_name': 'Google Chrome OS', + } + else: + raise Exception('Unknown build')
diff --git a/tools/grit/grit/gather/policy_json_unittest.py b/tools/grit/grit/gather/policy_json_unittest.py index 187dac1..5fb3b5c 100755 --- a/tools/grit/grit/gather/policy_json_unittest.py +++ b/tools/grit/grit/gather/policy_json_unittest.py
@@ -272,20 +272,23 @@ "messages": {} }""" gatherer = policy_json.PolicyJson(StringIO.StringIO(original)) + gatherer.SetDefines({'_google_chrome': True}) gatherer.Parse() self.failUnless(len(gatherer.GetCliques()) == 1) - expected = json.loads(re.sub('<ph.*ph>', '$1', original)) + expected = json.loads(re.sub('<ph.*ph>', 'Google Chrome', original)) + result = json.loads(gatherer.Translate('en')) self.failUnless(expected == json.loads(gatherer.Translate('en'))) self.failUnless(gatherer.GetCliques()[0].translateable) msg = gatherer.GetCliques()[0].GetMessage() self.failUnless(len(msg.GetPlaceholders()) == 1) ph = msg.GetPlaceholders()[0] - self.failUnless(ph.GetOriginal() == '$1') + self.failUnless(ph.GetOriginal() == 'Google Chrome') self.failUnless(ph.GetPresentation() == 'PRODUCT_NAME') self.failUnless(ph.GetExample() == 'Google Chrome') def testGetDescription(self): gatherer = policy_json.PolicyJson({}) + gatherer.SetDefines({'_google_chrome': True}) self.assertEquals( gatherer._GetDescription({'name': 'Policy1'}, 'policy', None, 'desc'), 'Description of the policy named Policy1')
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 53b461c..698bd69 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -724,6 +724,7 @@ 'gpu-try-linux-nvidia-dbg': 'gpu_tests_debug_trybot', 'layout_test_leak_detection': 'release_trybot', 'leak_detection_linux': 'release_trybot', + 'linux-annotator-rel': 'release_trybot', 'linux-blink-heap-concurrent-marking-tsan-rel': 'release_trybot_tsan', 'linux-blink-heap-verification-try': 'release_trybot_enable_blink_heap_verification', 'linux-coverage-rel': 'gpu_tests_release_trybot_no_symbols_use_dummy_lastchange_code_coverage',
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 4e20ad0..1f13161 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -93382,7 +93382,7 @@ </histogram> <histogram name="PasswordManager.MediationOptional" - enum="CredentialManagerGetResult" expires_after="M77"> + enum="CredentialManagerGetResult" expires_after="M87"> <owner>jdoerrie@chromium.org</owner> <owner>vasilii@chromium.org</owner> <summary> @@ -93392,7 +93392,7 @@ </histogram> <histogram name="PasswordManager.MediationRequired" - enum="CredentialManagerGetResult" expires_after="M77"> + enum="CredentialManagerGetResult" expires_after="M87"> <owner>jdoerrie@chromium.org</owner> <owner>vasilii@chromium.org</owner> <summary> @@ -93403,7 +93403,7 @@ </histogram> <histogram name="PasswordManager.MediationSilent" - enum="CredentialManagerGetResult" expires_after="M77"> + enum="CredentialManagerGetResult" expires_after="M87"> <owner>jdoerrie@chromium.org</owner> <owner>vasilii@chromium.org</owner> <summary>
diff --git a/ui/accessibility/ax_tree.cc b/ui/accessibility/ax_tree.cc index abe0282..5949559 100644 --- a/ui/accessibility/ax_tree.cc +++ b/ui/accessibility/ax_tree.cc
@@ -149,6 +149,8 @@ // reparented if they are in this list and removed from somewhere else. std::set<int> potentially_reparented_ids; + std::unordered_set<int> node_data_changed_ids; + // Keeps track of new nodes created during this update. std::set<const AXNode*> new_nodes; @@ -528,12 +530,23 @@ changes.push_back(AXTreeObserver::Change(node, change)); } + // Update the unignored cached values as necessary. for (int parent_id : update_state.invalidate_unignored_cached_values_ids) { AXNode* parent = GetFromId(parent_id); if (parent) parent->UpdateUnignoredCachedValues(); } + // Now that the unignored cached values are up to date, update observers to + // node changes. + for (int node_data_changed_id : update_state.node_data_changed_ids) { + AXNode* node = GetFromId(node_data_changed_id); + if (node) { + for (AXTreeObserver& observer : observers_) + observer.OnNodeChanged(this, node); + } + } + // Tree is no longer updating. SetTreeUpdateInProgressState(false); @@ -681,8 +694,7 @@ node->SetData(src); } - for (AXTreeObserver& observer : observers_) - observer.OnNodeChanged(this, node); + update_state->node_data_changed_ids.insert(node->id()); // First, delete nodes that used to be children of this node but aren't // anymore.
diff --git a/ui/base/ime/chromeos/component_extension_ime_manager.cc b/ui/base/ime/chromeos/component_extension_ime_manager.cc index 44d53e8..b327e5f3 100644 --- a/ui/base/ime/chromeos/component_extension_ime_manager.cc +++ b/ui/base/ime/chromeos/component_extension_ime_manager.cc
@@ -42,51 +42,44 @@ } // namespace -ComponentExtensionEngine::ComponentExtensionEngine() { -} +ComponentExtensionEngine::ComponentExtensionEngine() = default; ComponentExtensionEngine::ComponentExtensionEngine( const ComponentExtensionEngine& other) = default; -ComponentExtensionEngine::~ComponentExtensionEngine() { -} +ComponentExtensionEngine::~ComponentExtensionEngine() = default; -ComponentExtensionIME::ComponentExtensionIME() { -} +ComponentExtensionIME::ComponentExtensionIME() = default; ComponentExtensionIME::ComponentExtensionIME( const ComponentExtensionIME& other) = default; -ComponentExtensionIME::~ComponentExtensionIME() { -} +ComponentExtensionIME::~ComponentExtensionIME() = default; -ComponentExtensionIMEManagerDelegate::ComponentExtensionIMEManagerDelegate() { -} +ComponentExtensionIMEManagerDelegate::ComponentExtensionIMEManagerDelegate() = + default; -ComponentExtensionIMEManagerDelegate::~ComponentExtensionIMEManagerDelegate() { -} +ComponentExtensionIMEManagerDelegate::~ComponentExtensionIMEManagerDelegate() = + default; ComponentExtensionIMEManager::ComponentExtensionIMEManager() { - for (size_t i = 0; i < base::size(input_method::kInputMethods); ++i) { - if (input_method::kInputMethods[i].is_login_keyboard) - login_layout_set_.insert(input_method::kInputMethods[i].xkb_layout_id); + for (const auto& input_method : input_method::kInputMethods) { + if (input_method.is_login_keyboard) + login_layout_set_.insert(input_method.xkb_layout_id); } } -ComponentExtensionIMEManager::~ComponentExtensionIMEManager() { -} +ComponentExtensionIMEManager::~ComponentExtensionIMEManager() = default; void ComponentExtensionIMEManager::Initialize( std::unique_ptr<ComponentExtensionIMEManagerDelegate> delegate) { delegate_ = std::move(delegate); std::vector<ComponentExtensionIME> ext_list = delegate_->ListIME(); - for (size_t i = 0; i < ext_list.size(); ++i) { - ComponentExtensionIME& ext = ext_list[i]; + for (const auto& ext : ext_list) { bool extension_exists = IsWhitelistedExtension(ext.id); if (!extension_exists) component_extension_imes_[ext.id] = ext; - for (size_t j = 0; j < ext.engines.size(); ++j) { - ComponentExtensionEngine& ime = ext.engines[j]; + for (const auto& ime : ext.engines) { const std::string input_method_id = extension_ime_util::GetComponentInputMethodID(ext.id, ime.engine_id); if (extension_exists && !IsWhitelisted(input_method_id)) @@ -165,9 +158,9 @@ input_method::InputMethodDescriptors result; const input_method::InputMethodDescriptors& descriptors = GetAllIMEAsInputMethodDescriptor(); - for (size_t i = 0; i < descriptors.size(); ++i) { - if (extension_ime_util::IsKeyboardLayoutExtension(descriptors[i].id())) - result.push_back(descriptors[i]); + for (const auto& descriptor : descriptors) { + if (extension_ime_util::IsKeyboardLayoutExtension(descriptor.id())) + result.push_back(descriptor); } return result; } @@ -180,8 +173,7 @@ std::string extension_id = extension_ime_util::GetExtensionIDFromInputMethodID(input_method_id); - std::map<std::string, ComponentExtensionIME>::iterator it = - component_extension_imes_.find(extension_id); + auto it = component_extension_imes_.find(extension_id); if (it == component_extension_imes_.end()) return false; @@ -192,8 +184,8 @@ bool ComponentExtensionIMEManager::IsInLoginLayoutWhitelist( const std::vector<std::string>& layouts) { - for (size_t i = 0; i < layouts.size(); ++i) { - if (login_layout_set_.find(layouts[i]) != login_layout_set_.end()) + for (const auto& layout : layouts) { + if (login_layout_set_.find(layout) != login_layout_set_.end()) return true; } return false;
diff --git a/ui/base/ime/chromeos/fake_ime_keyboard.cc b/ui/base/ime/chromeos/fake_ime_keyboard.cc index cc2d29e..fd70580 100644 --- a/ui/base/ime/chromeos/fake_ime_keyboard.cc +++ b/ui/base/ime/chromeos/fake_ime_keyboard.cc
@@ -12,8 +12,7 @@ auto_repeat_is_enabled_(false) { } -FakeImeKeyboard::~FakeImeKeyboard() { -} +FakeImeKeyboard::~FakeImeKeyboard() = default; bool FakeImeKeyboard::SetCurrentKeyboardLayoutByName( const std::string& layout_name) {
diff --git a/ui/base/ime/chromeos/fake_input_method_delegate.cc b/ui/base/ime/chromeos/fake_input_method_delegate.cc index 12f0566b..4c16afbc5 100644 --- a/ui/base/ime/chromeos/fake_input_method_delegate.cc +++ b/ui/base/ime/chromeos/fake_input_method_delegate.cc
@@ -11,8 +11,7 @@ : active_locale_("en") { } -FakeInputMethodDelegate::~FakeInputMethodDelegate() { -} +FakeInputMethodDelegate::~FakeInputMethodDelegate() = default; std::string FakeInputMethodDelegate::GetHardwareKeyboardLayouts() const { return hardware_keyboard_layout_;
diff --git a/ui/base/ime/chromeos/ime_keyboard.cc b/ui/base/ime/chromeos/ime_keyboard.cc index f028f39..975b468 100644 --- a/ui/base/ime/chromeos/ime_keyboard.cc +++ b/ui/base/ime/chromeos/ime_keyboard.cc
@@ -64,8 +64,7 @@ : caps_lock_is_enabled_(false) { } -ImeKeyboard::~ImeKeyboard() { -} +ImeKeyboard::~ImeKeyboard() = default; void ImeKeyboard::AddObserver(Observer* observer) { observers_.AddObserver(observer); @@ -96,16 +95,16 @@ } bool ImeKeyboard::IsISOLevel5ShiftAvailable() const { - for (size_t i = 0; i < base::size(kISOLevel5ShiftLayoutIds); ++i) { - if (last_layout_ == kISOLevel5ShiftLayoutIds[i]) + for (const auto* id : kISOLevel5ShiftLayoutIds) { + if (last_layout_ == id) return true; } return false; } bool ImeKeyboard::IsAltGrAvailable() const { - for (size_t i = 0; i < base::size(kAltGrLayoutIds); ++i) { - if (last_layout_ == kAltGrLayoutIds[i]) + for (const auto* id : kAltGrLayoutIds) { + if (last_layout_ == id) return true; } return false;
diff --git a/ui/base/ime/chromeos/ime_keymap.cc b/ui/base/ime/chromeos/ime_keymap.cc index c639df8..016fe6a 100644 --- a/ui/base/ime/chromeos/ime_keymap.cc +++ b/ui/base/ime/chromeos/ime_keymap.cc
@@ -160,21 +160,19 @@ class KeyCodeMap { public: KeyCodeMap() { - for (size_t i = 0; i < base::size(kKeyCodeTable); ++i) { - map_dom_key_[kKeyCodeTable[i].dom_code] = kKeyCodeTable[i].keyboard_code; - map_key_dom_[kKeyCodeTable[i].keyboard_code] = kKeyCodeTable[i].dom_code; + for (const auto& key_code : kKeyCodeTable) { + map_dom_key_[key_code.dom_code] = key_code.keyboard_code; + map_key_dom_[key_code.keyboard_code] = key_code.dom_code; } } KeyboardCode GetKeyboardCode(const std::string& dom_code) const { - std::map<std::string, KeyboardCode>::const_iterator it = - map_dom_key_.find(dom_code); + auto it = map_dom_key_.find(dom_code); return (it == map_dom_key_.end()) ? VKEY_UNKNOWN : it->second; } std::string GetDomKeycode(KeyboardCode key_code) const { - std::map<KeyboardCode, std::string>::const_iterator it = - map_key_dom_.find(key_code); + auto it = map_key_dom_.find(key_code); return (it == map_key_dom_.end()) ? "" : it->second; }
diff --git a/ui/base/ime/chromeos/input_method_chromeos.cc b/ui/base/ime/chromeos/input_method_chromeos.cc index b0de01f..ec5b5da 100644 --- a/ui/base/ime/chromeos/input_method_chromeos.cc +++ b/ui/base/ime/chromeos/input_method_chromeos.cc
@@ -674,7 +674,7 @@ } while (char_iterator.Advance()); // The text length in Unicode characters. - uint32_t char_length = static_cast<uint32_t>(char16_offsets.size()); + auto char_length = static_cast<uint32_t>(char16_offsets.size()); // Make sure we can convert the value of |char_length| as well. char16_offsets.push_back(length); @@ -685,16 +685,16 @@ const ImeTextSpans text_ime_text_spans = text.ime_text_spans; if (!text_ime_text_spans.empty()) { - for (size_t i = 0; i < text_ime_text_spans.size(); ++i) { - const uint32_t start = text_ime_text_spans[i].start_offset; - const uint32_t end = text_ime_text_spans[i].end_offset; + for (const auto& text_ime_text_span : text_ime_text_spans) { + const uint32_t start = text_ime_text_span.start_offset; + const uint32_t end = text_ime_text_span.end_offset; if (start >= end) continue; ImeTextSpan ime_text_span(ui::ImeTextSpan::Type::kComposition, char16_offsets[start], char16_offsets[end], - text_ime_text_spans[i].thickness, - text_ime_text_spans[i].background_color); - ime_text_span.underline_color = text_ime_text_spans[i].underline_color; + text_ime_text_span.thickness, + text_ime_text_span.background_color); + ime_text_span.underline_color = text_ime_text_span.underline_color; out_composition->ime_text_spans.push_back(ime_text_span); } }
diff --git a/ui/base/ime/chromeos/input_method_chromeos_unittest.cc b/ui/base/ime/chromeos/input_method_chromeos_unittest.cc index d9f9e96..2573439 100644 --- a/ui/base/ime/chromeos/input_method_chromeos_unittest.cc +++ b/ui/base/ime/chromeos/input_method_chromeos_unittest.cc
@@ -173,7 +173,7 @@ bool is_jp_ime() const { return is_jp_ime_; } protected: - ~TestState() override {} + ~TestState() override = default; private: bool is_jp_kbd_ = false; @@ -217,7 +217,7 @@ ResetFlags(); } - ~InputMethodChromeOSTest() override {} + ~InputMethodChromeOSTest() override = default; void SetUp() override { IMEBridge::Initialize(); @@ -243,10 +243,10 @@ void TearDown() override { if (ime_.get()) - ime_->SetFocusedTextInputClient(NULL); + ime_->SetFocusedTextInputClient(nullptr); ime_.reset(); - IMEBridge::Get()->SetCurrentEngineHandler(NULL); - IMEBridge::Get()->SetCandidateWindowHandler(NULL); + IMEBridge::Get()->SetCurrentEngineHandler(nullptr); + IMEBridge::Get()->SetCandidateWindowHandler(nullptr); mock_ime_engine_handler_.reset(); mock_ime_candidate_window_handler_.reset(); IMEBridge::Shutdown(); @@ -385,13 +385,13 @@ TEST_F(InputMethodChromeOSTest, GetTextInputClient) { EXPECT_EQ(this, ime_->GetTextInputClient()); - ime_->SetFocusedTextInputClient(NULL); - EXPECT_EQ(NULL, ime_->GetTextInputClient()); + ime_->SetFocusedTextInputClient(nullptr); + EXPECT_EQ(nullptr, ime_->GetTextInputClient()); } TEST_F(InputMethodChromeOSTest, GetInputTextType_WithoutFocusedClient) { EXPECT_EQ(TEXT_INPUT_TYPE_NONE, ime_->GetTextInputType()); - ime_->SetFocusedTextInputClient(NULL); + ime_->SetFocusedTextInputClient(nullptr); input_type_ = TEXT_INPUT_TYPE_PASSWORD; ime_->OnTextInputTypeChanged(this); // The OnTextInputTypeChanged() call above should be ignored since |this| is @@ -501,7 +501,7 @@ mock_ime_engine_handler_->last_text_input_context().mode); // Confirm that FocusOut is called when set focus to NULL client. - ime_->SetFocusedTextInputClient(NULL); + ime_->SetFocusedTextInputClient(nullptr); EXPECT_EQ(3, mock_ime_engine_handler_->focus_in_call_count()); EXPECT_EQ(3, mock_ime_engine_handler_->focus_out_call_count()); // Confirm that FocusIn is called when set focus to this client. @@ -900,8 +900,8 @@ class InputMethodChromeOSKeyEventTest : public InputMethodChromeOSTest { public: - InputMethodChromeOSKeyEventTest() {} - ~InputMethodChromeOSKeyEventTest() override {} + InputMethodChromeOSKeyEventTest() = default; + ~InputMethodChromeOSKeyEventTest() override = default; DISALLOW_COPY_AND_ASSIGN(InputMethodChromeOSKeyEventTest); };
diff --git a/ui/base/ime/chromeos/input_method_delegate.h b/ui/base/ime/chromeos/input_method_delegate.h index 47aa251..e66c686 100644 --- a/ui/base/ime/chromeos/input_method_delegate.h +++ b/ui/base/ime/chromeos/input_method_delegate.h
@@ -16,8 +16,8 @@ // Provides access to read/persist Input Method-related properties. class InputMethodDelegate { public: - InputMethodDelegate() {} - virtual ~InputMethodDelegate() {} + InputMethodDelegate() = default; + virtual ~InputMethodDelegate() = default; // Returns original VPD value. virtual std::string GetHardwareKeyboardLayouts() const = 0;
diff --git a/ui/base/ime/chromeos/input_method_descriptor.cc b/ui/base/ime/chromeos/input_method_descriptor.cc index 67f9a3c..769bd4e 100644 --- a/ui/base/ime/chromeos/input_method_descriptor.cc +++ b/ui/base/ime/chromeos/input_method_descriptor.cc
@@ -60,11 +60,9 @@ return indicator_; } -InputMethodDescriptor::InputMethodDescriptor() { -} +InputMethodDescriptor::InputMethodDescriptor() = default; -InputMethodDescriptor::~InputMethodDescriptor() { -} +InputMethodDescriptor::~InputMethodDescriptor() = default; } // namespace input_method } // namespace chromeos
diff --git a/ui/base/ime/chromeos/input_method_manager.cc b/ui/base/ime/chromeos/input_method_manager.cc index 87fd7796..b5592bb 100644 --- a/ui/base/ime/chromeos/input_method_manager.cc +++ b/ui/base/ime/chromeos/input_method_manager.cc
@@ -10,17 +10,16 @@ namespace input_method { namespace { -InputMethodManager* g_input_method_manager = NULL; +InputMethodManager* g_input_method_manager = nullptr; } -InputMethodManager::State::~State() { -} +InputMethodManager::State::~State() = default; -InputMethodManager::MenuItem::MenuItem() {} +InputMethodManager::MenuItem::MenuItem() = default; InputMethodManager::MenuItem::MenuItem(const MenuItem& other) = default; -InputMethodManager::MenuItem::~MenuItem() {} +InputMethodManager::MenuItem::~MenuItem() = default; // static InputMethodManager* InputMethodManager::Get() { @@ -38,7 +37,7 @@ DCHECK(g_input_method_manager) << "InputMethodManager() is not initialized."; delete g_input_method_manager; - g_input_method_manager = NULL; + g_input_method_manager = nullptr; } } // namespace input_method
diff --git a/ui/base/ime/chromeos/input_method_manager.h b/ui/base/ime/chromeos/input_method_manager.h index 2df18043..dc1ca0c 100644 --- a/ui/base/ime/chromeos/input_method_manager.h +++ b/ui/base/ime/chromeos/input_method_manager.h
@@ -77,7 +77,7 @@ class Observer { public: - virtual ~Observer() {} + virtual ~Observer() = default; // Called when the current input method is changed. |show_message| // indicates whether the user should be notified of this change. virtual void InputMethodChanged(InputMethodManager* manager, @@ -105,7 +105,7 @@ // keyboard is used, since it controls its own candidate window. class CandidateWindowObserver { public: - virtual ~CandidateWindowObserver() {} + virtual ~CandidateWindowObserver() = default; // Called when the candidate window is opened. virtual void CandidateWindowOpened(InputMethodManager* manager) = 0; // Called when the candidate window is closed. @@ -116,7 +116,7 @@ // bar. class ImeMenuObserver { public: - virtual ~ImeMenuObserver() {} + virtual ~ImeMenuObserver() = default; // Called when the IME menu is activated or deactivated. virtual void ImeMenuActivationChanged(bool is_active) = 0; @@ -257,7 +257,7 @@ virtual ~State(); }; - virtual ~InputMethodManager() {} + virtual ~InputMethodManager() = default; // Gets the global instance of InputMethodManager. Initialize() must be called // first.
diff --git a/ui/base/ime/chromeos/input_method_util.cc b/ui/base/ime/chromeos/input_method_util.cc index a1c4b94f4..aebb9f06 100644 --- a/ui/base/ime/chromeos/input_method_util.cc +++ b/ui/base/ime/chromeos/input_method_util.cc
@@ -51,8 +51,6 @@ { chromeos::extension_ime_util::kBrailleImeEngineId, IDS_LANGUAGES_MEDIUM_LEN_NAME_BRAILLE }, }; -const size_t kMappingImeIdToMediumLenNameResourceIdLen = - base::size(kMappingImeIdToMediumLenNameResourceId); // Due to asynchronous initialization of component extension manager, // GetFirstLoginInputMethodIds may miss component extension IMEs. To enable @@ -388,8 +386,7 @@ // static data, avoiding this up-front cost. std::vector<EnglishToIDMap::value_type> map_storage; map_storage.reserve(kEnglishToResourceIdArraySize); - for (size_t i = 0; i < kEnglishToResourceIdArraySize; ++i) { - const EnglishToResouceId& map_entry = kEnglishToResourceIdArray[i]; + for (const auto& map_entry : kEnglishToResourceIdArray) { map_storage.emplace_back(map_entry.english_string_from_ibus, map_entry.resource_id); } @@ -400,7 +397,7 @@ << "Duplicate string is found"; } -InputMethodUtil::~InputMethodUtil() {} +InputMethodUtil::~InputMethodUtil() = default; std::string InputMethodUtil::GetLocalizedDisplayName( const InputMethodDescriptor& descriptor) const { @@ -454,7 +451,7 @@ const std::string& input_method_id) const { // We can't check the component extension is whilelisted or not here because // it might not be initialized. - return GetInputMethodDescriptorFromId(input_method_id) != NULL || + return GetInputMethodDescriptorFromId(input_method_id) != nullptr || extension_ime_util::IsComponentExtensionIME(input_method_id) || extension_ime_util::IsArcIME(input_method_id); } @@ -468,8 +465,7 @@ std::string InputMethodUtil::GetKeyboardLayoutName( const std::string& input_method_id) const { - InputMethodIdToDescriptorMap::const_iterator iter - = id_to_descriptor_.find(input_method_id); + auto iter = id_to_descriptor_.find(input_method_id); return (iter == id_to_descriptor_.end()) ? "" : iter->second.GetPreferredKeyboardLayout(); } @@ -501,12 +497,10 @@ // For the "Your input method has changed to..." bubble. In most cases // it uses the same name as the short name, unless found in a table // for medium length names. - for (size_t i = 0; i < kMappingImeIdToMediumLenNameResourceIdLen; ++i) { - if (extension_ime_util::GetInputMethodIDByEngineID( - kMappingImeIdToMediumLenNameResourceId[i].engine_id) == + for (const auto& i : kMappingImeIdToMediumLenNameResourceId) { + if (extension_ime_util::GetInputMethodIDByEngineID(i.engine_id) == input_method.id()) { - return delegate_->GetLocalizedString( - kMappingImeIdToMediumLenNameResourceId[i].resource_id); + return delegate_->GetLocalizedString(i.resource_id); } } return GetInputMethodShortName(input_method); @@ -553,10 +547,9 @@ const InputMethodDescriptor* InputMethodUtil::GetInputMethodDescriptorFromId( const std::string& input_method_id) const { - InputMethodIdToDescriptorMap::const_iterator iter = - id_to_descriptor_.find(input_method_id); + auto iter = id_to_descriptor_.find(input_method_id); if (iter == id_to_descriptor_.end()) - return NULL; + return nullptr; return &(iter->second); } @@ -581,8 +574,7 @@ std::pair<LanguageCodeToIdsMap::const_iterator, LanguageCodeToIdsMap::const_iterator> range = language_code_to_ids.equal_range(normalized_language_code); - for (LanguageCodeToIdsMap::const_iterator iter = range.first; - iter != range.second; ++iter) { + for (auto iter = range.first; iter != range.second; ++iter) { const std::string& input_method_id = iter->second; if ((type == kAllInputMethods) || IsKeyboardLayout(input_method_id)) { out_input_method_ids->push_back(input_method_id); @@ -607,13 +599,11 @@ const std::string current_layout = preferred_input_method.GetPreferredKeyboardLayout(); - for (size_t i = 0; i < base::size(kDefaultInputMethodRecommendation); ++i) { - if (kDefaultInputMethodRecommendation[i].locale == language_code && - (!kDefaultInputMethodRecommendation[i].layout[0] || - kDefaultInputMethodRecommendation[i].layout == current_layout)) { + for (const auto& i : kDefaultInputMethodRecommendation) { + if (i.locale == language_code && + (!i.layout[0] || i.layout == current_layout)) { out_input_method_ids->push_back( - extension_ime_util::GetInputMethodIDByEngineID( - kDefaultInputMethodRecommendation[i].engine_id)); + extension_ime_util::GetInputMethodIDByEngineID(i.engine_id)); return; } } @@ -633,12 +623,12 @@ std::vector<std::string>* out_language_codes) const { out_language_codes->clear(); - for (size_t i = 0; i < input_method_ids.size(); ++i) { - const std::string& input_method_id = input_method_ids[i]; + for (const auto& i : input_method_ids) { + const std::string& input_method_id = i; const InputMethodDescriptor* input_method = GetInputMethodDescriptorFromId(input_method_id); if (!input_method) { - DVLOG(1) << "Unknown input method ID: " << input_method_ids[i]; + DVLOG(1) << "Unknown input method ID: " << i; continue; } DCHECK(!input_method->language_codes().empty()); @@ -666,12 +656,10 @@ const std::string& input_method_id) { std::string engine_id = input_method_id; // Migrates some Engine IDs from VPD. - for (size_t j = 0; j < base::size(kEngineIdMigrationMap); ++j) { - size_t pos = engine_id.find(kEngineIdMigrationMap[j][0]); + for (const auto& entry : kEngineIdMigrationMap) { + size_t pos = engine_id.find(entry[0]); if (pos == 0) { - engine_id.replace(0, - strlen(kEngineIdMigrationMap[j][0]), - kEngineIdMigrationMap[j][1]); + engine_id.replace(0, strlen(entry[0]), entry[1]); break; } } @@ -690,10 +678,10 @@ std::vector<std::string>* input_method_ids) { bool rewritten = false; std::vector<std::string>& ids = *input_method_ids; - for (size_t i = 0; i < ids.size(); ++i) { - std::string id = MigrateInputMethod(ids[i]); - if (id != ids[i]) { - ids[i] = id; + for (std::string& i : ids) { + std::string id = MigrateInputMethod(i); + if (id != i) { + i = id; rewritten = true; } } @@ -701,10 +689,10 @@ // Removes the duplicates. std::vector<std::string> new_ids; std::unordered_set<std::string> ids_set; - for (size_t i = 0; i < ids.size(); ++i) { - if (ids_set.find(ids[i]) == ids_set.end()) - new_ids.push_back(ids[i]); - ids_set.insert(ids[i]); + for (const auto& id : ids) { + if (ids_set.find(id) == ids_set.end()) + new_ids.push_back(id); + ids_set.insert(id); } ids.swap(new_ids); } @@ -724,10 +712,10 @@ MigrateInputMethods(&hardware_layouts_); bool has_xkb = false; - for (size_t i = 0; i < hardware_layouts_.size(); ++i) { - if (IsLoginKeyboard(hardware_layouts_[i])) - hardware_login_layouts_.push_back(hardware_layouts_[i]); - if (extension_ime_util::IsKeyboardLayoutExtension(hardware_layouts_[i])) + for (const auto& hardware_layout : hardware_layouts_) { + if (IsLoginKeyboard(hardware_layout)) + hardware_login_layouts_.push_back(hardware_layout); + if (extension_ime_util::IsKeyboardLayoutExtension(hardware_layout)) has_xkb = true; } @@ -783,25 +771,25 @@ } void InputMethodUtil::AppendInputMethods(const InputMethodDescriptors& imes) { - for (size_t i = 0; i < imes.size(); ++i) { - const InputMethodDescriptor& input_method = imes[i]; + for (const auto& input_method : imes) { DCHECK(!input_method.language_codes().empty()); const std::vector<std::string>& language_codes = input_method.language_codes(); id_to_descriptor_[input_method.id()] = input_method; typedef LanguageCodeToIdsMap::const_iterator It; - for (size_t j = 0; j < language_codes.size(); ++j) { + for (const auto& language_code : language_codes) { std::pair<It, It> range = - language_code_to_ids_.equal_range(language_codes[j]); - It it = range.first; + language_code_to_ids_.equal_range(language_code); + auto it = range.first; for (; it != range.second; ++it) { if (it->second == input_method.id()) break; } - if (it == range.second) + if (it == range.second) { language_code_to_ids_.insert( - std::make_pair(language_codes[j], input_method.id())); + std::make_pair(language_code, input_method.id())); + } } } } @@ -827,9 +815,9 @@ InputMethodDescriptor InputMethodUtil::GetFallbackInputMethodDescriptor() { std::vector<std::string> layouts; - layouts.push_back("us"); + layouts.emplace_back("us"); std::vector<std::string> languages; - languages.push_back("en-US"); + languages.emplace_back("en-US"); return InputMethodDescriptor( extension_ime_util::GetInputMethodIDByEngineID("xkb:us::eng"), "",
diff --git a/ui/base/ime/chromeos/input_method_util_unittest.cc b/ui/base/ime/chromeos/input_method_util_unittest.cc index 92d13947..363760c 100644 --- a/ui/base/ime/chromeos/input_method_util_unittest.cc +++ b/ui/base/ime/chromeos/input_method_util_unittest.cc
@@ -60,8 +60,8 @@ std::vector<std::string> layouts; std::vector<std::string> languages; - layouts.push_back("us"); - languages.push_back("zh-CN"); + layouts.emplace_back("us"); + languages.emplace_back("zh-CN"); InputMethodDescriptor pinyin_ime(Id(pinyin_ime_id), "Pinyin input for testing", @@ -74,7 +74,7 @@ input_methods.push_back(pinyin_ime); languages.clear(); - languages.push_back("zh-TW"); + languages.emplace_back("zh-TW"); InputMethodDescriptor zhuyin_ime(zhuyin_ime_id, "Zhuyin input for testing", "TW", @@ -177,14 +177,13 @@ TEST_F(InputMethodUtilTest, GetInputMethodMediumNameTest) { { // input methods with medium name equal to short name - const char* const input_method_id[] = { + const char* const input_method_ids[] = { "xkb:us:altgr-intl:eng", "xkb:us:dvorak:eng", "xkb:us:intl:eng", "xkb:us:colemak:eng", "xkb:de:neo:ger", "xkb:es:cat:cat", "xkb:gb:dvorak:eng", }; - const int len = base::size(input_method_id); - for (int i = 0; i < len; ++i) { - InputMethodDescriptor desc = GetDesc(input_method_id[i], "", "", ""); + for (const char* id : input_method_ids) { + InputMethodDescriptor desc = GetDesc(id, "", "", ""); base::string16 medium_name = util_.GetInputMethodMediumName(desc); base::string16 short_name = util_.GetInputMethodShortName(desc); EXPECT_EQ(medium_name, short_name); @@ -192,12 +191,12 @@ } { // input methods with medium name not equal to short name - const char* const input_method_id[] = { - pinyin_ime_id, zhuyin_ime_id, + const char* const input_method_ids[] = { + pinyin_ime_id, + zhuyin_ime_id, }; - const int len = base::size(input_method_id); - for (int i = 0; i < len; ++i) { - InputMethodDescriptor desc = GetDesc(input_method_id[i], "", "", ""); + for (const char* id : input_method_ids) { + InputMethodDescriptor desc = GetDesc(id, "", "", ""); base::string16 medium_name = util_.GetInputMethodMediumName(desc); base::string16 short_name = util_.GetInputMethodShortName(desc); EXPECT_NE(medium_name, short_name); @@ -292,11 +291,11 @@ } TEST_F(InputMethodUtilTest, TestGetInputMethodDescriptorFromId) { - EXPECT_EQ(NULL, util_.GetInputMethodDescriptorFromId("non_existent")); + EXPECT_EQ(nullptr, util_.GetInputMethodDescriptorFromId("non_existent")); const InputMethodDescriptor* descriptor = util_.GetInputMethodDescriptorFromId(Id(pinyin_ime_id)); - ASSERT_TRUE(NULL != descriptor); // ASSERT_NE doesn't compile. + ASSERT_TRUE(nullptr != descriptor); // ASSERT_NE doesn't compile. EXPECT_EQ(Id(pinyin_ime_id), descriptor->id()); EXPECT_EQ("us", descriptor->GetPreferredKeyboardLayout()); // This used to be "zh" but now we have "zh-CN" in input_methods.h, @@ -340,7 +339,7 @@ TEST_F(InputMethodUtilTest, TestGetFirstLoginInputMethodIds_Us_And_EnUs) { const InputMethodDescriptor* descriptor = util_.GetInputMethodDescriptorFromId(Id("xkb:us::eng")); // US keyboard. - ASSERT_TRUE(NULL != descriptor); // ASSERT_NE doesn't compile. + ASSERT_TRUE(nullptr != descriptor); // ASSERT_NE doesn't compile. std::vector<std::string> input_method_ids; util_.GetFirstLoginInputMethodIds("en-US", *descriptor, &input_method_ids); ASSERT_EQ(1U, input_method_ids.size()); @@ -351,7 +350,7 @@ TEST_F(InputMethodUtilTest, TestGetFirstLoginInputMethodIds_Us_And_Zh) { const InputMethodDescriptor* descriptor = util_.GetInputMethodDescriptorFromId(Id("xkb:us::eng")); // US keyboard. - ASSERT_TRUE(NULL != descriptor); // ASSERT_NE doesn't compile. + ASSERT_TRUE(nullptr != descriptor); // ASSERT_NE doesn't compile. std::vector<std::string> input_method_ids; util_.GetFirstLoginInputMethodIds("zh-CN", *descriptor, &input_method_ids); ASSERT_EQ(2U, input_method_ids.size()); @@ -363,7 +362,7 @@ TEST_F(InputMethodUtilTest, TestGetFirstLoginInputMethodIds_Us_And_Ru) { const InputMethodDescriptor* descriptor = util_.GetInputMethodDescriptorFromId(Id("xkb:us::eng")); // US keyboard. - ASSERT_TRUE(NULL != descriptor); // ASSERT_NE doesn't compile. + ASSERT_TRUE(nullptr != descriptor); // ASSERT_NE doesn't compile. std::vector<std::string> input_method_ids; util_.GetFirstLoginInputMethodIds("ru", *descriptor, &input_method_ids); ASSERT_EQ(2U, input_method_ids.size()); @@ -375,7 +374,7 @@ TEST_F(InputMethodUtilTest, TestGetFirstLoginInputMethodIds_Us_And_ZhTw) { const InputMethodDescriptor* descriptor = util_.GetInputMethodDescriptorFromId(Id("xkb:us::eng")); // US keyboard. - ASSERT_TRUE(NULL != descriptor); // ASSERT_NE doesn't compile. + ASSERT_TRUE(nullptr != descriptor); // ASSERT_NE doesn't compile. std::vector<std::string> input_method_ids; util_.GetFirstLoginInputMethodIds("zh-TW", *descriptor, &input_method_ids); ASSERT_EQ(2U, input_method_ids.size()); @@ -387,7 +386,7 @@ TEST_F(InputMethodUtilTest, TestGetFirstLoginInputMethodIds_Us_And_Th) { const InputMethodDescriptor* descriptor = util_.GetInputMethodDescriptorFromId(Id("xkb:us::eng")); // US keyboard. - ASSERT_TRUE(NULL != descriptor); // ASSERT_NE doesn't compile. + ASSERT_TRUE(nullptr != descriptor); // ASSERT_NE doesn't compile. std::vector<std::string> input_method_ids; util_.GetFirstLoginInputMethodIds("th", *descriptor, &input_method_ids); ASSERT_EQ(2U, input_method_ids.size()); @@ -399,7 +398,7 @@ TEST_F(InputMethodUtilTest, TestGetFirstLoginInputMethodIds_Us_And_Vi) { const InputMethodDescriptor* descriptor = util_.GetInputMethodDescriptorFromId(Id("xkb:us::eng")); // US keyboard. - ASSERT_TRUE(NULL != descriptor); // ASSERT_NE doesn't compile. + ASSERT_TRUE(nullptr != descriptor); // ASSERT_NE doesn't compile. std::vector<std::string> input_method_ids; util_.GetFirstLoginInputMethodIds("vi", *descriptor, &input_method_ids); ASSERT_EQ(2U, input_method_ids.size()); @@ -411,7 +410,7 @@ TEST_F(InputMethodUtilTest, TestGetFirstLoginInputMethodIds_Us_And_Jp) { const InputMethodDescriptor* descriptor = util_.GetInputMethodDescriptorFromId(Id("xkb:us::eng")); // US keyboard. - ASSERT_TRUE(NULL != descriptor); // ASSERT_NE doesn't compile. + ASSERT_TRUE(nullptr != descriptor); // ASSERT_NE doesn't compile. std::vector<std::string> input_method_ids; util_.GetFirstLoginInputMethodIds("ja", *descriptor, &input_method_ids); ASSERT_EQ(2U, input_method_ids.size()); @@ -423,7 +422,7 @@ TEST_F(InputMethodUtilTest, TestGetFirstLoginInputMethodIds_Jp_And_Jp) { const InputMethodDescriptor* descriptor = util_.GetInputMethodDescriptorFromId(Id("xkb:jp::jpn")); // JP keyboard. - ASSERT_TRUE(NULL != descriptor); // ASSERT_NE doesn't compile. + ASSERT_TRUE(nullptr != descriptor); // ASSERT_NE doesn't compile. std::vector<std::string> input_method_ids; util_.GetFirstLoginInputMethodIds("ja", *descriptor, &input_method_ids); ASSERT_EQ(2U, input_method_ids.size()); @@ -435,7 +434,7 @@ TEST_F(InputMethodUtilTest, TestGetFirstLoginInputMethodIds_Us_And_He) { const InputMethodDescriptor* descriptor = util_.GetInputMethodDescriptorFromId(Id("xkb:us::eng")); // US keyboard. - ASSERT_TRUE(NULL != descriptor); // ASSERT_NE doesn't compile. + ASSERT_TRUE(nullptr != descriptor); // ASSERT_NE doesn't compile. std::vector<std::string> input_method_ids; util_.GetFirstLoginInputMethodIds("he", *descriptor, &input_method_ids); ASSERT_EQ(2U, input_method_ids.size()); @@ -461,9 +460,8 @@ TEST_F(InputMethodUtilTest, TestIBusInputMethodText) { const std::map<std::string, InputMethodDescriptor>& id_to_descriptor = util_.GetIdToDesciptorMapForTesting(); - for (std::map<std::string, InputMethodDescriptor>::const_iterator it = - id_to_descriptor.begin(); it != id_to_descriptor.end(); ++it) { - const std::string language_code = it->second.language_codes().at(0); + for (const auto& it : id_to_descriptor) { + const std::string language_code = it.second.language_codes().at(0); const base::string16 display_name = l10n_util::GetDisplayNameForLocale(language_code, "en", false); // Only two formats, like "fr" (lower case) and "en-US" (lower-upper), are @@ -495,10 +493,10 @@ {"unknown", "unknown"}, }; std::vector<std::string> input_method_ids; - for (size_t i = 0; i < base::size(migration_cases); ++i) - input_method_ids.push_back(migration_cases[i][0]); + for (const auto& migration_case : migration_cases) + input_method_ids.emplace_back(migration_case[0]); // Duplicated hangul_2set. - input_method_ids.push_back("ime:ko:hangul_2set"); + input_method_ids.emplace_back("ime:ko:hangul_2set"); util_.MigrateInputMethods(&input_method_ids);
diff --git a/ui/base/ime/chromeos/input_method_whitelist.cc b/ui/base/ime/chromeos/input_method_whitelist.cc index e3078069..0c65bbf 100644 --- a/ui/base/ime/chromeos/input_method_whitelist.cc +++ b/ui/base/ime/chromeos/input_method_whitelist.cc
@@ -21,13 +21,12 @@ const char kLanguageDelimiter[] = ","; InputMethodWhitelist::InputMethodWhitelist() { - for (size_t i = 0; i < base::size(kInputMethods); ++i) { - supported_input_methods_.insert(kInputMethods[i].input_method_id); + for (const auto& input_method : kInputMethods) { + supported_input_methods_.insert(input_method.input_method_id); } } -InputMethodWhitelist::~InputMethodWhitelist() { -} +InputMethodWhitelist::~InputMethodWhitelist() = default; bool InputMethodWhitelist::InputMethodIdIsWhitelisted( const std::string& input_method_id) const { @@ -39,25 +38,22 @@ std::unique_ptr<InputMethodDescriptors> input_methods( new InputMethodDescriptors); input_methods->reserve(base::size(kInputMethods)); - for (size_t i = 0; i < base::size(kInputMethods); ++i) { + for (const auto& input_method : kInputMethods) { std::vector<std::string> layouts; - layouts.push_back(kInputMethods[i].xkb_layout_id); + layouts.emplace_back(input_method.xkb_layout_id); - std::vector<std::string> languages = base::SplitString( - kInputMethods[i].language_code, kLanguageDelimiter, - base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + std::vector<std::string> languages = + base::SplitString(input_method.language_code, kLanguageDelimiter, + base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); DCHECK(!languages.empty()); input_methods->push_back(InputMethodDescriptor( extension_ime_util::GetInputMethodIDByEngineID( - kInputMethods[i].input_method_id), - "", - kInputMethods[i].indicator, - layouts, - languages, - kInputMethods[i].is_login_keyboard, - GURL(), // options page url. - GURL() // input view page url. + input_method.input_method_id), + "", input_method.indicator, layouts, languages, + input_method.is_login_keyboard, + GURL(), // options page url. + GURL() // input view page url. )); } return input_methods;
diff --git a/ui/base/ime/chromeos/mock_component_extension_ime_manager_delegate.cc b/ui/base/ime/chromeos/mock_component_extension_ime_manager_delegate.cc index 82f6c13..3090121 100644 --- a/ui/base/ime/chromeos/mock_component_extension_ime_manager_delegate.cc +++ b/ui/base/ime/chromeos/mock_component_extension_ime_manager_delegate.cc
@@ -16,8 +16,8 @@ unload_call_count_(0) { } -MockComponentExtIMEManagerDelegate::~MockComponentExtIMEManagerDelegate() { -} +MockComponentExtIMEManagerDelegate::~MockComponentExtIMEManagerDelegate() = + default; std::vector<ComponentExtensionIME> MockComponentExtIMEManagerDelegate::ListIME() {
diff --git a/ui/base/ime/chromeos/mock_ime_candidate_window_handler.cc b/ui/base/ime/chromeos/mock_ime_candidate_window_handler.cc index 9f6c7e85..4d31aa9 100644 --- a/ui/base/ime/chromeos/mock_ime_candidate_window_handler.cc +++ b/ui/base/ime/chromeos/mock_ime_candidate_window_handler.cc
@@ -11,9 +11,7 @@ update_lookup_table_call_count_(0) { } -MockIMECandidateWindowHandler::~MockIMECandidateWindowHandler() { - -} +MockIMECandidateWindowHandler::~MockIMECandidateWindowHandler() = default; void MockIMECandidateWindowHandler::UpdateLookupTable( const ui::CandidateWindow& table,
diff --git a/ui/base/ime/chromeos/mock_ime_engine_handler.cc b/ui/base/ime/chromeos/mock_ime_engine_handler.cc index a3a6022..20f33712 100644 --- a/ui/base/ime/chromeos/mock_ime_engine_handler.cc +++ b/ui/base/ime/chromeos/mock_ime_engine_handler.cc
@@ -21,8 +21,7 @@ last_set_surrounding_cursor_pos_(0), last_set_surrounding_anchor_pos_(0) {} -MockIMEEngineHandler::~MockIMEEngineHandler() { -} +MockIMEEngineHandler::~MockIMEEngineHandler() = default; void MockIMEEngineHandler::FocusIn(const InputContext& input_context) { last_text_input_context_ = input_context;
diff --git a/ui/base/ime/chromeos/mock_input_method_manager.cc b/ui/base/ime/chromeos/mock_input_method_manager.cc index 570c59b9..cabbcee 100644 --- a/ui/base/ime/chromeos/mock_input_method_manager.cc +++ b/ui/base/ime/chromeos/mock_input_method_manager.cc
@@ -9,7 +9,7 @@ namespace chromeos { namespace input_method { -MockInputMethodManager::State::State() {} +MockInputMethodManager::State::State() = default; scoped_refptr<InputMethodManager::State> MockInputMethodManager::State::Clone() const { @@ -112,12 +112,12 @@ return GURL::EmptyGURL(); } -MockInputMethodManager::State::~State() {} +MockInputMethodManager::State::~State() = default; MockInputMethodManager::MockInputMethodManager() : features_enabled_state_(InputMethodManager::FEATURE_ALL) {} -MockInputMethodManager::~MockInputMethodManager() {} +MockInputMethodManager::~MockInputMethodManager() = default; InputMethodManager::UISessionState MockInputMethodManager::GetUISessionState() { return InputMethodManager::STATE_BROWSER_SCREEN;
diff --git a/ui/base/ime/win/tsf_text_store.cc b/ui/base/ime/win/tsf_text_store.cc index 2db29ce0..ee6a31bc 100644 --- a/ui/base/ime/win/tsf_text_store.cc +++ b/ui/base/ime/win/tsf_text_store.cc
@@ -1243,8 +1243,15 @@ } else { new_text_size = new_size - replace_text_range_.start(); } + // If |new_text_size| is 0, then we want to commit composition with current + // composition text if there is any. Construct |new_committed_string| to be + // current composition text so that |TextInputClient::InsertText| will + // commit current composition text. const base::string16& new_committed_string = string_buffer_document_.substr( - replace_text_range_.start(), new_text_size); + replace_text_range_.start(), + (new_text_size == 0 && selection_.end() > replace_text_range_.start()) + ? selection_.end() - replace_text_range_.start() + : new_text_size); // if the |replace_text_range_| start is greater than |old_size|, then we // don't need to delete anything because the replacement text hasn't been // inserted into blink yet. @@ -1267,8 +1274,16 @@ new_committed_string_offset = replace_text_range_.start(); new_committed_string_size = replace_text_size_; } + // If |new_committed_string_size| is 0, then we want to commit composition + // with current composition text if there is any. Construct + // |new_committed_string| to be current composition text so that + // |TextInputClient::InsertText| will commit current composition text. const base::string16& new_committed_string = string_buffer_document_.substr( - new_committed_string_offset, new_committed_string_size); + new_committed_string_offset, + (new_committed_string_size == 0 && + selection_.end() > new_committed_string_offset) + ? selection_.end() - new_committed_string_offset + : new_committed_string_size); // TODO(crbug.com/978678): Unify the behavior of // |TextInputClient::InsertText(text)| for the empty text. if (!new_committed_string.empty())
diff --git a/ui/base/ime/win/tsf_text_store_unittest.cc b/ui/base/ime/win/tsf_text_store_unittest.cc index 36121c76..e66184d5 100644 --- a/ui/base/ime/win/tsf_text_store_unittest.cc +++ b/ui/base/ime/win/tsf_text_store_unittest.cc
@@ -2892,5 +2892,100 @@ EXPECT_EQ(S_OK, result); } +// Due to crbug.com/978678, we should not call TextInputClient::InsertText if +// provided text is empty. In fact, we should call TextInputClient::InsertText +// with current composition text to commit compositon without losing text. +class RegressionTest4Callback : public TSFTextStoreTestCallback { + public: + explicit RegressionTest4Callback(TSFTextStore* text_store) + : TSFTextStoreTestCallback(text_store) {} + + HRESULT LockGranted1(DWORD flags) { + GetTextTest(0, -1, L"", 0); + SetTextTest(0, 0, L"a", S_OK); + GetTextTest(0, -1, L"a", 1); + SetSelectionTest(0, 1, S_OK); + + text_spans()->clear(); + ImeTextSpan text_span; + text_span.start_offset = 0; + text_span.end_offset = 1; + text_span.underline_color = SK_ColorBLACK; + text_span.thickness = ImeTextSpan::Thickness::kThin; + text_span.background_color = SK_ColorTRANSPARENT; + text_spans()->push_back(text_span); + *edit_flag() = true; + *composition_start() = 0; + composition_range()->set_start(0); + composition_range()->set_end(1); + text_store_->OnKeyTraceDown(65u, 1966081u); + *has_composition_range() = true; + + return S_OK; + } + + void SetCompositionText1(const ui::CompositionText& composition) { + EXPECT_EQ(L"a", composition.text); + EXPECT_EQ(0u, composition.selection.start()); + EXPECT_EQ(1u, composition.selection.end()); + ASSERT_EQ(1u, composition.ime_text_spans.size()); + EXPECT_EQ(SK_ColorBLACK, composition.ime_text_spans[0].underline_color); + EXPECT_EQ(SK_ColorTRANSPARENT, + composition.ime_text_spans[0].background_color); + EXPECT_EQ(0u, composition.ime_text_spans[0].start_offset); + EXPECT_EQ(1u, composition.ime_text_spans[0].end_offset); + EXPECT_EQ(ImeTextSpan::Thickness::kThin, + composition.ime_text_spans[0].thickness); + SetHasCompositionText(true); + } + + HRESULT LockGranted2(DWORD flags) { + GetTextTest(0, -1, L"a", 1); + SetSelectionTest(1, 1, S_OK); + + text_spans()->clear(); + *edit_flag() = true; + *composition_start() = 0; + composition_range()->set_start(0); + composition_range()->set_end(0); + + *has_composition_range() = false; + return S_OK; + } + + void InsertText2(const base::string16& text) { + EXPECT_EQ(L"a", text); + SetHasCompositionText(false); + } + + private: + DISALLOW_COPY_AND_ASSIGN(RegressionTest4Callback); +}; + +TEST_F(TSFTextStoreTest, RegressionTest4) { + RegressionTest4Callback callback(text_store_.get()); + EXPECT_CALL(text_input_client_, SetCompositionText(_)) + .WillOnce( + Invoke(&callback, &RegressionTest4Callback::SetCompositionText1)); + + EXPECT_CALL(text_input_client_, InsertText(_)) + .WillOnce(Invoke(&callback, &RegressionTest4Callback::InsertText2)); + + EXPECT_CALL(*sink_, OnLockGranted(_)) + .WillOnce(Invoke(&callback, &RegressionTest4Callback::LockGranted1)) + .WillOnce(Invoke(&callback, &RegressionTest4Callback::LockGranted2)); + + ON_CALL(text_input_client_, HasCompositionText()) + .WillByDefault( + Invoke(&callback, &TSFTextStoreTestCallback::HasCompositionText)); + + HRESULT result = kInvalidResult; + EXPECT_EQ(S_OK, text_store_->RequestLock(TS_LF_READWRITE, &result)); + EXPECT_EQ(S_OK, result); + result = kInvalidResult; + EXPECT_EQ(S_OK, text_store_->RequestLock(TS_LF_READWRITE, &result)); + EXPECT_EQ(S_OK, result); +} + } // namespace } // namespace ui
diff --git a/ui/file_manager/file_manager/foreground/css/file_manager.css b/ui/file_manager/file_manager/foreground/css/file_manager.css index 823eaca..ade3c7f 100644 --- a/ui/file_manager/file_manager/foreground/css/file_manager.css +++ b/ui/file_manager/file_manager/foreground/css/file_manager.css
@@ -2159,6 +2159,10 @@ padding-bottom: 8px; } +.signals-overscroll { + min-height: calc(68px + 24px); +} + /* Progress center */ @keyframes progress-center-toggle {
diff --git a/ui/file_manager/file_manager/foreground/elements/files_metadata_box.js b/ui/file_manager/file_manager/foreground/elements/files_metadata_box.js index 0e5bb12b..e7c5a5b 100644 --- a/ui/file_manager/file_manager/foreground/elements/files_metadata_box.js +++ b/ui/file_manager/file_manager/foreground/elements/files_metadata_box.js
@@ -6,11 +6,13 @@ is: 'files-metadata-box', properties: { - // File media type, e.g. image, video. + // File path and type, e.g. image, video. + filePath: String, type: String, + + // File size, modification time, mimeType. size: String, modificationTime: String, - filePath: String, mediaMimeType: String, // File type specific metadata below. @@ -69,6 +71,16 @@ * @private */ hasFileSpecificInfo_: Boolean, + + /** + * FilesMetadataBox [metadata] attribute. Used to indicate the metadata box + * field rendering phases. + * @private + */ + metadata: { + type: String, + reflectToAttribute: true, + }, }, /** @@ -76,10 +88,15 @@ * @param {boolean} keepSizeFields do not clear size and isSizeLoading fields. */ clear: function(keepSizeFields) { + this.filePath = ''; this.type = ''; + + if (!keepSizeFields) { + this.size = ''; + this.isSizeLoading = false; + } this.modificationTime = ''; this.mediaMimeType = ''; - this.filePath = ''; this.imageWidth = 0; this.imageHeight = 0; @@ -92,10 +109,7 @@ this.mediaYearRecorded = ''; this.ifd = null; - if (!keepSizeFields) { - this.size = ''; - this.isSizeLoading = false; - } + this.metadata = ''; }, /** @@ -141,6 +155,21 @@ }, /** + * Update the metadata attribute with the rendered metadata |type|. + * @param {?string} type + * @public + */ + metadataRendered: function(type) { + if (!type) { + this.metadata = ''; + } else if (!this.metadata) { + this.metadata = type; + } else { + this.metadata += ' ' + type; + } + }, + + /** * Converts the duration into human friendly string. * @param {number} time the duration in seconds. * @return {string} String representation of the given duration.
diff --git a/ui/file_manager/file_manager/foreground/js/metadata_box_controller.js b/ui/file_manager/file_manager/foreground/js/metadata_box_controller.js index 3609d7c..3033a5c 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata_box_controller.js +++ b/ui/file_manager/file_manager/foreground/js/metadata_box_controller.js
@@ -151,6 +151,7 @@ } else if (item.size) { this.metadataBox_.size = this.fileMetadataFormatter_.formatSize(item.size, item.hosted); + this.metadataBox_.metadataRendered('size'); } this.updateModificationTime_(entry, isSameEntry, items); @@ -159,11 +160,13 @@ this.metadataModel_.get([entry], ['contentMimeType']).then(items => { const item = items[0]; this.metadataBox_.mediaMimeType = item.contentMimeType || ''; + this.metadataBox_.metadataRendered('mime'); }); } else { this.metadataModel_.get([entry], ['mediaMimeType']).then(items => { const item = items[0]; this.metadataBox_.mediaMimeType = item.mediaMimeType || ''; + this.metadataBox_.metadataRendered('mime'); }); } @@ -178,6 +181,7 @@ /** @type {number} */ (item.imageHeight); this.metadataBox_.imageWidth = /** @type {number} */ (item.imageWidth); + this.metadataBox_.metadataRendered('meta'); }); } else { this.metadataModel_ @@ -207,6 +211,7 @@ this.metadataBox_.mediaTitle = item.mediaTitle || ''; this.metadataBox_.mediaTrack = item.mediaTrack || ''; this.metadataBox_.mediaYearRecorded = item.mediaYearRecorded || ''; + this.metadataBox_.metadataRendered('meta'); }); } } @@ -293,5 +298,6 @@ this.metadataBox_.size = this.fileMetadataFormatter_.formatSize(size, true); this.metadataBox_.isSizeLoading = false; + this.metadataBox_.metadataRendered('size'); }); };
diff --git a/ui/file_manager/file_manager/foreground/js/quick_view_controller.js b/ui/file_manager/file_manager/foreground/js/quick_view_controller.js index d6f957d..cd932e8 100644 --- a/ui/file_manager/file_manager/foreground/js/quick_view_controller.js +++ b/ui/file_manager/file_manager/foreground/js/quick_view_controller.js
@@ -271,7 +271,10 @@ } /** - * Update quick view using file entry and loaded metadata and tasks. + * Update quick view for |entry| from its loaded metadata and tasks. + * + * Note: fast-typing users can change the active selection while the |entry| + * metadata and tasks were being async fetched. Bail out in that case. * * @param {!FileEntry} entry * @param {Array<MetadataItem>} items @@ -280,6 +283,10 @@ */ onMetadataLoaded_(entry, items, tasks) { return this.getQuickViewParameters_(entry, items, tasks).then(params => { + if (this.quickViewModel_.getSelectedEntry() != entry) { + return; // Bail: there's no point drawing a stale selection. + } + this.quickView_.type = params.type || ''; this.quickView_.subtype = params.subtype || ''; this.quickView_.filePath = params.filePath || ''; @@ -321,10 +328,10 @@ volumeInfo.volumeType) >= 0; if (!localFile) { - // For Drive files, display a thumbnail if there is one. + // Drive files: fetch their thumbnail if there is one. if (item.thumbnailUrl) { return this.loadThumbnailFromDrive_(item.thumbnailUrl).then(result => { - if (result.status === 'success') { + if (result.status === LoadImageResponseStatus.SUCCESS) { if (params.type == 'video') { params.videoPoster = result.data; } else if (params.type == 'image') { @@ -344,9 +351,26 @@ return Promise.resolve(params); } + if (type === 'raw') { + // RAW files: fetch their ImageLoader thumbnail. + return this.loadRawFileThumbnailFromImageLoader_(entry) + .then(result => { + if (result.status === LoadImageResponseStatus.SUCCESS) { + params.contentUrl = result.data; + params.type = 'image'; + } + return params; + }) + .catch(e => { + console.error(e); + return params; + }); + } + if (type === '.folder') { return Promise.resolve(params); } + return new Promise((resolve, reject) => { entry.file(resolve, reject); }) @@ -407,8 +431,7 @@ * Loads a thumbnail from Drive. * * @param {string} url Thumbnail url - * @return Promise<{{status: string, data:string, width:number, - * height:number}}> + * @return Promise<!LoadImageResponse> * @private */ loadThumbnailFromDrive_(url) { @@ -417,6 +440,30 @@ LoadImageRequest.createForUrl(url), resolve); }); } + + /** + * Loads a RAW image thumbnail from ImageLoader. Resolve the file entry first + * to get its |lastModified| time. ImageLoaderClient uses that to work out if + * its cached data for |entry| is up-to-date or otherwise call ImageLoader to + * refresh the cached |entry| data with the most recent data. + * + * @param {!Entry} entry The RAW file entry. + * @return Promise<!LoadImageResponse> + * @private + */ + loadRawFileThumbnailFromImageLoader_(entry) { + return new Promise((resolve, reject) => { + entry.file(function requestFileThumbnail(file) { + const request = LoadImageRequest.createForUrl(entry.toURL()); + request.maxWidth = ThumbnailLoader.THUMBNAIL_MAX_WIDTH; + request.maxHeight = ThumbnailLoader.THUMBNAIL_MAX_HEIGHT; + request.timestamp = file.lastModified; + request.cache = true; + request.priority = 0; + ImageLoaderClient.getInstance().load(request, resolve); + }, reject); + }); + } } /**
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_grid.js b/ui/file_manager/file_manager/foreground/js/ui/file_grid.js index 1b4c0017..e8419ce 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/file_grid.js +++ b/ui/file_manager/file_manager/foreground/js/ui/file_grid.js
@@ -116,6 +116,12 @@ self.historyLoader_ = historyLoader; self.a11y = a11y; + // Force the list's ending spacer to be tall enough to allow overscroll. + let endSpacer = self.querySelector('.spacer:last-child'); + if (endSpacer) { + endSpacer.classList.add('signals-overscroll'); + } + self.listThumbnailLoader_ = null; self.beginIndex_ = 0; self.endIndex_ = 0;
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_table.js b/ui/file_manager/file_manager/foreground/js/ui/file_table.js index 379bcbd9..421ab1e 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/file_table.js +++ b/ui/file_manager/file_manager/foreground/js/ui/file_table.js
@@ -433,6 +433,12 @@ self.historyLoader_ = historyLoader; self.a11y = a11y; + // Force the list's ending spacer to be tall enough to allow overscroll. + let endSpacer = self.querySelector('.spacer:last-child'); + if (endSpacer) { + endSpacer.classList.add('signals-overscroll'); + } + /** @private {ListThumbnailLoader} */ self.listThumbnailLoader_ = null;
diff --git a/ui/file_manager/file_manager/foreground/js/ui/progress_center_panel.js b/ui/file_manager/file_manager/foreground/js/ui/progress_center_panel.js index e05cd70..9c7ebf9 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/progress_center_panel.js +++ b/ui/file_manager/file_manager/foreground/js/ui/progress_center_panel.js
@@ -336,10 +336,16 @@ panelItem = this.feedbackHost_.addPanelItem(item.id); panelItem.panelType = panelItem.panelTypeProgress; panelItem.setAttribute('primary-text', item.message); + panelItem.setAttribute('data-progress-id', item.id); if (item.subMessage) { panelItem.setAttribute('secondary-text', item.subMessage); } } + panelItem.signalCallback = (signal) => { + if (signal === 'cancel' && item.cancelCallback) { + item.cancelCallback(item.id); + } + }; panelItem.progress = item.progressRateInPercent; // Remove the feedback panel when complete, and create // an activity complete panel.
diff --git a/ui/file_manager/integration_tests/file_manager/quick_view.js b/ui/file_manager/integration_tests/file_manager/quick_view.js index dc3bfde1..7017a17 100644 --- a/ui/file_manager/integration_tests/file_manager/quick_view.js +++ b/ui/file_manager/integration_tests/file_manager/quick_view.js
@@ -94,11 +94,30 @@ * @return {string} text Text value in the field name. */ async function getQuickViewMetadataBoxField(appId, name) { + let filesMetadataBox = 'files-metadata-box'; + + /** + * <files-metadata-box> field rendering is async. The field name has been + * rendered when the 'metadata' attribute indicates that. + */ + switch (name) { + case 'Size': + filesMetadataBox += '[metadata~="size"]'; + break; + case 'Modified Time': + case 'Type': + filesMetadataBox += '[metadata~="mime"]'; + break; + default: + filesMetadataBox += '[metadata~="meta"]'; + break; + } + /** * The <files-metadata-box> element resides in the #quick-view shadow DOM * as a child of the #dialog element. */ - let quickViewQuery = ['#quick-view', '#dialog[open] files-metadata-box']; + let quickViewQuery = ['#quick-view', '#dialog[open] ' + filesMetadataBox]; /** * The <files-metadata-entry key="name"> element resides in the shadow DOM @@ -792,6 +811,52 @@ }; /** + * Tests opening Quick View on an RAW image. The RAW image has EXIF and that + * information should be displayed in the QuickView metadata box. + */ + testcase.openQuickViewImageRaw = async () => { + const caller = getCaller(); + + /** + * The <webview> resides in the <files-safe-media type="image"> shadow DOM, + * which is a child of the #quick-view shadow DOM. + */ + const webView = + ['#quick-view', 'files-safe-media[type="image"]', 'webview']; + + // Open Files app on Downloads containing ENTRIES.rawImage. + const appId = await setupAndWaitUntilReady( + RootPath.DOWNLOADS, [ENTRIES.rawImage], []); + + // Open the file in Quick View. + await openQuickView(appId, ENTRIES.rawImage.nameText); + + // Wait for the Quick View <webview> to load and display its content. + function checkWebViewImageLoaded(elements) { + let haveElements = Array.isArray(elements) && elements.length === 1; + if (haveElements) { + haveElements = elements[0].styles.display.includes('block'); + } + if (!haveElements || elements[0].attributes.loaded !== '') { + return pending(caller, 'Waiting for <webview> to load.'); + } + return; + } + await repeatUntil(async () => { + return checkWebViewImageLoaded(await remoteCall.callRemoteTestUtil( + 'deepQueryAllElements', appId, [webView, ['display']])); + }); + + // Check: the correct mimeType should be displayed. + const mimeType = await getQuickViewMetadataBoxField(appId, 'Type'); + chrome.test.assertEq('image/x-olympus-orf', mimeType); + + // Check: the image EXIF metadata should be displayed. + // TODO(crbug.com/965370) Make the metadata controller extract and display + // the RAW image EXIF metadata in the metadata box. + }; + + /** * Tests opening Quick View containing a video. */ testcase.openQuickViewVideo = async () => {