Commit 9e89338a authored by kalman@chromium.org's avatar kalman@chromium.org

Extension Settings API: throttle the API in the same way that the Bookmarks API

is throttled.


BUG=98498
TEST=*ExtensionSettings*


Review URL: http://codereview.chromium.org/8491033

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110854 0039d316-1c4b-4281-b951-d872f2087c98
parent 454a0c41
......@@ -152,7 +152,7 @@ class RemoveBookmarkFunction : public BookmarksFunction {
// BookmarksFunction:
virtual bool RunImpl() OVERRIDE;
virtual void GetQuotaLimitHeuristics(
std::list<QuotaLimitHeuristic*>* heuristics) const;
QuotaLimitHeuristics* heuristics) const OVERRIDE;
private:
DECLARE_EXTENSION_FUNCTION_NAME("bookmarks.remove")
......@@ -165,7 +165,7 @@ class RemoveTreeBookmarkFunction : public RemoveBookmarkFunction {
class CreateBookmarkFunction : public BookmarksFunction {
public:
virtual void GetQuotaLimitHeuristics(
std::list<QuotaLimitHeuristic*>* heuristics) const;
QuotaLimitHeuristics* heuristics) const OVERRIDE;
// BookmarksFunction:
virtual bool RunImpl() OVERRIDE;
......@@ -178,7 +178,7 @@ class MoveBookmarkFunction : public BookmarksFunction {
static bool ExtractIds(const base::ListValue* args, std::list<int64>* ids,
bool* invalid_id);
virtual void GetQuotaLimitHeuristics(
std::list<QuotaLimitHeuristic*>* heuristics) const;
QuotaLimitHeuristics* heuristics) const OVERRIDE;
// BookmarksFunction:
virtual bool RunImpl() OVERRIDE;
......@@ -191,7 +191,7 @@ class UpdateBookmarkFunction : public BookmarksFunction {
static bool ExtractIds(const base::ListValue* args, std::list<int64>* ids,
bool* invalid_id);
virtual void GetQuotaLimitHeuristics(
std::list<QuotaLimitHeuristic*>* heuristics) const;
QuotaLimitHeuristics* heuristics) const OVERRIDE;
virtual bool RunImpl();
private:
DECLARE_EXTENSION_FUNCTION_NAME("bookmarks.update")
......
......@@ -82,7 +82,7 @@ class ExtensionFunction
// Returns a quota limit heuristic suitable for this function.
// No quota limiting by default.
virtual void GetQuotaLimitHeuristics(
std::list<QuotaLimitHeuristic*>* heuristics) const {}
QuotaLimitHeuristics* heuristics) const {}
// Called when the quota limit has been exceeded. The default implementation
// returns an error.
......
......@@ -1602,7 +1602,7 @@ bool WebRequestHandlerBehaviorChanged::RunImpl() {
}
void WebRequestHandlerBehaviorChanged::GetQuotaLimitHeuristics(
std::list<QuotaLimitHeuristic*>* heuristics) const {
QuotaLimitHeuristics* heuristics) const {
QuotaLimitHeuristic::Config config = {
20, // Refill 20 tokens per interval.
base::TimeDelta::FromMinutes(10) // 10 minutes refill interval.
......
......@@ -360,7 +360,7 @@ class WebRequestHandlerBehaviorChanged : public SyncIOThreadExtensionFunction {
private:
virtual void GetQuotaLimitHeuristics(
std::list<QuotaLimitHeuristic*>* heuristics) const OVERRIDE;
QuotaLimitHeuristics* heuristics) const OVERRIDE;
// Handle quota exceeded gracefully: Only warn the user but still execute the
// function.
virtual void OnQuotaExceeded() OVERRIDE;
......
......@@ -7,6 +7,8 @@
#include "base/bind.h"
#include "base/values.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extensions_quota_service.h"
#include "chrome/browser/extensions/settings/settings_api.h"
#include "chrome/browser/extensions/settings/settings_frontend.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/browser_thread.h"
......@@ -77,9 +79,10 @@ bool SettingsFunction::UseWriteResult(
// Concrete settings functions
namespace {
// Adds all StringValues from a ListValue to a vector of strings.
static void AddAllStringValues(
const ListValue& from, std::vector<std::string>* to) {
void AddAllStringValues(const ListValue& from, std::vector<std::string>* to) {
DCHECK(to->empty());
std::string as_string;
for (ListValue::const_iterator it = from.begin(); it != from.end(); ++it) {
......@@ -90,7 +93,7 @@ static void AddAllStringValues(
}
// Gets the keys of a DictionaryValue.
static std::vector<std::string> GetKeys(const DictionaryValue& dict) {
std::vector<std::string> GetKeys(const DictionaryValue& dict) {
std::vector<std::string> keys;
for (DictionaryValue::key_iterator it = dict.begin_keys();
it != dict.end_keys(); ++it) {
......@@ -99,6 +102,32 @@ static std::vector<std::string> GetKeys(const DictionaryValue& dict) {
return keys;
}
// Creates quota heuristics for settings modification.
static void GetModificationQuotaLimitHeuristics(
QuotaLimitHeuristics* heuristics) {
// A max of 1000 operations per hour.
QuotaLimitHeuristic::Config longLimitConfig = {
1000,
base::TimeDelta::FromHours(1)
};
heuristics->push_back(
new ExtensionsQuotaService::TimedLimit(
longLimitConfig, new QuotaLimitHeuristic::SingletonBucketMapper()));
// A max of 10 operations per minute, sustained over 10 minutes.
QuotaLimitHeuristic::Config shortLimitConfig = {
10,
base::TimeDelta::FromMinutes(1)
};
heuristics->push_back(
new ExtensionsQuotaService::SustainedLimit(
base::TimeDelta::FromMinutes(10),
shortLimitConfig,
new QuotaLimitHeuristic::SingletonBucketMapper()));
};
} // namespace
bool GetSettingsFunction::RunWithStorage(
scoped_refptr<SettingsObserverList> observers,
SettingsStorage* storage) {
......@@ -152,6 +181,11 @@ bool SetSettingsFunction::RunWithStorage(
observers, storage->Set(SettingsStorage::DEFAULTS, *input));
}
void SetSettingsFunction::GetQuotaLimitHeuristics(
QuotaLimitHeuristics* heuristics) const {
GetModificationQuotaLimitHeuristics(heuristics);
}
bool RemoveSettingsFunction::RunWithStorage(
scoped_refptr<SettingsObserverList> observers,
SettingsStorage* storage) {
......@@ -179,6 +213,11 @@ bool RemoveSettingsFunction::RunWithStorage(
};
}
void RemoveSettingsFunction::GetQuotaLimitHeuristics(
QuotaLimitHeuristics* heuristics) const {
GetModificationQuotaLimitHeuristics(heuristics);
}
bool ClearSettingsFunction::RunWithStorage(
scoped_refptr<SettingsObserverList> observers,
SettingsStorage* storage) {
......@@ -186,4 +225,9 @@ bool ClearSettingsFunction::RunWithStorage(
return UseWriteResult(observers, storage->Clear());
}
void ClearSettingsFunction::GetQuotaLimitHeuristics(
QuotaLimitHeuristics* heuristics) const {
GetModificationQuotaLimitHeuristics(heuristics);
}
} // namespace extensions
......@@ -66,6 +66,9 @@ class SetSettingsFunction : public SettingsFunction {
virtual bool RunWithStorage(
scoped_refptr<SettingsObserverList> observers,
SettingsStorage* storage) OVERRIDE;
virtual void GetQuotaLimitHeuristics(
QuotaLimitHeuristics* heuristics) const OVERRIDE;
};
class RemoveSettingsFunction : public SettingsFunction {
......@@ -76,6 +79,9 @@ class RemoveSettingsFunction : public SettingsFunction {
virtual bool RunWithStorage(
scoped_refptr<SettingsObserverList> observers,
SettingsStorage* storage) OVERRIDE;
virtual void GetQuotaLimitHeuristics(
QuotaLimitHeuristics* heuristics) const OVERRIDE;
};
class ClearSettingsFunction : public SettingsFunction {
......@@ -86,6 +92,9 @@ class ClearSettingsFunction : public SettingsFunction {
virtual bool RunWithStorage(
scoped_refptr<SettingsObserverList> observers,
SettingsStorage* storage) OVERRIDE;
virtual void GetQuotaLimitHeuristics(
QuotaLimitHeuristics* heuristics) const OVERRIDE;
};
} // namespace extensions
......
......@@ -285,6 +285,21 @@ chrome.test.runTests([
succeed();
}
stage0();
},
function throttling() {
// Should get throttled after 1000 calls.
var maxRequests = 1001;
function next() {
chrome.experimental.settings.clear((--maxRequests > 0) ? next : done);
}
function done() {
chrome.test.assertEq(
"This request exceeds available quota.",
chrome.extension.lastError.message);
succeed();
}
chrome.experimental.settings.clear(next);
}
]);
</script>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment