OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef WEBKIT_BROWSER_DATABASE_DATABASE_TRACKER_H_ | |
6 #define WEBKIT_BROWSER_DATABASE_DATABASE_TRACKER_H_ | |
7 | |
8 #include <map> | |
9 #include <set> | |
10 #include <utility> | |
11 | |
12 #include "base/files/file.h" | |
13 #include "base/files/file_path.h" | |
14 #include "base/gtest_prod_util.h" | |
15 #include "base/memory/ref_counted.h" | |
16 #include "base/memory/scoped_ptr.h" | |
17 #include "base/observer_list.h" | |
18 #include "base/strings/string16.h" | |
19 #include "base/strings/string_util.h" | |
20 #include "base/time/time.h" | |
21 #include "net/base/completion_callback.h" | |
22 #include "webkit/browser/webkit_storage_browser_export.h" | |
23 #include "webkit/common/database/database_connections.h" | |
24 | |
25 namespace base { | |
26 class MessageLoopProxy; | |
27 } | |
28 | |
29 namespace content { | |
30 class DatabaseTracker_TestHelper_Test; | |
31 class MockDatabaseTracker; | |
32 } | |
33 | |
34 namespace sql { | |
35 class Connection; | |
36 class MetaTable; | |
37 } | |
38 | |
39 namespace quota { | |
40 class QuotaManagerProxy; | |
41 class SpecialStoragePolicy; | |
42 } | |
43 | |
44 namespace webkit_database { | |
45 | |
46 WEBKIT_STORAGE_BROWSER_EXPORT extern const base::FilePath::CharType | |
47 kDatabaseDirectoryName[]; | |
48 WEBKIT_STORAGE_BROWSER_EXPORT extern const base::FilePath::CharType | |
49 kTrackerDatabaseFileName[]; | |
50 | |
51 class DatabasesTable; | |
52 | |
53 // This class is used to store information about all databases in an origin. | |
54 class WEBKIT_STORAGE_BROWSER_EXPORT OriginInfo { | |
55 public: | |
56 OriginInfo(); | |
57 OriginInfo(const OriginInfo& origin_info); | |
58 ~OriginInfo(); | |
59 | |
60 const std::string& GetOriginIdentifier() const { return origin_identifier_; } | |
61 int64 TotalSize() const { return total_size_; } | |
62 void GetAllDatabaseNames(std::vector<base::string16>* databases) const; | |
63 int64 GetDatabaseSize(const base::string16& database_name) const; | |
64 base::string16 GetDatabaseDescription( | |
65 const base::string16& database_name) const; | |
66 | |
67 protected: | |
68 typedef std::map<base::string16, std::pair<int64, base::string16> > | |
69 DatabaseInfoMap; | |
70 | |
71 OriginInfo(const std::string& origin_identifier, int64 total_size); | |
72 | |
73 std::string origin_identifier_; | |
74 int64 total_size_; | |
75 DatabaseInfoMap database_info_; | |
76 }; | |
77 | |
78 // This class manages the main database and keeps track of open databases. | |
79 // | |
80 // The data in this class is not thread-safe, so all methods of this class | |
81 // should be called on the same thread. The only exceptions are the ctor(), | |
82 // the dtor() and the database_directory() and quota_manager_proxy() getters. | |
83 // | |
84 // Furthermore, some methods of this class have to read/write data from/to | |
85 // the disk. Therefore, in a multi-threaded application, all methods of this | |
86 // class should be called on the thread dedicated to file operations (file | |
87 // thread in the browser process, for example), if such a thread exists. | |
88 class WEBKIT_STORAGE_BROWSER_EXPORT DatabaseTracker | |
89 : public base::RefCountedThreadSafe<DatabaseTracker> { | |
90 public: | |
91 class Observer { | |
92 public: | |
93 virtual void OnDatabaseSizeChanged(const std::string& origin_identifier, | |
94 const base::string16& database_name, | |
95 int64 database_size) = 0; | |
96 virtual void OnDatabaseScheduledForDeletion( | |
97 const std::string& origin_identifier, | |
98 const base::string16& database_name) = 0; | |
99 | |
100 protected: | |
101 virtual ~Observer() {} | |
102 }; | |
103 | |
104 DatabaseTracker(const base::FilePath& profile_path, | |
105 bool is_incognito, | |
106 quota::SpecialStoragePolicy* special_storage_policy, | |
107 quota::QuotaManagerProxy* quota_manager_proxy, | |
108 base::MessageLoopProxy* db_tracker_thread); | |
109 | |
110 void DatabaseOpened(const std::string& origin_identifier, | |
111 const base::string16& database_name, | |
112 const base::string16& database_details, | |
113 int64 estimated_size, | |
114 int64* database_size); | |
115 void DatabaseModified(const std::string& origin_identifier, | |
116 const base::string16& database_name); | |
117 void DatabaseClosed(const std::string& origin_identifier, | |
118 const base::string16& database_name); | |
119 void HandleSqliteError(const std::string& origin_identifier, | |
120 const base::string16& database_name, | |
121 int error); | |
122 | |
123 void CloseDatabases(const DatabaseConnections& connections); | |
124 | |
125 void AddObserver(Observer* observer); | |
126 void RemoveObserver(Observer* observer); | |
127 | |
128 void CloseTrackerDatabaseAndClearCaches(); | |
129 | |
130 const base::FilePath& DatabaseDirectory() const { return db_dir_; } | |
131 base::FilePath GetFullDBFilePath(const std::string& origin_identifier, | |
132 const base::string16& database_name); | |
133 | |
134 // virtual for unit-testing only | |
135 virtual bool GetOriginInfo(const std::string& origin_id, OriginInfo* info); | |
136 virtual bool GetAllOriginIdentifiers(std::vector<std::string>* origin_ids); | |
137 virtual bool GetAllOriginsInfo(std::vector<OriginInfo>* origins_info); | |
138 | |
139 // Safe to call on any thread. | |
140 quota::QuotaManagerProxy* quota_manager_proxy() const { | |
141 return quota_manager_proxy_.get(); | |
142 } | |
143 | |
144 bool IsDatabaseScheduledForDeletion(const std::string& origin_identifier, | |
145 const base::string16& database_name); | |
146 | |
147 // Deletes a single database. Returns net::OK on success, net::FAILED on | |
148 // failure, or net::ERR_IO_PENDING and |callback| is invoked upon completion, | |
149 // if non-NULL. | |
150 int DeleteDatabase(const std::string& origin_identifier, | |
151 const base::string16& database_name, | |
152 const net::CompletionCallback& callback); | |
153 | |
154 // Delete any databases that have been touched since the cutoff date that's | |
155 // supplied, omitting any that match IDs within |protected_origins|. | |
156 // Returns net::OK on success, net::FAILED if not all databases could be | |
157 // deleted, and net::ERR_IO_PENDING and |callback| is invoked upon completion, | |
158 // if non-NULL. Protected origins, according the the SpecialStoragePolicy, | |
159 // are not deleted by this method. | |
160 int DeleteDataModifiedSince(const base::Time& cutoff, | |
161 const net::CompletionCallback& callback); | |
162 | |
163 // Delete all databases that belong to the given origin. Returns net::OK on | |
164 // success, net::FAILED if not all databases could be deleted, and | |
165 // net::ERR_IO_PENDING and |callback| is invoked upon completion, if non-NULL. | |
166 // virtual for unit testing only | |
167 virtual int DeleteDataForOrigin(const std::string& origin_identifier, | |
168 const net::CompletionCallback& callback); | |
169 | |
170 bool IsIncognitoProfile() const { return is_incognito_; } | |
171 | |
172 const base::File* GetIncognitoFile(const base::string16& vfs_file_path) const; | |
173 const base::File* SaveIncognitoFile(const base::string16& vfs_file_path, | |
174 base::File file); | |
175 void CloseIncognitoFileHandle(const base::string16& vfs_file_path); | |
176 bool HasSavedIncognitoFileHandle(const base::string16& vfs_file_path) const; | |
177 | |
178 // Shutdown the database tracker, deleting database files if the tracker is | |
179 // used for an incognito profile. | |
180 void Shutdown(); | |
181 // Disables the exit-time deletion of session-only data. | |
182 void SetForceKeepSessionState(); | |
183 | |
184 private: | |
185 friend class base::RefCountedThreadSafe<DatabaseTracker>; | |
186 friend class content::DatabaseTracker_TestHelper_Test; | |
187 friend class content::MockDatabaseTracker; // for testing | |
188 | |
189 typedef std::map<std::string, std::set<base::string16> > DatabaseSet; | |
190 typedef std::vector<std::pair<net::CompletionCallback, DatabaseSet> > | |
191 PendingDeletionCallbacks; | |
192 typedef std::map<base::string16, base::File*> FileHandlesMap; | |
193 typedef std::map<std::string, base::string16> OriginDirectoriesMap; | |
194 | |
195 class CachedOriginInfo : public OriginInfo { | |
196 public: | |
197 CachedOriginInfo() : OriginInfo(std::string(), 0) {} | |
198 void SetOriginIdentifier(const std::string& origin_identifier) { | |
199 origin_identifier_ = origin_identifier; | |
200 } | |
201 void SetDatabaseSize(const base::string16& database_name, int64 new_size) { | |
202 int64 old_size = 0; | |
203 if (database_info_.find(database_name) != database_info_.end()) | |
204 old_size = database_info_[database_name].first; | |
205 database_info_[database_name].first = new_size; | |
206 if (new_size != old_size) | |
207 total_size_ += new_size - old_size; | |
208 } | |
209 void SetDatabaseDescription(const base::string16& database_name, | |
210 const base::string16& description) { | |
211 database_info_[database_name].second = description; | |
212 } | |
213 }; | |
214 | |
215 // virtual for unit-testing only. | |
216 virtual ~DatabaseTracker(); | |
217 | |
218 // Deletes the directory that stores all DBs in incognito mode, if it exists. | |
219 void DeleteIncognitoDBDirectory(); | |
220 | |
221 // Deletes session-only databases. Blocks databases from being created/opened. | |
222 void ClearSessionOnlyOrigins(); | |
223 | |
224 bool DeleteClosedDatabase(const std::string& origin_identifier, | |
225 const base::string16& database_name); | |
226 | |
227 // Delete all files belonging to the given origin given that no database | |
228 // connections within this origin are open, or if |force| is true, delete | |
229 // the meta data and rename the associated directory. | |
230 bool DeleteOrigin(const std::string& origin_identifier, bool force); | |
231 void DeleteDatabaseIfNeeded(const std::string& origin_identifier, | |
232 const base::string16& database_name); | |
233 | |
234 bool LazyInit(); | |
235 bool UpgradeToCurrentVersion(); | |
236 void InsertOrUpdateDatabaseDetails(const std::string& origin_identifier, | |
237 const base::string16& database_name, | |
238 const base::string16& database_details, | |
239 int64 estimated_size); | |
240 | |
241 void ClearAllCachedOriginInfo(); | |
242 CachedOriginInfo* MaybeGetCachedOriginInfo( | |
243 const std::string& origin_identifier, | |
244 bool create_if_needed); | |
245 CachedOriginInfo* GetCachedOriginInfo( | |
246 const std::string& origin_identifier) { | |
247 return MaybeGetCachedOriginInfo(origin_identifier, true); | |
248 } | |
249 | |
250 int64 GetDBFileSize(const std::string& origin_identifier, | |
251 const base::string16& database_name); | |
252 int64 SeedOpenDatabaseInfo(const std::string& origin_identifier, | |
253 const base::string16& database_name, | |
254 const base::string16& description); | |
255 int64 UpdateOpenDatabaseInfoAndNotify(const std::string& origin_identifier, | |
256 const base::string16& database_name, | |
257 const base::string16* opt_description); | |
258 int64 UpdateOpenDatabaseSizeAndNotify(const std::string& origin_identifier, | |
259 const base::string16& database_name) { | |
260 return UpdateOpenDatabaseInfoAndNotify( | |
261 origin_identifier, database_name, NULL); | |
262 } | |
263 | |
264 | |
265 void ScheduleDatabaseForDeletion(const std::string& origin_identifier, | |
266 const base::string16& database_name); | |
267 // Schedule a set of open databases for deletion. If non-null, callback is | |
268 // invoked upon completion. | |
269 void ScheduleDatabasesForDeletion(const DatabaseSet& databases, | |
270 const net::CompletionCallback& callback); | |
271 | |
272 // Returns the directory where all DB files for the given origin are stored. | |
273 base::string16 GetOriginDirectory(const std::string& origin_identifier); | |
274 | |
275 bool is_initialized_; | |
276 const bool is_incognito_; | |
277 bool force_keep_session_state_; | |
278 bool shutting_down_; | |
279 const base::FilePath profile_path_; | |
280 const base::FilePath db_dir_; | |
281 scoped_ptr<sql::Connection> db_; | |
282 scoped_ptr<DatabasesTable> databases_table_; | |
283 scoped_ptr<sql::MetaTable> meta_table_; | |
284 ObserverList<Observer, true> observers_; | |
285 std::map<std::string, CachedOriginInfo> origins_info_map_; | |
286 DatabaseConnections database_connections_; | |
287 | |
288 // The set of databases that should be deleted but are still opened | |
289 DatabaseSet dbs_to_be_deleted_; | |
290 PendingDeletionCallbacks deletion_callbacks_; | |
291 | |
292 // Apps and Extensions can have special rights. | |
293 scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy_; | |
294 | |
295 scoped_refptr<quota::QuotaManagerProxy> quota_manager_proxy_; | |
296 | |
297 // The database tracker thread we're supposed to run file IO on. | |
298 scoped_refptr<base::MessageLoopProxy> db_tracker_thread_; | |
299 | |
300 // When in incognito mode, store a DELETE_ON_CLOSE handle to each | |
301 // main DB and journal file that was accessed. When the incognito profile | |
302 // goes away (or when the browser crashes), all these handles will be | |
303 // closed, and the files will be deleted. | |
304 FileHandlesMap incognito_file_handles_; | |
305 | |
306 // In a non-incognito profile, all DBs in an origin are stored in a directory | |
307 // named after the origin. In an incognito profile though, we do not want the | |
308 // directory structure to reveal the origins visited by the user (in case the | |
309 // browser process crashes and those directories are not deleted). So we use | |
310 // this map to assign directory names that do not reveal this information. | |
311 OriginDirectoriesMap incognito_origin_directories_; | |
312 int incognito_origin_directories_generator_; | |
313 | |
314 FRIEND_TEST_ALL_PREFIXES(DatabaseTracker, TestHelper); | |
315 }; | |
316 | |
317 } // namespace webkit_database | |
318 | |
319 #endif // WEBKIT_BROWSER_DATABASE_DATABASE_TRACKER_H_ | |
OLD | NEW |