#ifndef WEBKIT_BROWSER_DATABASE_DATABASE_TRACKER_H_
#define WEBKIT_BROWSER_DATABASE_DATABASE_TRACKER_H_
#include <map>
#include <set>
#include <utility>
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
#include "base/platform_file.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/time/time.h"
#include "net/base/completion_callback.h"
#include "webkit/browser/webkit_storage_browser_export.h"
#include "webkit/common/database/database_connections.h"
namespace base {
class MessageLoopProxy;
}
namespace sql {
class Connection;
class MetaTable;
}
namespace quota {
class QuotaManagerProxy;
class SpecialStoragePolicy;
}
namespace webkit_database {
WEBKIT_STORAGE_BROWSER_EXPORT extern const base::FilePath::CharType
kDatabaseDirectoryName[];
WEBKIT_STORAGE_BROWSER_EXPORT extern const base::FilePath::CharType
kTrackerDatabaseFileName[];
class DatabasesTable;
class WEBKIT_STORAGE_BROWSER_EXPORT OriginInfo {
public:
OriginInfo();
OriginInfo(const OriginInfo& origin_info);
~OriginInfo();
const std::string& GetOriginIdentifier() const { return origin_identifier_; }
int64 TotalSize() const { return total_size_; }
void GetAllDatabaseNames(std::vector<base::string16>* databases) const;
int64 GetDatabaseSize(const base::string16& database_name) const;
base::string16 GetDatabaseDescription(
const base::string16& database_name) const;
protected:
typedef std::map<base::string16, std::pair<int64, base::string16> >
DatabaseInfoMap;
OriginInfo(const std::string& origin_identifier, int64 total_size);
std::string origin_identifier_;
int64 total_size_;
DatabaseInfoMap database_info_;
};
class WEBKIT_STORAGE_BROWSER_EXPORT DatabaseTracker
: public base::RefCountedThreadSafe<DatabaseTracker> {
public:
class Observer {
public:
virtual void OnDatabaseSizeChanged(const std::string& origin_identifier,
const base::string16& database_name,
int64 database_size) = 0;
virtual void OnDatabaseScheduledForDeletion(
const std::string& origin_identifier,
const base::string16& database_name) = 0;
protected:
virtual ~Observer() {}
};
DatabaseTracker(const base::FilePath& profile_path,
bool is_incognito,
quota::SpecialStoragePolicy* special_storage_policy,
quota::QuotaManagerProxy* quota_manager_proxy,
base::MessageLoopProxy* db_tracker_thread);
void DatabaseOpened(const std::string& origin_identifier,
const base::string16& database_name,
const base::string16& database_details,
int64 estimated_size,
int64* database_size);
void DatabaseModified(const std::string& origin_identifier,
const base::string16& database_name);
void DatabaseClosed(const std::string& origin_identifier,
const base::string16& database_name);
void HandleSqliteError(const std::string& origin_identifier,
const base::string16& database_name,
int error);
void CloseDatabases(const DatabaseConnections& connections);
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
void CloseTrackerDatabaseAndClearCaches();
const base::FilePath& DatabaseDirectory() const { return db_dir_; }
base::FilePath GetFullDBFilePath(const std::string& origin_identifier,
const base::string16& database_name);
virtual bool GetOriginInfo(const std::string& origin_id, OriginInfo* info);
virtual bool GetAllOriginIdentifiers(std::vector<std::string>* origin_ids);
virtual bool GetAllOriginsInfo(std::vector<OriginInfo>* origins_info);
quota::QuotaManagerProxy* quota_manager_proxy() const {
return quota_manager_proxy_.get();
}
bool IsDatabaseScheduledForDeletion(const std::string& origin_identifier,
const base::string16& database_name);
int DeleteDatabase(const std::string& origin_identifier,
const base::string16& database_name,
const net::CompletionCallback& callback);
int DeleteDataModifiedSince(const base::Time& cutoff,
const net::CompletionCallback& callback);
virtual int DeleteDataForOrigin(const std::string& origin_identifier,
const net::CompletionCallback& callback);
bool IsIncognitoProfile() const { return is_incognito_; }
void GetIncognitoFileHandle(const base::string16& vfs_file_path,
base::PlatformFile* file_handle) const;
void SaveIncognitoFileHandle(const base::string16& vfs_file_path,
const base::PlatformFile& file_handle);
bool CloseIncognitoFileHandle(const base::string16& vfs_file_path);
bool HasSavedIncognitoFileHandle(const base::string16& vfs_file_path) const;
void Shutdown();
void SetForceKeepSessionState();
private:
friend class base::RefCountedThreadSafe<DatabaseTracker>;
friend class MockDatabaseTracker;
typedef std::map<std::string, std::set<base::string16> > DatabaseSet;
typedef std::vector<std::pair<net::CompletionCallback, DatabaseSet> >
PendingDeletionCallbacks;
typedef std::map<base::string16, base::PlatformFile> FileHandlesMap;
typedef std::map<std::string, base::string16> OriginDirectoriesMap;
class CachedOriginInfo : public OriginInfo {
public:
CachedOriginInfo() : OriginInfo(std::string(), 0) {}
void SetOriginIdentifier(const std::string& origin_identifier) {
origin_identifier_ = origin_identifier;
}
void SetDatabaseSize(const base::string16& database_name, int64 new_size) {
int64 old_size = 0;
if (database_info_.find(database_name) != database_info_.end())
old_size = database_info_[database_name].first;
database_info_[database_name].first = new_size;
if (new_size != old_size)
total_size_ += new_size - old_size;
}
void SetDatabaseDescription(const base::string16& database_name,
const base::string16& description) {
database_info_[database_name].second = description;
}
};
virtual ~DatabaseTracker();
void DeleteIncognitoDBDirectory();
void ClearSessionOnlyOrigins();
bool DeleteClosedDatabase(const std::string& origin_identifier,
const base::string16& database_name);
bool DeleteOrigin(const std::string& origin_identifier, bool force);
void DeleteDatabaseIfNeeded(const std::string& origin_identifier,
const base::string16& database_name);
bool LazyInit();
bool UpgradeToCurrentVersion();
void InsertOrUpdateDatabaseDetails(const std::string& origin_identifier,
const base::string16& database_name,
const base::string16& database_details,
int64 estimated_size);
void ClearAllCachedOriginInfo();
CachedOriginInfo* MaybeGetCachedOriginInfo(
const std::string& origin_identifier,
bool create_if_needed);
CachedOriginInfo* GetCachedOriginInfo(
const std::string& origin_identifier) {
return MaybeGetCachedOriginInfo(origin_identifier, true);
}
int64 GetDBFileSize(const std::string& origin_identifier,
const base::string16& database_name);
int64 SeedOpenDatabaseInfo(const std::string& origin_identifier,
const base::string16& database_name,
const base::string16& description);
int64 UpdateOpenDatabaseInfoAndNotify(const std::string& origin_identifier,
const base::string16& database_name,
const base::string16* opt_description);
int64 UpdateOpenDatabaseSizeAndNotify(const std::string& origin_identifier,
const base::string16& database_name) {
return UpdateOpenDatabaseInfoAndNotify(
origin_identifier, database_name, NULL);
}
void ScheduleDatabaseForDeletion(const std::string& origin_identifier,
const base::string16& database_name);
void ScheduleDatabasesForDeletion(const DatabaseSet& databases,
const net::CompletionCallback& callback);
base::string16 GetOriginDirectory(const std::string& origin_identifier);
bool is_initialized_;
const bool is_incognito_;
bool force_keep_session_state_;
bool shutting_down_;
const base::FilePath profile_path_;
const base::FilePath db_dir_;
scoped_ptr<sql::Connection> db_;
scoped_ptr<DatabasesTable> databases_table_;
scoped_ptr<sql::MetaTable> meta_table_;
ObserverList<Observer, true> observers_;
std::map<std::string, CachedOriginInfo> origins_info_map_;
DatabaseConnections database_connections_;
DatabaseSet dbs_to_be_deleted_;
PendingDeletionCallbacks deletion_callbacks_;
scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy_;
scoped_refptr<quota::QuotaManagerProxy> quota_manager_proxy_;
scoped_refptr<base::MessageLoopProxy> db_tracker_thread_;
FileHandlesMap incognito_file_handles_;
OriginDirectoriesMap incognito_origin_directories_;
int incognito_origin_directories_generator_;
FRIEND_TEST_ALL_PREFIXES(DatabaseTracker, TestHelper);
};
}
#endif