1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_BUDGET_SERVICE_BUDGET_DATABASE_H_
#define CHROME_BROWSER_BUDGET_SERVICE_BUDGET_DATABASE_H_
#include <list>
#include <map>
#include <memory>
#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "components/leveldb_proto/proto_database.h"
#include "third_party/WebKit/public/platform/modules/budget_service/budget_service.mojom.h"
namespace base {
class Clock;
class SequencedTaskRunner;
class Time;
}
namespace budget_service {
class Budget;
}
namespace url {
class Origin;
}
class Profile;
// A class used to asynchronously read and write details of the budget
// assigned to an origin. The class uses an underlying LevelDB.
class BudgetDatabase {
public:
// Callback for getting a list of all budget chunks.
using GetBudgetCallback = blink::mojom::BudgetService::GetBudgetCallback;
// This is invoked only after the spend has been written to the database.
using SpendBudgetCallback =
base::Callback<void(blink::mojom::BudgetServiceErrorType error_type,
bool success)>;
// The database_dir specifies the location of the budget information on
// disk. The task_runner is used by the ProtoDatabase to handle all blocking
// calls and disk access.
BudgetDatabase(Profile* profile,
const base::FilePath& database_dir,
const scoped_refptr<base::SequencedTaskRunner>& task_runner);
~BudgetDatabase();
// Get the full budget expectation for the origin. This will return a
// sequence of time points and the expected budget at those times.
void GetBudgetDetails(const url::Origin& origin,
const GetBudgetCallback& callback);
// Spend a particular amount of budget for an origin. The callback indicates
// whether there was an error and if the origin had enough budget.
void SpendBudget(const url::Origin& origin,
double amount,
const SpendBudgetCallback& callback);
private:
friend class BudgetDatabaseTest;
// Used to allow tests to change time for testing.
void SetClockForTesting(std::unique_ptr<base::Clock> clock);
// Holds information about individual pieces of awarded budget. There is a
// one-to-one mapping of these to the chunks in the underlying database.
struct BudgetChunk {
BudgetChunk(double amount, base::Time expiration)
: amount(amount), expiration(expiration) {}
BudgetChunk(const BudgetChunk& other)
: amount(other.amount), expiration(other.expiration) {}
double amount;
base::Time expiration;
};
// Data structure for caching budget information.
using BudgetChunks = std::list<BudgetChunk>;
// Holds information about the overall budget for a site. This includes the
// time the budget was last incremented, as well as a list of budget chunks
// which have been awarded.
struct BudgetInfo {
BudgetInfo();
BudgetInfo(const BudgetInfo&& other);
~BudgetInfo();
base::Time last_engagement_award;
BudgetChunks chunks;
DISALLOW_COPY_AND_ASSIGN(BudgetInfo);
};
// Callback for writing budget values to the database.
using StoreBudgetCallback = base::Callback<void(bool success)>;
using CacheCallback = base::Callback<void(bool success)>;
void OnDatabaseInit(bool success);
bool IsCached(const url::Origin& origin) const;
double GetBudget(const url::Origin& origin) const;
void AddToCache(const url::Origin& origin,
const CacheCallback& callback,
bool success,
std::unique_ptr<budget_service::Budget> budget);
void GetBudgetAfterSync(const url::Origin& origin,
const GetBudgetCallback& callback,
bool success);
void SpendBudgetAfterSync(const url::Origin& origin,
double amount,
const SpendBudgetCallback& callback,
bool success);
void SpendBudgetAfterWrite(const SpendBudgetCallback& callback, bool success);
void WriteCachedValuesToDatabase(const url::Origin& origin,
const StoreBudgetCallback& callback);
void SyncCache(const url::Origin& origin, const CacheCallback& callback);
void SyncLoadedCache(const url::Origin& origin,
const CacheCallback& callback,
bool success);
// Add budget based on engagement with an origin. The method queries for the
// engagement score of the origin, and then calculates when engagement budget
// was last awarded and awards a portion of the score based on that.
// This only writes budget to the cache.
void AddEngagementBudget(const url::Origin& origin);
bool CleanupExpiredBudget(const url::Origin& origin);
Profile* profile_;
// The database for storing budget information.
std::unique_ptr<leveldb_proto::ProtoDatabase<budget_service::Budget>> db_;
// Cached data for the origins which have been loaded.
std::map<url::Origin, BudgetInfo> budget_map_;
// The clock used to vend times.
std::unique_ptr<base::Clock> clock_;
base::WeakPtrFactory<BudgetDatabase> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(BudgetDatabase);
};
#endif // CHROME_BROWSER_BUDGET_SERVICE_BUDGET_DATABASE_H_
|