1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/engagement/site_engagement_eviction_policy.h"
#include "base/command_line.h"
#include "base/metrics/field_trial.h"
#include "base/strings/string_util.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/engagement/site_engagement_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/common/chrome_switches.h"
#include "content/public/browser/browser_thread.h"
namespace {
const int kExpectedEngagementSites = 200;
// Gets the quota that an origin deserves based on its site engagement.
int64_t GetSoftQuotaForOrigin(const GURL& origin,
int score,
int total_engagement_points,
int64_t global_quota) {
double quota_per_point =
global_quota /
std::max(kExpectedEngagementSites * SiteEngagementScore::kMaxPoints,
static_cast<double>(total_engagement_points));
return score * quota_per_point;
}
GURL DoCalculateEvictionOrigin(
const scoped_refptr<storage::SpecialStoragePolicy>& special_storage_policy,
SiteEngagementScoreProvider* score_provider,
const std::set<GURL>& exceptions,
const std::map<GURL, int64_t>& usage_map,
int64_t global_quota) {
// TODO(calamity): Integrate storage access frequency as an input to this
// heuristic.
// This heuristic is intended to optimize for two criteria:
// - evict the site that the user cares about least
// - evict the least number of sites to get under the quota limit
//
// The heuristic for deciding the next eviction origin calculates a soft
// quota for each origin which is the amount the origin should be allowed to
// use based on its engagement and the global quota. The origin that most
// exceeds its soft quota is chosen.
GURL origin_to_evict;
int64_t max_overuse = std::numeric_limits<int64_t>::min();
int total_engagement_points = score_provider->GetTotalEngagementPoints();
for (const auto& usage : usage_map) {
GURL origin = usage.first;
if (special_storage_policy &&
(special_storage_policy->IsStorageUnlimited(origin) ||
special_storage_policy->IsStorageDurable(origin))) {
continue;
}
// |overuse| can be negative if the soft quota exceeds the usage.
int64_t overuse =
usage.second -
GetSoftQuotaForOrigin(origin, score_provider->GetScore(origin),
total_engagement_points, global_quota);
if (overuse > max_overuse && !ContainsKey(exceptions, origin)) {
max_overuse = overuse;
origin_to_evict = origin;
}
}
return origin_to_evict;
}
GURL GetSiteEngagementEvictionOriginOnUIThread(
const scoped_refptr<storage::SpecialStoragePolicy>& special_storage_policy,
content::BrowserContext* browser_context,
const std::set<GURL>& exceptions,
const std::map<GURL, int64_t>& usage_map,
int64_t global_quota) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
Profile* profile = Profile::FromBrowserContext(browser_context);
SiteEngagementScoreProvider* score_provider =
g_browser_process->profile_manager()->IsValidProfile(profile)
? SiteEngagementService::Get(profile)
: nullptr;
if (!score_provider)
return GURL();
return DoCalculateEvictionOrigin(special_storage_policy, score_provider,
exceptions, usage_map, global_quota);
}
} // namespace
// static
bool SiteEngagementEvictionPolicy::IsEnabled() {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableSiteEngagementEvictionPolicy)) {
return true;
}
const std::string group_name = base::FieldTrialList::FindFullName(
SiteEngagementService::kEngagementParams);
return base::StartsWith(group_name, "StorageEvictionEnabled",
base::CompareCase::SENSITIVE);
}
SiteEngagementEvictionPolicy::SiteEngagementEvictionPolicy(
content::BrowserContext* browser_context)
: browser_context_(browser_context) {}
SiteEngagementEvictionPolicy::~SiteEngagementEvictionPolicy() {}
void SiteEngagementEvictionPolicy::GetEvictionOrigin(
const scoped_refptr<storage::SpecialStoragePolicy>& special_storage_policy,
const std::set<GURL>& exceptions,
const std::map<GURL, int64_t>& usage_map,
int64_t global_quota,
const storage::GetOriginCallback& callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::UI, FROM_HERE,
base::Bind(&GetSiteEngagementEvictionOriginOnUIThread,
special_storage_policy, browser_context_, exceptions,
usage_map, global_quota),
callback);
}
// static
GURL SiteEngagementEvictionPolicy::CalculateEvictionOriginForTests(
const scoped_refptr<storage::SpecialStoragePolicy>& special_storage_policy,
SiteEngagementScoreProvider* score_provider,
const std::set<GURL>& exceptions,
const std::map<GURL, int64_t>& usage_map,
int64_t global_quota) {
return DoCalculateEvictionOrigin(special_storage_policy, score_provider,
exceptions, usage_map, global_quota);
}
|