| // Copyright 2026 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CONTENT_BROWSER_PRELOADING_PREFETCH_PREFETCH_CONTAINER_ASYNC_OBSERVER_H_ |
| #define CONTENT_BROWSER_PRELOADING_PREFETCH_PREFETCH_CONTAINER_ASYNC_OBSERVER_H_ |
| |
| #include <memory> |
| |
| #include "base/memory/ptr_util.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/task/sequenced_task_runner.h" |
| #include "content/browser/preloading/prefetch/prefetch_container_observer.h" |
| |
| namespace content { |
| |
| // Wrapper class of `PrefetchContainerObserver` that notifies the underlying |
| // `PrefetchContainerObserver` asynchronously, to avoid complicated logic |
| // executed synchronously from `PrefetchContainer::NotifyObservers()`. |
| // |
| // Note: Currently `underlying_observer_` isn't notified of |
| // `OnWillBeDestroyed()`, to simplify the code and just because |
| // `OnWillBeDestroyed` is not used by the current use cases. |
| // |
| // Be careful of the state changes between the `PrefetchContainerLoadState` |
| // transitions and asynchronous `PrefetchContainerObserver` method calls. |
| // Namely, |
| // - The observer is notified only if the corresponding `PrefetchContainer` is |
| // still alive at the time of async call dispatch. |
| // - Prefer accessing `PrefetchContainer` methods that return the same value |
| // after the `PrefetchContainerLoadState` transitions, e.g. |
| // `GetInitialEligibility()`. |
| class PrefetchContainerAsyncObserverBase : public PrefetchContainerObserver { |
| public: |
| ~PrefetchContainerAsyncObserverBase() override; |
| |
| virtual PrefetchContainerObserver& GetUnderlyingObserver() = 0; |
| |
| // PrefetchContainerObserver implementations |
| void OnWillBeDestroyed(const PrefetchContainer& prefetch_container) override; |
| void OnGotInitialEligibility( |
| const PrefetchContainer& prefetch_container) override; |
| void OnDeterminedHead(const PrefetchContainer& prefetch_container) override; |
| void OnPrefetchCompletedOrFailed( |
| const PrefetchContainer& prefetch_container) override; |
| void OnPrefetchStale(const PrefetchContainer& prefetch_container) override; |
| |
| protected: |
| PrefetchContainerAsyncObserverBase(); |
| |
| private: |
| void Dispatch( |
| void (PrefetchContainerObserver::*method)(const PrefetchContainer&), |
| base::WeakPtr<const PrefetchContainer> prefetch_container); |
| |
| base::WeakPtrFactory<PrefetchContainerAsyncObserverBase> weak_factory_{this}; |
| }; |
| |
| template <typename UnderlyingObserver = PrefetchContainerObserver> |
| class PrefetchContainerAsyncObserver final |
| : public PrefetchContainerAsyncObserverBase { |
| public: |
| // Returns null if the `underlying_observer` is null. |
| static std::unique_ptr<PrefetchContainerAsyncObserver> Create( |
| std::unique_ptr<UnderlyingObserver> underlying_observer) { |
| if (!underlying_observer) { |
| return nullptr; |
| } |
| return base::WrapUnique( |
| new PrefetchContainerAsyncObserver(std::move(underlying_observer))); |
| } |
| |
| UnderlyingObserver& GetUnderlyingObserver() override { |
| return *underlying_observer_; |
| } |
| |
| private: |
| explicit PrefetchContainerAsyncObserver( |
| std::unique_ptr<UnderlyingObserver> underlying_observer) |
| : underlying_observer_(std::move(underlying_observer)) { |
| CHECK(underlying_observer_); |
| } |
| |
| std::unique_ptr<UnderlyingObserver> underlying_observer_; |
| }; |
| |
| } // namespace content |
| |
| #endif // CONTENT_BROWSER_PRELOADING_PREFETCH_PREFETCH_CONTAINER_ASYNC_OBSERVER_H_ |