[go: nahoru, domu]

blob: 7badfa9ef7b0709d05c6379912bda38b5cab0c9e [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
24// Skews |value| by +/- |percent|.
25int64_t RandomizeByPercent(int64_t value, int percent) {
26 double random_percent = (base::RandDouble() - 0.5) * percent * 2;
27 return value + (value * (random_percent / 100.0));
28}
29
michaeln10e5fc352017-02-07 02:07:5830base::Optional<storage::QuotaSettings> CalculateNominalDynamicSettings(
31 const base::FilePath& partition_path,
Jarryd451ab7b2019-02-12 06:39:0632 bool is_incognito,
33 QuotaDiskInfoHelper* disk_info_helper) {
Etienne Bergeron436d42212019-02-26 17:15:1234 base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
35 base::BlockingType::MAY_BLOCK);
michaeln10e5fc352017-02-07 02:07:5836 const int64_t kMBytes = 1024 * 1024;
michaelnfa4c89402017-04-11 02:36:2037 const int kRandomizedPercentage = 10;
michaeln10e5fc352017-02-07 02:07:5838
39 if (is_incognito) {
michaelnfa4c89402017-04-11 02:36:2040 // The incognito pool size is a fraction of the amount of system memory,
41 // and the amount is capped to a hard limit.
42 const double kIncognitoPoolSizeRatio = 0.1; // 10%
43 const int64_t kMaxIncognitoPoolSize = 300 * kMBytes;
44
michaeln10e5fc352017-02-07 02:07:5845 storage::QuotaSettings settings;
michaelnfa4c89402017-04-11 02:36:2046 settings.pool_size = std::min(
47 RandomizeByPercent(kMaxIncognitoPoolSize, kRandomizedPercentage),
48 static_cast<int64_t>(base::SysInfo::AmountOfPhysicalMemory() *
49 kIncognitoPoolSizeRatio));
michaeln10e5fc352017-02-07 02:07:5850 settings.per_host_quota = settings.pool_size / 3;
michaelnfa4c89402017-04-11 02:36:2051 settings.session_only_per_host_quota = settings.per_host_quota;
michaeln10e5fc352017-02-07 02:07:5852 settings.refresh_interval = base::TimeDelta::Max();
53 return settings;
54 }
55
Jarryd7a79f0662019-01-24 07:26:4456 // The fraction of the device's storage the browser is willing to
57 // use for temporary storage.
58 // Check Finch for an experimental value to use as temporary pool size ratio
59 // if experiment is enabled, otherwise fallback to ~66% for chromeOS and
60 // ~33% otherwise.
61 const double kTemporaryPoolSizeRatio =
62 features::kExperimentalPoolSizeRatio.Get();
michaeln10e5fc352017-02-07 02:07:5863
Joshua Bell1e5b5702018-02-28 06:36:2964 // The amount of the device's storage the browser attempts to
Joshua Bell9508bf4e2018-02-23 18:05:2065 // keep free. If there is less than this amount of storage free
66 // on the device, Chrome will grant 0 quota to origins.
Joshua Bell1e5b5702018-02-28 06:36:2967 //
Joshua Bell73b18e32018-05-02 23:06:2968 // Prior to M66, this was 10% of total storage instead of a fixed value on
69 // all devices. Now the minimum of a fixed value (2GB) and 10% is used to
70 // limit the reserve on devices with plenty of storage, but scale down for
71 // devices with extremely limited storage.
72 // * 1TB storage -- min(100GB,2GB) = 2GB
73 // * 500GB storage -- min(50GB,2GB) = 2GB
74 // * 64GB storage -- min(6GB,2GB) = 2GB
75 // * 16GB storage -- min(1.6GB,2GB) = 1.6GB
76 // * 8GB storage -- min(800MB,2GB) = 800MB
77 const int64_t kShouldRemainAvailableFixed = 2048 * kMBytes; // 2GB
78 const double kShouldRemainAvailableRatio = 0.1; // 10%
michaeln10e5fc352017-02-07 02:07:5879
Joshua Bell1e5b5702018-02-28 06:36:2980 // The amount of the device's storage the browser attempts to
Joshua Bell9508bf4e2018-02-23 18:05:2081 // keep free at all costs. Data will be aggressively evicted.
Joshua Bell1e5b5702018-02-28 06:36:2982 //
Joshua Bell73b18e32018-05-02 23:06:2983 // Prior to M66, this was 1% of total storage instead of a fixed value on
84 // all devices. Now the minimum of a fixed value (1GB) and 1% 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(10GB,1GB) = 1GB
88 // * 500GB storage -- min(5GB,1GB) = 1GB
89 // * 64GB storage -- min(640MB,1GB) = 640MB
90 // * 16GB storage -- min(160MB,1GB) = 160MB
91 // * 8GB storage -- min(80MB,1GB) = 80MB
92 const int64_t kMustRemainAvailableFixed = 1024 * kMBytes; // 1GB
93 const double kMustRemainAvailableRatio = 0.01; // 1%
michaeln10e5fc352017-02-07 02:07:5894
95 // Determines the portion of the temp pool that can be
96 // utilized by a single host (ie. 5 for 20%).
Jarryd7a79f0662019-01-24 07:26:4497 const double kPerHostTemporaryRatio = features::kPerHostRatio.Get();
michaeln10e5fc352017-02-07 02:07:5898
michaelnfa4c89402017-04-11 02:36:2099 // SessionOnly (or ephemeral) origins are allotted a fraction of what
100 // normal origins are provided, and the amount is capped to a hard limit.
101 const double kSessionOnlyHostQuotaRatio = 0.1; // 10%
102 const int64_t kMaxSessionOnlyHostQuota = 300 * kMBytes;
103
michaeln10e5fc352017-02-07 02:07:58104 storage::QuotaSettings settings;
105
Jarryd451ab7b2019-02-12 06:39:06106 int64_t total = disk_info_helper->AmountOfTotalDiskSpace(partition_path);
michaeln10e5fc352017-02-07 02:07:58107 if (total == -1) {
108 LOG(ERROR) << "Unable to compute QuotaSettings.";
109 return base::nullopt;
110 }
111
Joshua Bellac707732018-03-05 21:22:59112 int64_t pool_size = total * kTemporaryPoolSizeRatio;
michaeln10e5fc352017-02-07 02:07:58113
114 settings.pool_size = pool_size;
Joshua Bell73b18e32018-05-02 23:06:29115 settings.should_remain_available =
116 std::min(kShouldRemainAvailableFixed,
117 static_cast<int64_t>(total * kShouldRemainAvailableRatio));
118 settings.must_remain_available =
119 std::min(kMustRemainAvailableFixed,
120 static_cast<int64_t>(total * kMustRemainAvailableRatio));
Jarryd7a79f0662019-01-24 07:26:44121 settings.per_host_quota = pool_size * kPerHostTemporaryRatio;
michaelnfa4c89402017-04-11 02:36:20122 settings.session_only_per_host_quota = std::min(
123 RandomizeByPercent(kMaxSessionOnlyHostQuota, kRandomizedPercentage),
124 static_cast<int64_t>(settings.per_host_quota *
125 kSessionOnlyHostQuotaRatio));
michaeln10e5fc352017-02-07 02:07:58126 settings.refresh_interval = base::TimeDelta::FromSeconds(60);
127 return settings;
128}
129
130} // namespace
taptede6d878e2017-06-24 01:53:45131
132void GetNominalDynamicSettings(const base::FilePath& partition_path,
133 bool is_incognito,
Jarryd451ab7b2019-02-12 06:39:06134 QuotaDiskInfoHelper* disk_info_helper,
taptede6d878e2017-06-24 01:53:45135 OptionalQuotaSettingsCallback callback) {
136 base::PostTaskWithTraitsAndReplyWithResult(
137 FROM_HERE,
Gabriel Charetteb10aeeb2018-07-26 20:15:00138 {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
taptede6d878e2017-06-24 01:53:45139 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
140 base::BindOnce(&CalculateNominalDynamicSettings, partition_path,
Jarryd451ab7b2019-02-12 06:39:06141 is_incognito, base::Unretained(disk_info_helper)),
taptede6d878e2017-06-24 01:53:45142 std::move(callback));
143}
144
Jarryd451ab7b2019-02-12 06:39:06145QuotaDiskInfoHelper* GetDefaultDiskInfoHelper() {
146 static base::NoDestructor<QuotaDiskInfoHelper> singleton;
147 return singleton.get();
148}
149
taptede6d878e2017-06-24 01:53:45150} // namespace storage