[go: nahoru, domu]

blob: b2210b55b40f4d49c6e592c023c1bbaf318b19b5 [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"
Jarryd1f02b902019-11-07 03:29:5716#include "storage/browser/quota/quota_device_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.
Jarryd50d305f7b2019-11-09 01:21:3537 double incognito_pool_size_ratio = 0.1; // 10%
38 int64_t max_incognito_pool_size = 300 * kMBytes;
Ramin Halavati57e618932019-10-31 12:46:4739 if (base::FeatureList::IsEnabled(features::kIncognitoDynamicQuota)) {
40 const double lower_bound = features::kIncognitoQuotaRatioLowerBound.Get();
41 const double upper_bound = features::kIncognitoQuotaRatioUpperBound.Get();
Jarryd50d305f7b2019-11-09 01:21:3542 incognito_pool_size_ratio =
Ramin Halavati57e618932019-10-31 12:46:4743 lower_bound + (base::RandDouble() * (upper_bound - lower_bound));
Jarryd50d305f7b2019-11-09 01:21:3544 max_incognito_pool_size = std::numeric_limits<int64_t>::max();
Ramin Halavati57e618932019-10-31 12:46:4745 } else {
Jarryd50d305f7b2019-11-09 01:21:3546 max_incognito_pool_size =
47 RandomizeByPercent(max_incognito_pool_size, kRandomizedPercentage);
Ramin Halavati57e618932019-10-31 12:46:4748 }
49
50 storage::QuotaSettings settings;
51 settings.pool_size = std::min(
Jarryd50d305f7b2019-11-09 01:21:3552 max_incognito_pool_size,
53 static_cast<int64_t>(physical_memory_amount * incognito_pool_size_ratio));
Ramin Halavati57e618932019-10-31 12:46:4754 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,
Jarryd1f02b902019-11-07 03:29:5763 QuotaDeviceInfoHelper* device_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(
Jarryd1f02b902019-11-07 03:29:5769 device_info_helper->AmountOfPhysicalMemory());
michaeln10e5fc352017-02-07 02:07:5870 }
71
Victor Costanf39940a2019-12-02 19:37:2972 // The fraction of the device's storage the browser is willing to use for
73 // temporary storage.
Jarryd7a79f0662019-01-24 07:26:4474 const double kTemporaryPoolSizeRatio =
Jarryd1cc73272019-07-22 18:31:3775 base::FeatureList::IsEnabled(features::kQuotaUnlimitedPoolSize)
76 ? 1.0
77 : features::kExperimentalPoolSizeRatio.Get();
michaeln10e5fc352017-02-07 02:07:5878
Joshua Bell1e5b5702018-02-28 06:36:2979 // The amount of the device's storage the browser attempts to
Joshua Bell9508bf4e2018-02-23 18:05:2080 // keep free. If there is less than this amount of storage free
81 // on the device, Chrome will grant 0 quota to origins.
Joshua Bell1e5b5702018-02-28 06:36:2982 //
Joshua Bell73b18e32018-05-02 23:06:2983 // Prior to M66, this was 10% of total storage instead of a fixed value on
84 // all devices. Now the minimum of a fixed value (2GB) and 10% is used to
85 // limit the reserve on devices with plenty of storage, but scale down for
86 // devices with extremely limited storage.
87 // * 1TB storage -- min(100GB,2GB) = 2GB
88 // * 500GB storage -- min(50GB,2GB) = 2GB
89 // * 64GB storage -- min(6GB,2GB) = 2GB
90 // * 16GB storage -- min(1.6GB,2GB) = 1.6GB
91 // * 8GB storage -- min(800MB,2GB) = 800MB
92 const int64_t kShouldRemainAvailableFixed = 2048 * kMBytes; // 2GB
93 const double kShouldRemainAvailableRatio = 0.1; // 10%
michaeln10e5fc352017-02-07 02:07:5894
Joshua Bell1e5b5702018-02-28 06:36:2995 // The amount of the device's storage the browser attempts to
Joshua Bell9508bf4e2018-02-23 18:05:2096 // keep free at all costs. Data will be aggressively evicted.
Joshua Bell1e5b5702018-02-28 06:36:2997 //
Joshua Bell73b18e32018-05-02 23:06:2998 // Prior to M66, this was 1% of total storage instead of a fixed value on
99 // all devices. Now the minimum of a fixed value (1GB) and 1% is used to
100 // limit the reserve on devices with plenty of storage, but scale down for
101 // devices with extremely limited storage.
102 // * 1TB storage -- min(10GB,1GB) = 1GB
103 // * 500GB storage -- min(5GB,1GB) = 1GB
104 // * 64GB storage -- min(640MB,1GB) = 640MB
105 // * 16GB storage -- min(160MB,1GB) = 160MB
106 // * 8GB storage -- min(80MB,1GB) = 80MB
107 const int64_t kMustRemainAvailableFixed = 1024 * kMBytes; // 1GB
108 const double kMustRemainAvailableRatio = 0.01; // 1%
michaeln10e5fc352017-02-07 02:07:58109
Victor Costanf39940a2019-12-02 19:37:29110 // The fraction of the temporary pool that can be utilized by a single host.
Jarryd1cc73272019-07-22 18:31:37111 const double kPerHostTemporaryRatio =
112 base::FeatureList::IsEnabled(features::kQuotaUnlimitedPoolSize)
113 ? 1.0
114 : features::kPerHostRatio.Get();
michaeln10e5fc352017-02-07 02:07:58115
michaelnfa4c89402017-04-11 02:36:20116 // SessionOnly (or ephemeral) origins are allotted a fraction of what
117 // normal origins are provided, and the amount is capped to a hard limit.
118 const double kSessionOnlyHostQuotaRatio = 0.1; // 10%
119 const int64_t kMaxSessionOnlyHostQuota = 300 * kMBytes;
120
michaeln10e5fc352017-02-07 02:07:58121 storage::QuotaSettings settings;
122
Jarryd1f02b902019-11-07 03:29:57123 int64_t total = device_info_helper->AmountOfTotalDiskSpace(partition_path);
michaeln10e5fc352017-02-07 02:07:58124 if (total == -1) {
125 LOG(ERROR) << "Unable to compute QuotaSettings.";
126 return base::nullopt;
127 }
128
Joshua Bellac707732018-03-05 21:22:59129 int64_t pool_size = total * kTemporaryPoolSizeRatio;
michaeln10e5fc352017-02-07 02:07:58130
131 settings.pool_size = pool_size;
Joshua Bell73b18e32018-05-02 23:06:29132 settings.should_remain_available =
133 std::min(kShouldRemainAvailableFixed,
134 static_cast<int64_t>(total * kShouldRemainAvailableRatio));
135 settings.must_remain_available =
136 std::min(kMustRemainAvailableFixed,
137 static_cast<int64_t>(total * kMustRemainAvailableRatio));
Jarryd7a79f0662019-01-24 07:26:44138 settings.per_host_quota = pool_size * kPerHostTemporaryRatio;
michaelnfa4c89402017-04-11 02:36:20139 settings.session_only_per_host_quota = std::min(
140 RandomizeByPercent(kMaxSessionOnlyHostQuota, kRandomizedPercentage),
141 static_cast<int64_t>(settings.per_host_quota *
142 kSessionOnlyHostQuotaRatio));
michaeln10e5fc352017-02-07 02:07:58143 settings.refresh_interval = base::TimeDelta::FromSeconds(60);
144 return settings;
145}
146
147} // namespace
taptede6d878e2017-06-24 01:53:45148
149void GetNominalDynamicSettings(const base::FilePath& partition_path,
150 bool is_incognito,
Jarryd1f02b902019-11-07 03:29:57151 QuotaDeviceInfoHelper* device_info_helper,
taptede6d878e2017-06-24 01:53:45152 OptionalQuotaSettingsCallback callback) {
Sami Kyostilad5265e92019-07-31 19:59:45153 base::PostTaskAndReplyWithResult(
taptede6d878e2017-06-24 01:53:45154 FROM_HERE,
Ben Kelly8980b4e2019-09-23 20:46:29155 {base::ThreadPool(), base::MayBlock(), base::TaskPriority::USER_VISIBLE,
taptede6d878e2017-06-24 01:53:45156 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
157 base::BindOnce(&CalculateNominalDynamicSettings, partition_path,
Jarryd1f02b902019-11-07 03:29:57158 is_incognito, base::Unretained(device_info_helper)),
taptede6d878e2017-06-24 01:53:45159 std::move(callback));
160}
161
Jarryd1f02b902019-11-07 03:29:57162QuotaDeviceInfoHelper* GetDefaultDeviceInfoHelper() {
163 static base::NoDestructor<QuotaDeviceInfoHelper> singleton;
Jarryd451ab7b2019-02-12 06:39:06164 return singleton.get();
165}
166
taptede6d878e2017-06-24 01:53:45167} // namespace storage