1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// The QuotaService uses heuristics to limit abusive requests 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// made by extensions. In this model 'items' (e.g individual bookmarks) are 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// represented by a 'Bucket' that holds state for that item for one single 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// interval of time. The interval of time is defined as 'how long we need to 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// watch an item (for a particular heuristic) before making a decision about 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// quota violations'. A heuristic is two functions: one mapping input 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// arguments to a unique Bucket (the BucketMapper), and another to determine 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if a new request involving such an item at a given time is a violation. 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#ifndef EXTENSIONS_BROWSER_QUOTA_SERVICE_H_ 15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define EXTENSIONS_BROWSER_QUOTA_SERVICE_H_ 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <list> 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/containers/hash_tables.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/non_thread_safe.h" 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExtensionFunction; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class QuotaLimitHeuristic; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)typedef std::list<QuotaLimitHeuristic*> QuotaLimitHeuristics; 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// The QuotaService takes care that calls to certain extension 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// functions do not exceed predefined quotas. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// The QuotaService needs to live entirely on one thread, i.e. be created, 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// called and destroyed on the same thread, due to its use of a RepeatingTimer. 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// It is not a KeyedService because instances exist on both the UI 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// and IO threads. 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class QuotaService : public base::NonThreadSafe { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Some concrete heuristics (declared below) that ExtensionFunctions can 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // use to help the service make decisions about quota violations. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class TimedLimit; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class SustainedLimit; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QuotaService(); 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual ~QuotaService(); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Decide whether the invocation of |function| with argument |args| by the 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension specified by |extension_id| results in a quota limit violation. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns an error message representing the failure if quota was exceeded, 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // or empty-string if the request is fine and can proceed. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string Assess(const std::string& extension_id, 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionFunction* function, 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const base::ListValue* args, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeTicks& event_time); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::string ExtensionId; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::string FunctionName; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All QuotaLimitHeuristic instances in this map are owned by us. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<FunctionName, QuotaLimitHeuristics> FunctionHeuristicsMap; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Purge resets all accumulated data (except |violation_errors_|) as if the 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // service was just created. Called periodically so we don't consume an 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // unbounded amount of memory while tracking quota. Yes, this could mean an 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension gets away with murder if it is timed right, but the extensions 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we are trying to limit are ones that consistently violate, so we'll 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // converge to the correct set. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Purge(); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PurgeFunctionHeuristicsMap(FunctionHeuristicsMap* map); 76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::RepeatingTimer<QuotaService> purge_timer_; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Our quota tracking state for extensions that have invoked quota limited 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // functions. Each extension is treated separately, so extension ids are the 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // key for the mapping. As an extension invokes functions, the map keeps 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // track of which functions it has invoked and the heuristics for each one. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Each heuristic will be evaluated and ANDed together to get a final answer. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<ExtensionId, FunctionHeuristicsMap> function_heuristics_; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For now, as soon as an extension violates quota, we don't allow it to 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // make any more requests to quota limited functions. This provides a quick 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // lookup for these extensions that is only stored in memory. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<std::string, std::string> ViolationErrorMap; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ViolationErrorMap violation_errors_; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(QuotaService); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A QuotaLimitHeuristic is two things: 1, A heuristic to map extension 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// function arguments to corresponding Buckets for each input arg, and 2) a 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// heuristic for determining if a new event involving a particular item 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (represented by its Bucket) constitutes a quota violation. 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class QuotaLimitHeuristic { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parameters to configure the amount of tokens allotted to individual 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Bucket objects (see Below) and how often they are replenished. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct Config { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The maximum number of tokens a bucket can contain, and is refilled to 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // every epoch. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 refill_token_count; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Specifies how frequently the bucket is logically refilled with tokens. 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta refill_interval; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A Bucket is how the heuristic portrays an individual item (since quota 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // limits are per item) and all associated state for an item that needs to 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // carry through multiple calls to Apply. It "holds" tokens, which are 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // debited and credited in response to new events involving the item being 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // being represented. For convenience, instead of actually periodically 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // refilling buckets they are just 'Reset' on-demand (e.g. when new events 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // come in). So, a bucket has an expiration to denote it has becomes stale. 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class Bucket { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bucket() : num_tokens_(0) {} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Removes a token from this bucket, and returns true if the bucket had 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // any tokens in the first place. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool DeductToken() { return num_tokens_-- > 0; } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if this bucket has tokens to deduct. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_tokens() const { return num_tokens_ > 0; } 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reset this bucket to specification (from internal configuration), to be 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // valid from |start| until the first refill interval elapses and it needs 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to be reset again. 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Reset(const Config& config, const base::TimeTicks& start); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The time at which the token count and next expiration should be reset, 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // via a call to Reset. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeTicks& expiration() { return expiration_; } 136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks expiration_; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 num_tokens_; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Bucket); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::list<Bucket*> BucketList; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A helper interface to retrieve the bucket corresponding to |args| from 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the set of buckets (which is typically stored in the BucketMapper itself) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for this QuotaLimitHeuristic. 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class BucketMapper { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~BucketMapper() {} 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In most cases, this should simply extract item IDs from the arguments 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (e.g for bookmark operations involving an existing item). If a problem 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // occurs while parsing |args|, the function aborts - buckets may be non- 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // empty). The expectation is that invalid args and associated errors are 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // handled by the ExtensionFunction itself so we don't concern ourselves. 155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void GetBucketsForArgs(const base::ListValue* args, 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BucketList* buckets) = 0; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Maps all calls to the same bucket, regardless of |args|, for this 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // QuotaLimitHeuristic. 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class SingletonBucketMapper : public BucketMapper { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SingletonBucketMapper() {} 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~SingletonBucketMapper() {} 165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void GetBucketsForArgs(const base::ListValue* args, 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BucketList* buckets) OVERRIDE; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bucket bucket_; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SingletonBucketMapper); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ownership of |map| is given to the new QuotaLimitHeuristic. 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaLimitHeuristic(const Config& config, 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BucketMapper* map, 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& name); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~QuotaLimitHeuristic(); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Determines if sufficient quota exists (according to the Apply 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // implementation of a derived class) to perform an operation with |args|, 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // based on the history of similar operations with similar arguments (which 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is retrieved using the BucketMapper). 183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool ApplyToArgs(const base::ListValue* args, 184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const base::TimeTicks& event_time); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns an error formatted according to this heuristic. 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string GetError() const; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Config& config() { return config_; } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Determine if the new event occurring at |event_time| involving |bucket| 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // constitutes a quota violation according to this heuristic. 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool Apply(Bucket* bucket, const base::TimeTicks& event_time) = 0; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class QuotaLimitHeuristicTest; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Config config_; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The mapper used in Map. Cannot be NULL. 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BucketMapper> bucket_mapper_; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The name of the heuristic for formatting error messages. 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string name_; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(QuotaLimitHeuristic); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A simple per-item heuristic to limit the number of events that can occur in 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a given period of time; e.g "no more than 100 events in an hour". 212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class QuotaService::TimedLimit : public QuotaLimitHeuristic { 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimedLimit(const Config& config, BucketMapper* map, const std::string& name) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : QuotaLimitHeuristic(config, map, name) {} 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool Apply(Bucket* bucket, 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeTicks& event_time) OVERRIDE; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A per-item heuristic to limit the number of events that can occur in a 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// period of time over a sustained longer interval. E.g "no more than two 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// events per minute, sustained over 10 minutes". 223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class QuotaService::SustainedLimit : public QuotaLimitHeuristic { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SustainedLimit(const base::TimeDelta& sustain, 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Config& config, 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BucketMapper* map, 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& name); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool Apply(Bucket* bucket, 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeTicks& event_time) OVERRIDE; 231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Specifies how long exhaustion of buckets is allowed to continue before 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // denying requests. 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int64 repeat_exhaustion_allowance_; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 num_available_repeat_exhaustions_; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} // namespace extensions 240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif // EXTENSIONS_BROWSER_QUOTA_SERVICE_H_ 242