blob: da70e39764abc3cd5adf8bb100f579dac582f400 [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_TABS_TAB_MODEL_H_
#define CHROME_BROWSER_UI_TABS_TAB_MODEL_H_
#include <memory>
#include <optional>
#include "base/memory/raw_ptr.h"
#include "base/observer_list.h"
#include "chrome/browser/ui/tabs/supports_handles.h"
#include "chrome/browser/ui/tabs/tab_model_observer.h"
#include "components/tab_groups/tab_group_id.h"
#include "content/public/browser/web_contents.h"
#include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"
class TabStripModel;
namespace tabs {
class TabCollection;
class TabFeatures;
class TabModel final : public SupportsHandles<const TabModel> {
public:
TabModel(std::unique_ptr<content::WebContents> contents,
TabStripModel* owning_model);
~TabModel() override;
TabModel(const TabModel&) = delete;
TabModel& operator=(const TabModel&) = delete;
void OnAddedToModel(TabStripModel* owning_model);
void OnRemovedFromModel();
void AddObserver(TabModelObserver* obs) { observers_.AddObserver(obs); }
void RemoveObserver(TabModelObserver* obs) { observers_.RemoveObserver(obs); }
content::WebContents* contents() const { return contents_.get(); }
TabStripModel* owning_model() const { return owning_model_.get(); }
content::WebContents* opener() const { return opener_; }
bool reset_opener_on_active_tab_change() const {
return reset_opener_on_active_tab_change_;
}
bool pinned() const { return pinned_; }
bool blocked() const { return blocked_; }
std::optional<tab_groups::TabGroupId> group() const { return group_; }
void set_opener(content::WebContents* opener) { opener_ = opener; }
void set_reset_opener_on_active_tab_change(
bool reset_opener_on_active_tab_change) {
reset_opener_on_active_tab_change_ = reset_opener_on_active_tab_change;
}
void set_pinned(bool pinned) { pinned_ = pinned; }
void set_blocked(bool blocked) { blocked_ = blocked; }
void set_group(std::optional<tab_groups::TabGroupId> group) {
group_ = group;
}
void WriteIntoTrace(perfetto::TracedValue context) const;
// https://crbug.com/331022416: Do not use this method. The signature of this
// method suggests that it's possible to replace the WebContents that
// represents a live, foregrounded tab with a different WebContents. This is
// never the case. Instead use RemoveContents() and AddContents().
std::unique_ptr<content::WebContents> ReplaceContents(
std::unique_ptr<content::WebContents> contents);
std::unique_ptr<content::WebContents> RemoveContents();
// The current contents of the tab must be |nullptr|.
void SetContents(std::unique_ptr<content::WebContents> contents);
TabFeatures* tab_features() { return tab_features_.get(); }
// Returns a pointer to the parent TabCollection. This method is specifically
// designed to be accessible only within the collection tree that has the
// kTabStripCollectionStorage flag enabled.
TabCollection* GetParentCollection(base::PassKey<TabCollection>) const;
// Provides access to the parent_collection_ for testing purposes. This method
// bypasses the PassKey mechanism, allowing tests to simulate scenarios and
// inspect the state without needing to replicate complex authorization
// mechanisms.
TabCollection* GetParentCollectionForTesting() { return parent_collection_; }
// Updates the parent collection of the TabModel in response to structural
// changes such as pinning, grouping, or moving the tab between collections.
// This method ensures the TabModel remains correctly associated within the
// tab hierarchy, maintaining consistent organization.
void OnReparented(TabCollection* parent, base::PassKey<TabCollection>);
private:
std::unique_ptr<content::WebContents> contents_;
// A back reference to the TabStripModel that contains this TabModel. The
// owning model can be nullptr if the tab has been detached from it's previous
// owning tabstrip model, and has yet to be transferred to a new tabstrip
// model or is in the process of being closed.
raw_ptr<TabStripModel> owning_model_;
raw_ptr<content::WebContents> opener_ = nullptr;
bool reset_opener_on_active_tab_change_ = false;
bool pinned_ = false;
bool blocked_ = false;
std::optional<tab_groups::TabGroupId> group_ = std::nullopt;
raw_ptr<TabCollection> parent_collection_ = nullptr;
base::ObserverList<TabModelObserver> observers_;
// Features that are per-tab will be owned by this class.
std::unique_ptr<TabFeatures> tab_features_;
};
using TabHandle = TabModel::Handle;
} // namespace tabs
#endif // CHROME_BROWSER_UI_TABS_TAB_MODEL_H_