blob: ec5a6917faeed4f577c72ebf5c81a13c4f151d60 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_PERMISSIONS_UNUSED_SITE_PERMISSIONS_SERVICE_H_
#define COMPONENTS_PERMISSIONS_UNUSED_SITE_PERMISSIONS_SERVICE_H_
#include <list>
#include <map>
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/clock.h"
#include "base/timer/timer.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/content_settings/core/common/content_settings_pattern.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/keyed_service/core/keyed_service.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
class HostContentSettingsMap;
namespace url {
class Origin;
}
namespace content {
class Page;
} // namespace content
namespace permissions {
// This task keeps track of unused permissions, updates their last_visit date
// on navigations and clears them periodically.
class UnusedSitePermissionsService
: public KeyedService,
public base::SupportsWeakPtr<UnusedSitePermissionsService> {
public:
struct ContentSettingEntry {
ContentSettingsType type;
ContentSettingPatternSource source;
};
class TabHelper : public content::WebContentsObserver,
public content::WebContentsUserData<TabHelper> {
public:
TabHelper(const TabHelper&) = delete;
TabHelper& operator=(const TabHelper&) = delete;
~TabHelper() override;
// WebContentsObserver:
void PrimaryPageChanged(content::Page& page) override;
private:
explicit TabHelper(
content::WebContents* web_contents,
UnusedSitePermissionsService* unused_site_permission_service);
base::WeakPtr<UnusedSitePermissionsService> unused_site_permission_service_;
friend class content::WebContentsUserData<TabHelper>;
WEB_CONTENTS_USER_DATA_KEY_DECL();
};
explicit UnusedSitePermissionsService(HostContentSettingsMap* hcsm);
UnusedSitePermissionsService(const UnusedSitePermissionsService&) = delete;
UnusedSitePermissionsService& operator=(const UnusedSitePermissionsService&) =
delete;
~UnusedSitePermissionsService() override;
// KeyedService implementation.
void Shutdown() override;
// If the user clicked "Allow again" for an auto-revoked origin, the
// permissions for that site should not be auto-revoked again by the service.
void IgnoreOriginForAutoRevocation(const url::Origin& origin);
// Triggers an update of the unused permission map. Automatically registers
// a delayed task for another update after 24h.
void StartRepeatedUpdates();
// Re-grants permissions that are auto-revoked ones and removes the origin
// from revoked permissions list.
void RegrantPermissionsForOrigin(const url::Origin& origin);
// Reverse changes made by |RegrantPermissionsForOrigin|. Adds this origin to
// the removed permissions list and resets its permissions.
void UndoRegrantPermissionsForOrigin(
const std::set<ContentSettingsType> permissions,
const absl::optional<content_settings::ContentSettingConstraints>
constraint,
const url::Origin origin);
// Clear the list of revoked permissions so they will no longer be shown to
// the user. Does not change permissions themselves.
void ClearRevokedPermissionsList();
// Stores revoked permissions data on HCSM.
void StorePermissionInRevokedPermissionSetting(
const std::set<ContentSettingsType> permissions,
const absl::optional<content_settings::ContentSettingConstraints>
constraint,
const url::Origin origin);
// Test support:
void SetClockForTesting(base::Clock* clock);
std::vector<ContentSettingEntry> GetTrackedUnusedPermissionsForTesting();
void UpdateUnusedPermissionsForTesting();
using UnusedPermissionMap =
std::map<std::string, std::list<ContentSettingEntry>>;
private:
// Called by TabHelper when a URL was visited.
void OnPageVisited(const url::Origin& origin);
// Called on UI thread
void UpdateUnusedPermissionsAsync(base::RepeatingClosure callback);
// Called on UI thread.
void OnUnusedPermissionsMapRetrieved(base::OnceClosure callback,
UnusedPermissionMap map);
// Revokes permissions that belong to sites that were last visited over 60
// days ago.
void RevokeUnusedPermissions();
// Stores revoked permissions data on HCSM.
void StorePermissionInRevokedPermissionSetting(
const std::set<ContentSettingsType> permissions,
const absl::optional<content_settings::ContentSettingConstraints>
constraint,
const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern);
// Set of permissions that haven't been used for at least a week.
UnusedPermissionMap recently_unused_permissions_;
// Repeating timer that updates the recently_unused_permissions_ map.
base::RepeatingTimer update_timer_;
const scoped_refptr<HostContentSettingsMap> hcsm_;
raw_ptr<base::Clock> clock_;
};
} // namespace permissions
#endif // COMPONENTS_PERMISSIONS_UNUSED_SITE_PERMISSIONS_SERVICE_H_