| // Copyright 2025 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_PUBLIC_BROWSER_PROCESS_SELECTION_USER_DATA_H_ |
| #define CONTENT_PUBLIC_BROWSER_PROCESS_SELECTION_USER_DATA_H_ |
| |
| #include "base/memory/safe_ref.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/supports_user_data.h" |
| #include "content/common/content_export.h" |
| |
| namespace content { |
| |
| // This class is a container for embedder-specific data that is available |
| // during the renderer process selection phase of a navigation. An instance of |
| // this class is created for each NavigationRequest and is accessible from |
| // ProcessSelectionDeferringConditions. Embedders can define their own data |
| // classes that inherit from ProcessSelectionUserData::Data and attach them to |
| // this object. |
| // |
| // Example: |
| // |
| // // --- in foo_process_selection_deferring_condition.h --- |
| // class FooData : public content::ProcessSelectionUserData::Data<FooData> { |
| // public: |
| // // other public members |
| // |
| // private: |
| // friend ProcessSelectionUserData::Data; |
| // PROCESS_SELECTION_USER_DATA_KEY_DECL(); |
| // }; |
| // |
| // class FooProcessSelectionDeferringCondition |
| // : public content::ProcessSelectionDeferringCondition { |
| // // ... |
| // }; |
| // |
| // // --- in foo_process_selection_deferring_condition.cc --- |
| // PROCESS_SELECTION_USER_DATA_KEY_IMPL(FooData); |
| // |
| // Result FooProcessSelectionDeferringCondition::OnWillSelectFinalProcess() |
| // override { |
| // content::ProcessSelectionUserData& user_data = |
| // GetProcessSelectionUserData(); |
| // user_data.SetUserData(FooData::UserDataKey(), |
| // std::make_unique<FooData>(kSomeData)); |
| // return Result::kProceed; |
| // } |
| // |
| // To access the data from the process selection logic: |
| // |
| // if (url_info().process_selection_user_data) { |
| // const FooData* foo_data = |
| // FooData::FromProcessSelectionUserData( |
| // url_info().process_selection_user_data); |
| // // ... |
| // } |
| class CONTENT_EXPORT ProcessSelectionUserData : public base::SupportsUserData { |
| public: |
| ProcessSelectionUserData(); |
| ~ProcessSelectionUserData() override; |
| |
| base::SafeRef<ProcessSelectionUserData> GetSafeRef(); |
| |
| // A base class for classes attached to ProcessSelectionUserData. |
| template <typename T> |
| class Data : public base::SupportsUserData::Data { |
| public: |
| // Returns the instance of type `T` from the `data` this is provided as an |
| // argument. Returns a nullptr if no instance of `T` is found on `data`. |
| static const T* FromProcessSelectionUserData( |
| const std::optional<base::SafeRef<ProcessSelectionUserData>>& data) { |
| if (!data) { |
| return nullptr; |
| } |
| const ProcessSelectionUserData* user_data = &**data; |
| return static_cast<const T*>(user_data->GetUserData(UserDataKey())); |
| } |
| static const T* FromProcessSelectionUserData( |
| const ProcessSelectionUserData& data) { |
| return static_cast<const T*>(data.GetUserData(UserDataKey())); |
| } |
| |
| static const void* UserDataKey() { return &T::kUserDataKey; } |
| }; |
| |
| private: |
| base::WeakPtrFactory<ProcessSelectionUserData> weak_ptr_factory_{this}; |
| }; |
| |
| // Subclasses of ProcessSelectionUserData::Data call this macro in the header. |
| #define PROCESS_SELECTION_USER_DATA_KEY_DECL() static const int kUserDataKey = 0 |
| |
| // Subclasses of ProcessSelectionUserData::Data call this macro in the cc file. |
| #define PROCESS_SELECTION_USER_DATA_KEY_IMPL(Type) const int Type::kUserDataKey |
| |
| } // namespace content |
| |
| #endif // CONTENT_PUBLIC_BROWSER_PROCESS_SELECTION_USER_DATA_H_ |