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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
|
// Copyright (c) 2011 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 WEBKIT_QUOTA_QUOTA_MANAGER_H_
#define WEBKIT_QUOTA_QUOTA_MANAGER_H_
#pragma once
#include <deque>
#include <list>
#include <map>
#include <string>
#include "base/basictypes.h"
#include "base/callback.h"
#include "base/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_callback_factory.h"
#include "base/memory/scoped_ptr.h"
#include "webkit/quota/quota_client.h"
#include "webkit/quota/quota_task.h"
#include "webkit/quota/quota_types.h"
namespace base {
class MessageLoopProxy;
}
class FilePath;
namespace quota {
class QuotaDatabase;
class UsageTracker;
struct QuotaManagerDeleter;
class QuotaManagerProxy;
// An interface called by QuotaTemporaryStorageEvictor.
class QuotaEvictionHandler {
public:
typedef Callback1<const GURL&>::Type GetLRUOriginCallback;
typedef Callback1<QuotaStatusCode>::Type EvictOriginDataCallback;
typedef Callback4<QuotaStatusCode,
int64 /* usage */,
int64 /* quota */,
int64 /* physical_available */ >::Type
GetUsageAndQuotaForEvictionCallback;
// Returns the least recently used origin. It might return empty
// GURL when there are no evictable origins.
virtual void GetLRUOrigin(
StorageType type,
GetLRUOriginCallback* callback) = 0;
virtual void EvictOriginData(
const GURL& origin,
StorageType type,
EvictOriginDataCallback* callback) = 0;
virtual void GetUsageAndQuotaForEviction(
GetUsageAndQuotaForEvictionCallback* callback) = 0;
protected:
virtual ~QuotaEvictionHandler() {}
};
// The quota manager class. This class is instantiated per profile and
// held by the profile. With the exception of the constructor and the
// proxy() method, all methods should only be called on the IO thread.
class QuotaManager : public QuotaTaskObserver,
public QuotaEvictionHandler,
public base::RefCountedThreadSafe<
QuotaManager, QuotaManagerDeleter> {
public:
typedef Callback3<QuotaStatusCode,
int64 /* usage */,
int64 /* quota */>::Type GetUsageAndQuotaCallback;
typedef Callback2<QuotaStatusCode,
int64 /* granted_quota */>::Type RequestQuotaCallback;
QuotaManager(bool is_incognito,
const FilePath& profile_path,
base::MessageLoopProxy* io_thread,
base::MessageLoopProxy* db_thread);
virtual ~QuotaManager();
// Returns a proxy object that can be used on any thread.
QuotaManagerProxy* proxy() { return proxy_.get(); }
// Called by clients or webapps.
// This method is declared as virtual to allow test code to override it.
virtual void GetUsageAndQuota(const GURL& origin,
StorageType type,
GetUsageAndQuotaCallback* callback);
// Called by webapps.
void RequestQuota(const GURL& origin,
StorageType type,
int64 requested_size,
RequestQuotaCallback* callback);
// Called by clients via proxy.
// Client storage should call this method when storage is accessed.
// Used to maintain LRU ordering.
void NotifyStorageAccessed(QuotaClient::ID client_id,
const GURL& origin,
StorageType typea);
// Called by clients via proxy.
// Client storage must call this method whenever they have made any
// modifications that change the amount of data stored in their storage.
void NotifyStorageModified(QuotaClient::ID client_id,
const GURL& origin,
StorageType type,
int64 delta);
// Used to avoid evicting origins with open pages.
// A call to NotifyOriginInUse must be balanced by a later call
// to NotifyOriginNoLongerInUse.
void NotifyOriginInUse(const GURL& origin);
void NotifyOriginNoLongerInUse(const GURL& origin);
bool IsOriginInUse(const GURL& origin) const {
return origins_in_use_.find(origin) != origins_in_use_.end();
}
// Called by UI and internal modules.
void GetAvailableSpace(AvailableSpaceCallback* callback);
void GetTemporaryGlobalQuota(QuotaCallback* callback);
void SetTemporaryGlobalQuota(int64 new_quota, QuotaCallback* callback);
void GetPersistentHostQuota(const std::string& host,
HostQuotaCallback* callback);
void SetPersistentHostQuota(const std::string& host,
int64 new_quota,
HostQuotaCallback* callback);
void GetGlobalUsage(StorageType type, UsageCallback* callback);
void GetHostUsage(const std::string& host, StorageType type,
HostUsageCallback* callback);
static const int64 kTemporaryStorageQuotaDefaultSize;
static const int64 kTemporaryStorageQuotaMaxSize;
static const char kDatabaseName[];
static const int64 kIncognitoDefaultTemporaryQuota;
private:
class DatabaseTaskBase;
class InitializeTask;
class TemporaryGlobalQuotaUpdateTask;
class PersistentHostQuotaQueryTask;
class PersistentHostQuotaUpdateTask;
class GetLRUOriginTask;
class OriginDeletionDatabaseTask;
class TemporaryOriginsRegistrationTask;
class UsageAndQuotaDispatcherTask;
class UsageAndQuotaDispatcherTaskForTemporary;
class UsageAndQuotaDispatcherTaskForPersistent;
class AvailableSpaceQueryTask;
struct EvictionContext {
EvictionContext()
: num_eviction_requested_clients(0),
num_evicted_clients(0),
num_eviction_error(0),
usage(0),
quota(0) {}
virtual ~EvictionContext() {}
scoped_ptr<EvictOriginDataCallback> evict_origin_data_callback;
int num_eviction_requested_clients;
int num_evicted_clients;
int num_eviction_error;
scoped_ptr<GetUsageAndQuotaForEvictionCallback>
get_usage_and_quota_callback;
int64 usage;
int64 quota;
};
typedef std::pair<std::string, StorageType> HostAndType;
typedef std::map<HostAndType, UsageAndQuotaDispatcherTask*>
UsageAndQuotaDispatcherTaskMap;
friend struct QuotaManagerDeleter;
friend class QuotaManagerProxy;
friend class QuotaManagerTest;
// This initialization method is lazily called on the IO thread
// when the first quota manager API is called.
// Initialize must be called after all quota clients are added to the
// manager by RegisterStorage.
void LazyInitialize();
// Called by clients via proxy.
// Registers a quota client to the manager.
// The client must remain valid until OnQuotaManagerDestored is called.
void RegisterClient(QuotaClient* client);
UsageTracker* GetUsageTracker(StorageType type) const;
// Extract cached origins list from the usage tracker.
// (Might return empty list if no origin is tracked by the tracker.)
void GetCachedOrigins(StorageType type, std::set<GURL>* origins);
// Methods for eviction logic.
void StartEviction();
void DeleteOriginFromDatabase(const GURL& origin, StorageType type);
void DidOriginDataEvicted(QuotaStatusCode status);
void DidGetAvailableSpaceForEviction(
QuotaStatusCode status,
int64 available_space);
void DidGetGlobalQuotaForEviction(
QuotaStatusCode status,
int64 quota);
void DidGetGlobalUsageForEviction(int64 usage);
// QuotaEvictionHandler.
virtual void GetLRUOrigin(
StorageType type,
GetLRUOriginCallback* callback) OVERRIDE;
virtual void EvictOriginData(
const GURL& origin,
StorageType type,
EvictOriginDataCallback* callback) OVERRIDE;
virtual void GetUsageAndQuotaForEviction(
GetUsageAndQuotaForEvictionCallback* callback) OVERRIDE;
void DidInitializeTemporaryGlobalQuota(int64 quota);
void DidRunInitialGetTemporaryGlobalUsage(int64 usage);
void DidGetDatabaseLRUOrigin(const GURL& origin);
void DeleteOnCorrectThread() const;
const bool is_incognito_;
const FilePath profile_path_;
scoped_refptr<QuotaManagerProxy> proxy_;
bool db_disabled_;
scoped_refptr<base::MessageLoopProxy> io_thread_;
scoped_refptr<base::MessageLoopProxy> db_thread_;
mutable scoped_ptr<QuotaDatabase> database_;
bool need_initialize_origins_;
scoped_ptr<GetLRUOriginCallback> lru_origin_callback_;
std::set<GURL> access_notified_origins_;
QuotaClientList clients_;
scoped_ptr<UsageTracker> temporary_usage_tracker_;
scoped_ptr<UsageTracker> persistent_usage_tracker_;
EvictionContext eviction_context_;
UsageAndQuotaDispatcherTaskMap usage_and_quota_dispatchers_;
int64 temporary_global_quota_;
QuotaCallbackQueue temporary_global_quota_callbacks_;
// Map from origin to count.
std::map<GURL, int> origins_in_use_;
base::ScopedCallbackFactory<QuotaManager> callback_factory_;
DISALLOW_COPY_AND_ASSIGN(QuotaManager);
};
struct QuotaManagerDeleter {
static void Destruct(const QuotaManager* manager) {
manager->DeleteOnCorrectThread();
}
};
// The proxy may be called and finally released on any thread.
class QuotaManagerProxy
: public base::RefCountedThreadSafe<QuotaManagerProxy> {
public:
virtual void RegisterClient(QuotaClient* client);
virtual void NotifyStorageAccessed(QuotaClient::ID client_id,
const GURL& origin,
StorageType type);
virtual void NotifyStorageModified(QuotaClient::ID client_id,
const GURL& origin,
StorageType type,
int64 delta);
virtual void NotifyOriginInUse(const GURL& origin);
virtual void NotifyOriginNoLongerInUse(const GURL& origin);
// This method may only be called on the IO thread.
// It may return NULL if the manager has already been deleted.
QuotaManager* quota_manager() const;
protected:
friend class QuotaManager;
friend class base::RefCountedThreadSafe<QuotaManagerProxy>;
QuotaManagerProxy(QuotaManager* manager, base::MessageLoopProxy* io_thread);
virtual ~QuotaManagerProxy();
QuotaManager* manager_; // only accessed on the io thread
scoped_refptr<base::MessageLoopProxy> io_thread_;
DISALLOW_COPY_AND_ASSIGN(QuotaManagerProxy);
};
} // namespace quota
#endif // WEBKIT_QUOTA_QUOTA_MANAGER_H_
|