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.
5 #ifndef STORAGE_BROWSER_DATABASE_DATABASE_TRACKER_H_
6 #define STORAGE_BROWSER_DATABASE_DATABASE_TRACKER_H_
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 "storage/browser/storage_browser_export.h"
23 #include "storage/common/database/database_connections.h"
26 class MessageLoopProxy
;
30 class DatabaseTracker_TestHelper_Test
;
31 class MockDatabaseTracker
;
40 class QuotaManagerProxy
;
41 class SpecialStoragePolicy
;
46 STORAGE_EXPORT
extern const base::FilePath::CharType
47 kDatabaseDirectoryName
[];
48 STORAGE_EXPORT
extern const base::FilePath::CharType
49 kTrackerDatabaseFileName
[];
53 // This class is used to store information about all databases in an origin.
54 class STORAGE_EXPORT OriginInfo
{
57 OriginInfo(const OriginInfo
& origin_info
);
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;
68 typedef std::map
<base::string16
, std::pair
<int64
, base::string16
> >
71 OriginInfo(const std::string
& origin_identifier
, int64 total_size
);
73 std::string origin_identifier_
;
75 DatabaseInfoMap database_info_
;
78 // This class manages the main database and keeps track of open databases.
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.
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 STORAGE_EXPORT DatabaseTracker
89 : public base::RefCountedThreadSafe
<DatabaseTracker
> {
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;
101 virtual ~Observer() {}
104 DatabaseTracker(const base::FilePath
& profile_path
,
106 storage::SpecialStoragePolicy
* special_storage_policy
,
107 storage::QuotaManagerProxy
* quota_manager_proxy
,
108 base::MessageLoopProxy
* db_tracker_thread
);
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
,
123 void CloseDatabases(const DatabaseConnections
& connections
);
125 void AddObserver(Observer
* observer
);
126 void RemoveObserver(Observer
* observer
);
128 void CloseTrackerDatabaseAndClearCaches();
130 const base::FilePath
& DatabaseDirectory() const { return db_dir_
; }
131 base::FilePath
GetFullDBFilePath(const std::string
& origin_identifier
,
132 const base::string16
& database_name
);
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
);
139 // Safe to call on any thread.
140 storage::QuotaManagerProxy
* quota_manager_proxy() const {
141 return quota_manager_proxy_
.get();
144 bool IsDatabaseScheduledForDeletion(const std::string
& origin_identifier
,
145 const base::string16
& database_name
);
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,
150 int DeleteDatabase(const std::string
& origin_identifier
,
151 const base::string16
& database_name
,
152 const net::CompletionCallback
& callback
);
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
);
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
);
170 bool IsIncognitoProfile() const { return is_incognito_
; }
172 const base::File
* GetIncognitoFile(const base::string16
& vfs_file_path
) const;
173 const base::File
* SaveIncognitoFile(const base::string16
& vfs_file_path
,
175 void CloseIncognitoFileHandle(const base::string16
& vfs_file_path
);
176 bool HasSavedIncognitoFileHandle(const base::string16
& vfs_file_path
) const;
178 // Shutdown the database tracker, deleting database files if the tracker is
179 // used for an incognito profile.
181 // Disables the exit-time deletion of session-only data.
182 void SetForceKeepSessionState();
185 friend class base::RefCountedThreadSafe
<DatabaseTracker
>;
186 friend class content::DatabaseTracker_TestHelper_Test
;
187 friend class content::MockDatabaseTracker
; // for testing
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
;
195 class CachedOriginInfo
: public OriginInfo
{
197 CachedOriginInfo() : OriginInfo(std::string(), 0) {}
198 void SetOriginIdentifier(const std::string
& origin_identifier
) {
199 origin_identifier_
= origin_identifier
;
201 void SetDatabaseSize(const base::string16
& database_name
, int64 new_size
) {
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
;
209 void SetDatabaseDescription(const base::string16
& database_name
,
210 const base::string16
& description
) {
211 database_info_
[database_name
].second
= description
;
215 // virtual for unit-testing only.
216 virtual ~DatabaseTracker();
218 // Deletes the directory that stores all DBs in incognito mode, if it exists.
219 void DeleteIncognitoDBDirectory();
221 // Deletes session-only databases. Blocks databases from being created/opened.
222 void ClearSessionOnlyOrigins();
224 bool DeleteClosedDatabase(const std::string
& origin_identifier
,
225 const base::string16
& database_name
);
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
);
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
);
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);
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
);
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
);
272 // Returns the directory where all DB files for the given origin are stored.
273 base::string16
GetOriginDirectory(const std::string
& origin_identifier
);
275 bool is_initialized_
;
276 const bool is_incognito_
;
277 bool force_keep_session_state_
;
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_
;
288 // The set of databases that should be deleted but are still opened
289 DatabaseSet dbs_to_be_deleted_
;
290 PendingDeletionCallbacks deletion_callbacks_
;
292 // Apps and Extensions can have special rights.
293 scoped_refptr
<storage::SpecialStoragePolicy
> special_storage_policy_
;
295 scoped_refptr
<storage::QuotaManagerProxy
> quota_manager_proxy_
;
297 // The database tracker thread we're supposed to run file IO on.
298 scoped_refptr
<base::MessageLoopProxy
> db_tracker_thread_
;
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_
;
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_
;
314 FRIEND_TEST_ALL_PREFIXES(DatabaseTracker
, TestHelper
);
317 } // namespace storage
319 #endif // STORAGE_BROWSER_DATABASE_DATABASE_TRACKER_H_