summaryrefslogtreecommitdiffstats
path: root/webkit/quota/quota_manager.h
blob: 16c05886eac453c9d0e3fc1a76e82c19fec14769 (plain)
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
// 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 "base/basictypes.h"
#include "base/callback.h"
#include "base/file_path.h"
#include "base/memory/scoped_callback_factory.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/ref_counted.h"
#include "webkit/quota/quota_client.h"
#include "webkit/quota/quota_task.h"
#include "webkit/quota/quota_types.h"

class FilePath;

namespace quota {

class QuotaDatabase;
class UsageTracker;

struct QuotaManagerDeleter;
class QuotaManagerProxy;

// 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 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,
               scoped_refptr<base::MessageLoopProxy> io_thread,
               scoped_refptr<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 UI and internal modules.
  void GetTemporaryGlobalQuota(QuotaCallback* callback);
  void SetTemporaryGlobalQuota(int64 new_quota);
  void GetPersistentHostQuota(const std::string& host,
                              HostQuotaCallback* callback);
  void SetPersistentHostQuota(const std::string& host, int64 new_quota);

  // TODO(kinuko): Add more APIs for UI:
  // - Get temporary global/per-host usage
  // - Get persistent global/per-host usage

  const static int64 kTemporaryStorageQuotaDefaultSize;
  const static int64 kTemporaryStorageQuotaMaxSize;
  const static char kDatabaseName[];

  const static int64 kIncognitoDefaultTemporaryQuota;

 private:
  class InitializeTask;
  class TemporaryGlobalQuotaUpdateTask;

  class UsageAndQuotaDispatcherTask;
  class UsageAndQuotaDispatcherTaskForTemporary;
  class UsageAndQuotaDispatcherTaskForPersistent;

  typedef std::pair<std::string, StorageType> HostAndType;
  typedef std::map<HostAndType, UsageAndQuotaDispatcherTask*>
      UsageAndQuotaDispatcherTaskMap;

  friend struct QuotaManagerDeleter;
  friend class QuotaManagerProxy;

  // 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);

  // Called by clients via proxy.
  // QuotaClients 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);

  UsageTracker* GetUsageTracker(StorageType type) const;

  void DidGetTemporaryGlobalQuota(int64 quota);
  void DidGetPersistentHostQuota(const std::string& host, int64 quota);

  void DeleteOnCorrectThread() const;

  const bool is_incognito_;
  const FilePath profile_path_;

  scoped_refptr<QuotaManagerProxy> proxy_;
  bool db_initialized_;
  bool db_disabled_;
  scoped_refptr<base::MessageLoopProxy> io_thread_;
  scoped_refptr<base::MessageLoopProxy> db_thread_;
  mutable scoped_ptr<QuotaDatabase> database_;

  QuotaClientList clients_;

  scoped_ptr<UsageTracker> temporary_usage_tracker_;
  scoped_ptr<UsageTracker> persistent_usage_tracker_;

  UsageAndQuotaDispatcherTaskMap usage_and_quota_dispatchers_;

  int64 temporary_global_quota_;
  QuotaCallbackQueue temporary_global_quota_callbacks_;

  std::map<std::string, int64> persistent_host_quota_;
  HostQuotaCallbackMap persistent_host_quota_callbacks_;

  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:
  void GetUsageAndQuota(const GURL& origin,
                        StorageType type,
                        QuotaManager::GetUsageAndQuotaCallback* callback);
  void RegisterClient(QuotaClient* client);
  void NotifyStorageModified(QuotaClient::ID client_id,
                            const GURL& origin,
                            StorageType type,
                            int64 delta);
 private:
  friend class QuotaManager;
  friend class base::RefCountedThreadSafe<QuotaManagerProxy>;
  QuotaManagerProxy(QuotaManager* manager, base::MessageLoopProxy* io_thread);
  ~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_