#ifndef COMPONENTS_CONTENT_SETTINGS_BROWSER_UI_COOKIE_CONTROLS_CONTROLLER_H_
#define COMPONENTS_CONTENT_SETTINGS_BROWSER_UI_COOKIE_CONTROLS_CONTROLLER_H_
#include <set>
#include "base/containers/lru_cache.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/scoped_observation.h"
#include "base/timer/timer.h"
#include "components/content_settings/browser/page_specific_content_settings.h"
#include "components/content_settings/core/browser/cookie_settings.h"
#include "components/content_settings/core/common/cookie_blocking_3pcd_status.h"
#include "components/content_settings/core/common/cookie_controls_enforcement.h"
#include "components/content_settings/core/common/cookie_controls_state.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/privacy_sandbox/tracking_protection_settings.h"
#include "content/public/browser/web_contents_observer.h"
namespace content {
class WebContents;
}
namespace content_settings {
class CookieSettings;
class CookieControlsObserver;
class CookieControlsController final
: content_settings::CookieSettings::Observer {
public:
CookieControlsController(
scoped_refptr<content_settings::CookieSettings> cookie_settings,
scoped_refptr<content_settings::CookieSettings> original_cookie_settings,
HostContentSettingsMap* settings_map,
privacy_sandbox::TrackingProtectionSettings* tracking_protection_settings,
bool is_incognito_profile);
CookieControlsController(const CookieControlsController& other) = delete;
CookieControlsController& operator=(const CookieControlsController& other) =
delete;
~CookieControlsController() override;
void Update(content::WebContents* web_contents);
void UpdateUserBypass();
void OnUiClosing();
void OnBubbleCloseTriggered();
void OnCookieBlockingEnabledForSite(bool block_third_party_cookies);
void OnTrackingProtectionsChangedForSite();
void OnEntryPointAnimated();
bool StateChangedViaBypass();
void SetStateChangedViaBypass(bool changed);
void AddObserver(CookieControlsObserver* obs);
void RemoveObserver(CookieControlsObserver* obs);
base::WeakPtr<CookieControlsController> AsWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
private:
struct Status {
Status(CookieControlsState controls_state,
CookieControlsEnforcement enforcement,
CookieBlocking3pcdStatus blocking_status,
base::Time expiration);
~Status();
CookieControlsState controls_state;
CookieControlsEnforcement enforcement;
CookieBlocking3pcdStatus blocking_status;
base::Time expiration;
};
class TabObserver
: public content_settings::PageSpecificContentSettings::SiteDataObserver,
public content::WebContentsObserver {
public:
TabObserver(CookieControlsController* cookie_controls,
content::WebContents* web_contents);
TabObserver(const TabObserver&) = delete;
TabObserver& operator=(const TabObserver&) = delete;
~TabObserver() override;
void OnSiteDataAccessed(const AccessDetails& access_details) override;
void OnStatefulBounceDetected() override;
void PrimaryPageChanged(content::Page& page) override;
void DidStopLoading() override;
void BeforeFormRepostWarningShow() override;
private:
raw_ptr<CookieControlsController> cookie_controls_;
base::RepeatingTimer timer_;
GURL last_visited_url_;
int reload_count_ = 0;
base::LRUCacheSet<AccessDetails> cookie_accessed_set_;
void ResetReloadCounter();
};
void OnThirdPartyCookieBlockingChanged(
bool block_third_party_cookies) override;
void OnCookieSettingChanged() override;
Status GetStatus(content::WebContents* web_contents);
CookieControlsEnforcement GetEnforcementForThirdPartyCookieBlocking(
CookieBlocking3pcdStatus status,
const GURL url,
const SettingInfo& info,
bool cookies_allowed);
bool HasOriginSandboxedTopLevelDocument() const;
void UpdateLastVisitedSitesMap();
void UpdatePageReloadStatus(int recent_reloads_count);
void OnPageFinishedLoading();
int GetStatefulBounceCount() const;
int GetAllowedThirdPartyCookiesSitesCount() const;
int GetBlockedThirdPartyCookiesSitesCount() const;
double GetSiteEngagementScore();
void RecordActivationMetrics();
bool SiteDataAccessed(int third_party_allowed_sites,
int third_party_blocked_sites);
bool ShouldHighlightUserBypass(CookieControlsState controls_state);
bool ShouldUserBypassIconBeVisible(CookieControlsState controls_state);
bool SiteDataAccessAttempted();
content::WebContents* GetWebContents() const;
std::unique_ptr<TabObserver> tab_observer_;
scoped_refptr<content_settings::CookieSettings> cookie_settings_;
scoped_refptr<content_settings::CookieSettings> original_cookie_settings_;
raw_ptr<HostContentSettingsMap> settings_map_;
raw_ptr<privacy_sandbox::TrackingProtectionSettings>
tracking_protection_settings_;
base::ScopedObservation<content_settings::CookieSettings,
content_settings::CookieSettings::Observer>
cookie_observation_{this};
bool should_reload_ = false;
bool user_changed_ub_state_ = false;
int recent_reloads_count_ = 0;
bool has_exception_expired_since_last_visit_ = false;
bool waiting_for_page_load_finish_ = false;
bool show_icon_as_confirmation_ = false;
base::ObserverList<CookieControlsObserver> observers_;
base::WeakPtrFactory<CookieControlsController> weak_ptr_factory_{this};
};
}
#endif