Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(935)

Side by Side Diff: chrome/browser/extensions/extensions_quota_service.cc

Issue 10871034: Make all quota-exceeding messages in the storage API explain what the failure (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: update... the other error message Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/extensions_quota_service.h" 5 #include "chrome/browser/extensions/extensions_quota_service.h"
6 6
7 #include "base/message_loop.h" 7 #include "base/message_loop.h"
8 #include "base/stl_util.h" 8 #include "base/stl_util.h"
9 #include "chrome/browser/extensions/extension_function.h" 9 #include "chrome/browser/extensions/extension_function.h"
10 #include "chrome/common/extensions/extension_error_utils.h"
11
12 namespace {
10 13
11 // If the browser stays open long enough, we reset state once a day. 14 // If the browser stays open long enough, we reset state once a day.
12 // Whatever this value is, it should be an order of magnitude longer than 15 // Whatever this value is, it should be an order of magnitude longer than
13 // the longest interval in any of the QuotaLimitHeuristics in use. 16 // the longest interval in any of the QuotaLimitHeuristics in use.
14 static const int kPurgeIntervalInDays = 1; 17 const int kPurgeIntervalInDays = 1;
15 18
16 const char QuotaLimitHeuristic::kGenericOverQuotaError[] = 19 const char kOverQuotaError[] = "This request exceeds the * quota.";
17 "This request exceeds available quota."; 20
21 } // namespace
18 22
19 ExtensionsQuotaService::ExtensionsQuotaService() { 23 ExtensionsQuotaService::ExtensionsQuotaService() {
20 if (MessageLoop::current() != NULL) { // Null in unit tests. 24 if (MessageLoop::current() != NULL) { // Null in unit tests.
21 purge_timer_.Start(FROM_HERE, 25 purge_timer_.Start(FROM_HERE,
22 base::TimeDelta::FromDays(kPurgeIntervalInDays), 26 base::TimeDelta::FromDays(kPurgeIntervalInDays),
23 this, &ExtensionsQuotaService::Purge); 27 this, &ExtensionsQuotaService::Purge);
24 } 28 }
25 } 29 }
26 30
27 ExtensionsQuotaService::~ExtensionsQuotaService() { 31 ExtensionsQuotaService::~ExtensionsQuotaService() {
28 DCHECK(CalledOnValidThread()); 32 DCHECK(CalledOnValidThread());
29 purge_timer_.Stop(); 33 purge_timer_.Stop();
30 Purge(); 34 Purge();
31 } 35 }
32 36
33 bool ExtensionsQuotaService::Assess(const std::string& extension_id, 37 std::string ExtensionsQuotaService::Assess(
34 ExtensionFunction* function, const ListValue* args, 38 const std::string& extension_id,
39 ExtensionFunction* function,
40 const ListValue* args,
35 const base::TimeTicks& event_time) { 41 const base::TimeTicks& event_time) {
36 DCHECK(CalledOnValidThread()); 42 DCHECK(CalledOnValidThread());
37 43
38 if (function->ShouldSkipQuotaLimiting()) 44 if (function->ShouldSkipQuotaLimiting())
39 return true; 45 return "";
40 46
41 // Lookup function list for extension. 47 // Lookup function list for extension.
42 FunctionHeuristicsMap& functions = function_heuristics_[extension_id]; 48 FunctionHeuristicsMap& functions = function_heuristics_[extension_id];
43 49
44 // Lookup heuristics for function, create if necessary. 50 // Lookup heuristics for function, create if necessary.
45 QuotaLimitHeuristics& heuristics = functions[function->name()]; 51 QuotaLimitHeuristics& heuristics = functions[function->name()];
46 if (heuristics.empty()) 52 if (heuristics.empty())
47 function->GetQuotaLimitHeuristics(&heuristics); 53 function->GetQuotaLimitHeuristics(&heuristics);
48 54
49 if (heuristics.empty()) 55 if (heuristics.empty())
50 return true; // No heuristic implies no limit. 56 return ""; // No heuristic implies no limit.
51 57
52 if (violators_.find(extension_id) != violators_.end()) 58 ViolationErrorMap::iterator violation_error =
53 return false; // Repeat offender. 59 violation_errors_.find(extension_id);
60 if (violation_error != violation_errors_.end())
61 return violation_error->second; // Repeat offender.
54 62
55 bool global_decision = true; 63 QuotaLimitHeuristic* failed_heuristic = NULL;
56 for (QuotaLimitHeuristics::iterator heuristic = heuristics.begin(); 64 for (QuotaLimitHeuristics::iterator heuristic = heuristics.begin();
57 heuristic != heuristics.end(); ++heuristic) { 65 heuristic != heuristics.end(); ++heuristic) {
58 // Apply heuristic to each item (bucket). 66 // Apply heuristic to each item (bucket).
59 global_decision = (*heuristic)->ApplyToArgs(args, event_time) && 67 if (!(*heuristic)->ApplyToArgs(args, event_time)) {
60 global_decision; 68 failed_heuristic = *heuristic;
69 break;
70 }
61 } 71 }
62 72
63 if (!global_decision) { 73 if (!failed_heuristic)
64 PurgeFunctionHeuristicsMap(&functions); 74 return "";
65 function_heuristics_.erase(extension_id); 75
66 violators_.insert(extension_id); 76 std::string error = failed_heuristic->GetError();
67 } 77 DCHECK_GT(error.length(), 0u);
68 return global_decision; 78
79 PurgeFunctionHeuristicsMap(&functions);
80 function_heuristics_.erase(extension_id);
81 violation_errors_[extension_id] = error;
82 return error;
69 } 83 }
70 84
71 void ExtensionsQuotaService::PurgeFunctionHeuristicsMap( 85 void ExtensionsQuotaService::PurgeFunctionHeuristicsMap(
72 FunctionHeuristicsMap* map) { 86 FunctionHeuristicsMap* map) {
73 FunctionHeuristicsMap::iterator heuristics = map->begin(); 87 FunctionHeuristicsMap::iterator heuristics = map->begin();
74 while (heuristics != map->end()) { 88 while (heuristics != map->end()) {
75 STLDeleteElements(&heuristics->second); 89 STLDeleteElements(&heuristics->second);
76 map->erase(heuristics++); 90 map->erase(heuristics++);
77 } 91 }
78 } 92 }
(...skipping 12 matching lines...) Expand all
91 expiration_ = start + config.refill_interval; 105 expiration_ = start + config.refill_interval;
92 } 106 }
93 107
94 void QuotaLimitHeuristic::SingletonBucketMapper::GetBucketsForArgs( 108 void QuotaLimitHeuristic::SingletonBucketMapper::GetBucketsForArgs(
95 const ListValue* args, 109 const ListValue* args,
96 BucketList* buckets) { 110 BucketList* buckets) {
97 buckets->push_back(&bucket_); 111 buckets->push_back(&bucket_);
98 } 112 }
99 113
100 QuotaLimitHeuristic::QuotaLimitHeuristic(const Config& config, 114 QuotaLimitHeuristic::QuotaLimitHeuristic(const Config& config,
101 BucketMapper* map) 115 BucketMapper* map,
102 : config_(config), bucket_mapper_(map) { 116 const std::string& name)
117 : config_(config), bucket_mapper_(map), name_(name) {
103 } 118 }
104 119
105 QuotaLimitHeuristic::~QuotaLimitHeuristic() {} 120 QuotaLimitHeuristic::~QuotaLimitHeuristic() {}
106 121
107 bool QuotaLimitHeuristic::ApplyToArgs(const ListValue* args, 122 bool QuotaLimitHeuristic::ApplyToArgs(const ListValue* args,
108 const base::TimeTicks& event_time) { 123 const base::TimeTicks& event_time) {
109 BucketList buckets; 124 BucketList buckets;
110 bucket_mapper_->GetBucketsForArgs(args, &buckets); 125 bucket_mapper_->GetBucketsForArgs(args, &buckets);
111 for (BucketList::iterator i = buckets.begin(); i != buckets.end(); ++i) { 126 for (BucketList::iterator i = buckets.begin(); i != buckets.end(); ++i) {
112 if ((*i)->expiration().is_null()) // A brand new bucket. 127 if ((*i)->expiration().is_null()) // A brand new bucket.
113 (*i)->Reset(config_, event_time); 128 (*i)->Reset(config_, event_time);
114 if (!Apply(*i, event_time)) 129 if (!Apply(*i, event_time))
115 return false; // It only takes one to spoil it for everyone. 130 return false; // It only takes one to spoil it for everyone.
116 } 131 }
117 return true; 132 return true;
118 } 133 }
119 134
135 std::string QuotaLimitHeuristic::GetError() const {
136 return ExtensionErrorUtils::FormatErrorMessage(kOverQuotaError, name_);
137 }
138
120 ExtensionsQuotaService::SustainedLimit::SustainedLimit( 139 ExtensionsQuotaService::SustainedLimit::SustainedLimit(
121 const base::TimeDelta& sustain, const Config& config, BucketMapper* map) 140 const base::TimeDelta& sustain,
122 : QuotaLimitHeuristic(config, map), 141 const Config& config,
142 BucketMapper* map,
143 const std::string& name)
144 : QuotaLimitHeuristic(config, map, name),
123 repeat_exhaustion_allowance_(sustain.InSeconds() / 145 repeat_exhaustion_allowance_(sustain.InSeconds() /
124 config.refill_interval.InSeconds()), 146 config.refill_interval.InSeconds()),
125 num_available_repeat_exhaustions_(repeat_exhaustion_allowance_) { 147 num_available_repeat_exhaustions_(repeat_exhaustion_allowance_) {
126 } 148 }
127 149
128 bool ExtensionsQuotaService::TimedLimit::Apply(Bucket* bucket, 150 bool ExtensionsQuotaService::TimedLimit::Apply(Bucket* bucket,
129 const base::TimeTicks& event_time) { 151 const base::TimeTicks& event_time) {
130 if (event_time > bucket->expiration()) 152 if (event_time > bucket->expiration())
131 bucket->Reset(config(), event_time); 153 bucket->Reset(config(), event_time);
132 154
(...skipping 27 matching lines...) Expand all
160 return false; 182 return false;
161 } 183 }
162 } 184 }
163 185
164 // We can go negative since we check has_tokens when we get to *next* bucket, 186 // We can go negative since we check has_tokens when we get to *next* bucket,
165 // and for the small interval all that matters is whether we used up all the 187 // and for the small interval all that matters is whether we used up all the
166 // tokens (which is true if num_tokens_ <= 0). 188 // tokens (which is true if num_tokens_ <= 0).
167 bucket->DeductToken(); 189 bucket->DeductToken();
168 return true; 190 return true;
169 } 191 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extensions_quota_service.h ('k') | chrome/browser/extensions/extensions_quota_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698