[go: nahoru, domu]

blob: d4b51ae0f2f6ab26851b65ccd91569fdf6d8e0e8 [file] [log] [blame]
michaeln10e5fc352017-02-07 02:07:581// Copyright 2016 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "storage/browser/quota/quota_settings.h"
6
7#include <algorithm>
Jarryd451ab7b2019-02-12 06:39:068#include <memory>
michaeln10e5fc352017-02-07 02:07:589
Sebastien Marchand6d0558fd2019-01-25 16:49:3710#include "base/bind.h"
michaelnfa4c89402017-04-11 02:36:2011#include "base/rand_util.h"
Sebastien Marchand75a7cdf2018-11-13 23:47:0312#include "base/system/sys_info.h"
Gabriel Charette44db1422018-08-06 11:19:3313#include "base/task/post_task.h"
Etienne Pierre-Doray57cf4702018-11-16 17:04:1414#include "base/threading/scoped_blocking_call.h"
Kevin Marshallf1bf4e52017-08-15 19:37:5815#include "build/build_config.h"
Jarryd451ab7b2019-02-12 06:39:0616#include "storage/browser/quota/quota_disk_info_helper.h"
Jarryd7a79f0662019-01-24 07:26:4417#include "storage/browser/quota/quota_features.h"
Oscar Johansson357dd5c2018-08-07 10:42:0218#include "storage/browser/quota/quota_macros.h"
michaeln10e5fc352017-02-07 02:07:5819
20namespace storage {
21
michaelnfa4c89402017-04-11 02:36:2022namespace {
23
Ramin Halavati57e618932019-10-31 12:46:4724const int64_t kMBytes = 1024 * 1024;
25const int kRandomizedPercentage = 10;
26
michaelnfa4c89402017-04-11 02:36:2027// Skews |value| by +/- |percent|.
28int64_t RandomizeByPercent(int64_t value, int percent) {
29 double random_percent = (base::RandDouble() - 0.5) * percent * 2;
30 return value + (value * (random_percent / 100.0));
31}
32
Ramin Halavati57e618932019-10-31 12:46:4733storage::QuotaSettings CalculateIncognitoDynamicSettings(
34 int64_t physical_memory_amount) {
35 // The incognito pool size is a fraction of the amount of system memory,
36 // and the amount is capped to a hard limit.
37 double kIncognitoPoolSizeRatio = 0.1; // 10%
38 int64_t kMaxIncognitoPoolSize = 300 * kMBytes;
39 if (base::FeatureList::IsEnabled(features::kIncognitoDynamicQuota)) {
40 const double lower_bound = features::kIncognitoQuotaRatioLowerBound.Get();
41 const double upper_bound = features::kIncognitoQuotaRatioUpperBound.Get();
42 kIncognitoPoolSizeRatio =
43 lower_bound + (base::RandDouble() * (upper_bound - lower_bound));
44 kMaxIncognitoPoolSize = std::numeric_limits<int64_t>::max();
45 } else {
46 kMaxIncognitoPoolSize =
47 RandomizeByPercent(kMaxIncognitoPoolSize, kRandomizedPercentage);
48 }
49
50 storage::QuotaSettings settings;
51 settings.pool_size = std::min(
52 kMaxIncognitoPoolSize,
53 static_cast<int64_t>(physical_memory_amount * kIncognitoPoolSizeRatio));
54 settings.per_host_quota = settings.pool_size / 3;
55 settings.session_only_per_host_quota = settings.per_host_quota;
56 settings.refresh_interval = base::TimeDelta::Max();
57 return settings;
58}
59
michaeln10e5fc352017-02-07 02:07:5860base::Optional<storage::QuotaSettings> CalculateNominalDynamicSettings(
61 const base::FilePath& partition_path,
Jarryd451ab7b2019-02-12 06:39:0662 bool is_incognito,
63 QuotaDiskInfoHelper* disk_info_helper) {
Etienne Bergeron436d42212019-02-26 17:15:1264 base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
65 base::BlockingType::MAY_BLOCK);
michaeln10e5fc352017-02-07 02:07:5866
67 if (is_incognito) {
Ramin Halavati57e618932019-10-31 12:46:4768 return CalculateIncognitoDynamicSettings(
69 base::SysInfo::AmountOfPhysicalMemory());
michaeln10e5fc352017-02-07 02:07:5870 }
71
Jarryd7a79f0662019-01-24 07:26:4472 // The fraction of the device's storage the browser is willing to
73 // use for temporary storage.
74 // Check Finch for an experimental value to use as temporary pool size ratio
75 // if experiment is enabled, otherwise fallback to ~66% for chromeOS and
76 // ~33% otherwise.
77 const double kTemporaryPoolSizeRatio =
Jarryd1cc73272019-07-22 18:31:3778 base::FeatureList::IsEnabled(features::kQuotaUnlimitedPoolSize)
79 ? 1.0
80 : features::kExperimentalPoolSizeRatio.Get();
michaeln10e5fc352017-02-07 02:07:5881
Joshua Bell1e5b5702018-02-28 06:36:2982 // The amount of the device's storage the browser attempts to
Joshua Bell9508bf4e2018-02-23 18:05:2083 // keep free. If there is less than this amount of storage free
84 // on the device, Chrome will grant 0 quota to origins.
Joshua Bell1e5b5702018-02-28 06:36:2985 //
Joshua Bell73b18e32018-05-02 23:06:2986 // Prior to M66, this was 10% of total storage instead of a fixed value on
87 // all devices. Now the minimum of a fixed value (2GB) and 10% is used to
88 // limit the reserve on devices with plenty of storage, but scale down for
89 // devices with extremely limited storage.
90 // * 1TB storage -- min(100GB,2GB) = 2GB
91 // * 500GB storage -- min(50GB,2GB) = 2GB
92 // * 64GB storage -- min(6GB,2GB) = 2GB
93 // * 16GB storage -- min(1.6GB,2GB) = 1.6GB
94 // * 8GB storage -- min(800MB,2GB) = 800MB
95 const int64_t kShouldRemainAvailableFixed = 2048 * kMBytes; // 2GB
96 const double kShouldRemainAvailableRatio = 0.1; // 10%
michaeln10e5fc352017-02-07 02:07:5897
Joshua Bell1e5b5702018-02-28 06:36:2998 // The amount of the device's storage the browser attempts to
Joshua Bell9508bf4e2018-02-23 18:05:2099 // keep free at all costs. Data will be aggressively evicted.
Joshua Bell1e5b5702018-02-28 06:36:29100 //
Joshua Bell73b18e32018-05-02 23:06:29101 // Prior to M66, this was 1% of total storage instead of a fixed value on
102 // all devices. Now the minimum of a fixed value (1GB) and 1% is used to
103 // limit the reserve on devices with plenty of storage, but scale down for
104 // devices with extremely limited storage.
105 // * 1TB storage -- min(10GB,1GB) = 1GB
106 // * 500GB storage -- min(5GB,1GB) = 1GB
107 // * 64GB storage -- min(640MB,1GB) = 640MB
108 // * 16GB storage -- min(160MB,1GB) = 160MB
109 // * 8GB storage -- min(80MB,1GB) = 80MB
110 const int64_t kMustRemainAvailableFixed = 1024 * kMBytes; // 1GB
111 const double kMustRemainAvailableRatio = 0.01; // 1%
michaeln10e5fc352017-02-07 02:07:58112
113 // Determines the portion of the temp pool that can be
114 // utilized by a single host (ie. 5 for 20%).
Jarryd1cc73272019-07-22 18:31:37115 const double kPerHostTemporaryRatio =
116 base::FeatureList::IsEnabled(features::kQuotaUnlimitedPoolSize)
117 ? 1.0
118 : features::kPerHostRatio.Get();
michaeln10e5fc352017-02-07 02:07:58119
michaelnfa4c89402017-04-11 02:36:20120 // SessionOnly (or ephemeral) origins are allotted a fraction of what
121 // normal origins are provided, and the amount is capped to a hard limit.
122 const double kSessionOnlyHostQuotaRatio = 0.1; // 10%
123 const int64_t kMaxSessionOnlyHostQuota = 300 * kMBytes;
124
michaeln10e5fc352017-02-07 02:07:58125 storage::QuotaSettings settings;
126
Jarryd451ab7b2019-02-12 06:39:06127 int64_t total = disk_info_helper->AmountOfTotalDiskSpace(partition_path);
michaeln10e5fc352017-02-07 02:07:58128 if (total == -1) {
129 LOG(ERROR) << "Unable to compute QuotaSettings.";
130 return base::nullopt;
131 }
132
Joshua Bellac707732018-03-05 21:22:59133 int64_t pool_size = total * kTemporaryPoolSizeRatio;
michaeln10e5fc352017-02-07 02:07:58134
135 settings.pool_size = pool_size;
Joshua Bell73b18e32018-05-02 23:06:29136 settings.should_remain_available =
137 std::min(kShouldRemainAvailableFixed,
138 static_cast<int64_t>(total * kShouldRemainAvailableRatio));
139 settings.must_remain_available =
140 std::min(kMustRemainAvailableFixed,
141 static_cast<int64_t>(total * kMustRemainAvailableRatio));
Jarryd7a79f0662019-01-24 07:26:44142 settings.per_host_quota = pool_size * kPerHostTemporaryRatio;
michaelnfa4c89402017-04-11 02:36:20143 settings.session_only_per_host_quota = std::min(
144 RandomizeByPercent(kMaxSessionOnlyHostQuota, kRandomizedPercentage),
145 static_cast<int64_t>(settings.per_host_quota *
146 kSessionOnlyHostQuotaRatio));
michaeln10e5fc352017-02-07 02:07:58147 settings.refresh_interval = base::TimeDelta::FromSeconds(60);
148 return settings;
149}
150
151} // namespace
taptede6d878e2017-06-24 01:53:45152
Ramin Halavati57e618932019-10-31 12:46:47153int64_t GetIncognitoPoolSizeForTesting(int64_t physical_memory_amount) {
154 return CalculateIncognitoDynamicSettings(physical_memory_amount).pool_size;
155}
156
taptede6d878e2017-06-24 01:53:45157void GetNominalDynamicSettings(const base::FilePath& partition_path,
158 bool is_incognito,
Jarryd451ab7b2019-02-12 06:39:06159 QuotaDiskInfoHelper* disk_info_helper,
taptede6d878e2017-06-24 01:53:45160 OptionalQuotaSettingsCallback callback) {
Sami Kyostilad5265e92019-07-31 19:59:45161 base::PostTaskAndReplyWithResult(
taptede6d878e2017-06-24 01:53:45162 FROM_HERE,
Ben Kelly8980b4e2019-09-23 20:46:29163 {base::ThreadPool(), base::MayBlock(), base::TaskPriority::USER_VISIBLE,
taptede6d878e2017-06-24 01:53:45164 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
165 base::BindOnce(&CalculateNominalDynamicSettings, partition_path,
Jarryd451ab7b2019-02-12 06:39:06166 is_incognito, base::Unretained(disk_info_helper)),
taptede6d878e2017-06-24 01:53:45167 std::move(callback));
168}
169
Jarryd451ab7b2019-02-12 06:39:06170QuotaDiskInfoHelper* GetDefaultDiskInfoHelper() {
171 static base::NoDestructor<QuotaDiskInfoHelper> singleton;
172 return singleton.get();
173}
174
taptede6d878e2017-06-24 01:53:45175} // namespace storage