database_message_filter.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
12538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar// Use of this source code is governed by a BSD-style license that can be
32538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar// found in the LICENSE file.
42538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
52538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar#include "content/browser/renderer_host/database_message_filter.h"
62538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
72538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar#include <string>
82538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
92538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar#include "base/bind.h"
102538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar#include "base/platform_file.h"
112538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar#include "base/string_util.h"
122538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar#include "base/threading/thread.h"
132538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar#include "base/utf_string_conversions.h"
148b67f774e9c38b7718b2b300b628388f966df4e0Chandler Carruth#include "content/common/database_messages.h"
152538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar#include "content/public/browser/user_metrics.h"
162538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar#include "content/public/common/result_codes.h"
172538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar#include "googleurl/src/gurl.h"
182538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
192538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar#include "third_party/sqlite/sqlite3.h"
202538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar#include "webkit/database/database_util.h"
212538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar#include "webkit/database/vfs_backend.h"
222538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar#include "webkit/quota/quota_manager.h"
232538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
242538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar#if defined(OS_POSIX)
252538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar#include "base/file_descriptor_posix.h"
262538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar#endif
272538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
282538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbarusing quota::QuotaManager;
292538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbarusing quota::QuotaManagerProxy;
302538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbarusing quota::QuotaStatusCode;
312538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbarusing WebKit::WebSecurityOrigin;
322538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbarusing webkit_database::DatabaseTracker;
332538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbarusing webkit_database::DatabaseUtil;
342538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbarusing webkit_database::VfsBackend;
352538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
362538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbarnamespace content {
372538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbarnamespace {
382538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
392538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbarconst int kNumDeleteRetries = 2;
402538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbarconst int kDelayDeleteRetryMs = 100;
412538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
422538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar}  // namespace
432538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
442538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel DunbarDatabaseMessageFilter::DatabaseMessageFilter(
452538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    webkit_database::DatabaseTracker* db_tracker)
462538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    : db_tracker_(db_tracker),
472538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar      observer_added_(false) {
482538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  DCHECK(db_tracker_);
492538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar}
502538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
512538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbarvoid DatabaseMessageFilter::OnChannelClosing() {
522538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  BrowserMessageFilter::OnChannelClosing();
532538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  if (observer_added_) {
542538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    observer_added_ = false;
552538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    BrowserThread::PostTask(
562538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar        BrowserThread::FILE, FROM_HERE,
572538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar        base::Bind(&DatabaseMessageFilter::RemoveObserver, this));
582538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  }
592538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar}
602538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
612538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbarvoid DatabaseMessageFilter::AddObserver() {
622538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
632538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  db_tracker_->AddObserver(this);
642538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar}
652538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
662538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbarvoid DatabaseMessageFilter::RemoveObserver() {
672538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
682538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  db_tracker_->RemoveObserver(this);
692538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
702538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  // If the renderer process died without closing all databases,
712538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  // then we need to manually close those connections
722538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  db_tracker_->CloseDatabases(database_connections_);
732538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  database_connections_.RemoveAllConnections();
742538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar}
752538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
762538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbarvoid DatabaseMessageFilter::OverrideThreadForMessage(
772538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    const IPC::Message& message,
782538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    BrowserThread::ID* thread) {
792538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  if (message.type() == DatabaseHostMsg_GetSpaceAvailable::ID)
802538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    *thread = BrowserThread::IO;
812538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  else if (IPC_MESSAGE_CLASS(message) == DatabaseMsgStart)
822538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    *thread = BrowserThread::FILE;
832538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
842538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  if (message.type() == DatabaseHostMsg_Opened::ID && !observer_added_) {
852538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    observer_added_ = true;
862538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    BrowserThread::PostTask(
872538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar        BrowserThread::FILE, FROM_HERE,
882538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar        base::Bind(&DatabaseMessageFilter::AddObserver, this));
892538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  }
90763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar}
91763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar
92763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbarbool DatabaseMessageFilter::OnMessageReceived(
932538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    const IPC::Message& message,
942538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    bool* message_was_ok) {
952538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  bool handled = true;
962538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  IPC_BEGIN_MESSAGE_MAP_EX(DatabaseMessageFilter, message, *message_was_ok)
972538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_OpenFile,
982538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar                                    OnDatabaseOpenFile)
992538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_DeleteFile,
1002538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar                                    OnDatabaseDeleteFile)
1012538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_GetFileAttributes,
1022d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar                                    OnDatabaseGetFileAttributes)
103763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar    IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_GetFileSize,
1042d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar                                    OnDatabaseGetFileSize)
105763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar    IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_GetSpaceAvailable,
1062d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar                                    OnDatabaseGetSpaceAvailable)
1072d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar    IPC_MESSAGE_HANDLER(DatabaseHostMsg_Opened, OnDatabaseOpened)
1080165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar    IPC_MESSAGE_HANDLER(DatabaseHostMsg_Modified, OnDatabaseModified)
1092d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar    IPC_MESSAGE_HANDLER(DatabaseHostMsg_Closed, OnDatabaseClosed)
110763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar    IPC_MESSAGE_HANDLER(DatabaseHostMsg_HandleSqliteError, OnHandleSqliteError)
1112d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar    IPC_MESSAGE_UNHANDLED(handled = false)
112763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar  IPC_END_MESSAGE_MAP_EX()
1132d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar  return handled;
1142d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar}
1152d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar
1162d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel DunbarDatabaseMessageFilter::~DatabaseMessageFilter() {
1172d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar}
1182d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar
1192d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbarvoid DatabaseMessageFilter::OnDatabaseOpenFile(const string16& vfs_file_name,
1202d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar                                               int desired_flags,
1212d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar                                               IPC::Message* reply_msg) {
1220165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
1230165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar  base::PlatformFile file_handle = base::kInvalidPlatformFileValue;
1240165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar  string16 origin_identifier;
1250165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar  string16 database_name;
1262538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
1272538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  // When in incognito mode, we want to make sure that all DB files are
1282538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  // removed when the incognito browser context goes away, so we add the
1292538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  // SQLITE_OPEN_DELETEONCLOSE flag when opening all files, and keep
1302538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  // open handles to them in the database tracker to make sure they're
1312538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  // around for as long as needed.
1322538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  if (vfs_file_name.empty()) {
1332538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    VfsBackend::OpenTempFileInDirectory(db_tracker_->DatabaseDirectory(),
1342538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar                                        desired_flags, &file_handle);
1352538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  } else if (DatabaseUtil::CrackVfsFileName(vfs_file_name, &origin_identifier,
1362538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar                                            &database_name, NULL) &&
1372538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar             !db_tracker_->IsDatabaseScheduledForDeletion(origin_identifier,
1382538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar                                                          database_name)) {
1392538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar      base::FilePath db_file =
1402538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar          DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name);
1412538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar      if (!db_file.empty()) {
1422538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar        if (db_tracker_->IsIncognitoProfile()) {
1432538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar          db_tracker_->GetIncognitoFileHandle(vfs_file_name, &file_handle);
1442538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar          if (file_handle == base::kInvalidPlatformFileValue) {
1452538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar            VfsBackend::OpenFile(db_file,
1462538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar                                 desired_flags | SQLITE_OPEN_DELETEONCLOSE,
1472538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar                                 &file_handle);
1482538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar            if (!(desired_flags & SQLITE_OPEN_DELETEONCLOSE))
1492538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar              db_tracker_->SaveIncognitoFileHandle(vfs_file_name, file_handle);
1502538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar          }
1512538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar        } else {
1522538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar          VfsBackend::OpenFile(db_file, desired_flags, &file_handle);
1532538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar        }
154050578fb4a006d7a183662f83fc22f7c78475605Daniel Dunbar      }
155050578fb4a006d7a183662f83fc22f7c78475605Daniel Dunbar  }
1562538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
1572538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  // Then we duplicate the file handle to make it useable in the renderer
1582538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  // process. The original handle is closed, unless we saved it in the
1592538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  // database tracker.
1602538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  bool auto_close = !db_tracker_->HasSavedIncognitoFileHandle(vfs_file_name);
1612538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  IPC::PlatformFileForTransit target_handle =
1622538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar      IPC::GetFileHandleForProcess(file_handle, peer_handle(), auto_close);
1632538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
1642538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  DatabaseHostMsg_OpenFile::WriteReplyParams(reply_msg, target_handle);
1652538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  Send(reply_msg);
1662538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar}
1672538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
1682538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbarvoid DatabaseMessageFilter::OnDatabaseDeleteFile(const string16& vfs_file_name,
1692538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar                                                 const bool& sync_dir,
1702538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar                                                 IPC::Message* reply_msg) {
1712538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  DatabaseDeleteFile(vfs_file_name, sync_dir, reply_msg, kNumDeleteRetries);
1722538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar}
1732538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
1742538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbarvoid DatabaseMessageFilter::DatabaseDeleteFile(const string16& vfs_file_name,
1752538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar                                               bool sync_dir,
1762538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar                                               IPC::Message* reply_msg,
1772538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar                                               int reschedule_count) {
1782538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
1792538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
1802538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  // Return an error if the file name is invalid or if the file could not
1812538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  // be deleted after kNumDeleteRetries attempts.
1822538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  int error_code = SQLITE_IOERR_DELETE;
1832538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  base::FilePath db_file =
1842538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar      DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name);
1852538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  if (!db_file.empty()) {
1862538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    // In order to delete a journal file in incognito mode, we only need to
1872538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    // close the open handle to it that's stored in the database tracker.
1882538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    if (db_tracker_->IsIncognitoProfile()) {
1892538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar      const string16 wal_suffix(ASCIIToUTF16("-wal"));
1902538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar      string16 sqlite_suffix;
1912538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
1922538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar      // WAL files can be deleted without having previously been opened.
1932538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar      if (!db_tracker_->HasSavedIncognitoFileHandle(vfs_file_name) &&
1942538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar          DatabaseUtil::CrackVfsFileName(vfs_file_name,
1952538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar                                         NULL, NULL, &sqlite_suffix) &&
1962538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar          sqlite_suffix == wal_suffix) {
1972538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar        error_code = SQLITE_OK;
1982538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar      } else if (db_tracker_->CloseIncognitoFileHandle(vfs_file_name)) {
1992538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar        error_code = SQLITE_OK;
2002538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar      }
2012538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    } else {
2022538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar      error_code = VfsBackend::DeleteFile(db_file, sync_dir);
2032538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    }
2042538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
2052538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    if ((error_code == SQLITE_IOERR_DELETE) && reschedule_count) {
2062538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar      // If the file could not be deleted, try again.
2072538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar      BrowserThread::PostDelayedTask(
2082538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar          BrowserThread::FILE, FROM_HERE,
2092538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar          base::Bind(&DatabaseMessageFilter::DatabaseDeleteFile, this,
2102538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar                     vfs_file_name, sync_dir, reply_msg, reschedule_count - 1),
2112538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar          base::TimeDelta::FromMilliseconds(kDelayDeleteRetryMs));
2122538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar      return;
2132538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    }
2142538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  }
2152538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
2162538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  DatabaseHostMsg_DeleteFile::WriteReplyParams(reply_msg, error_code);
2172538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  Send(reply_msg);
2182538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar}
2192538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
2202538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbarvoid DatabaseMessageFilter::OnDatabaseGetFileAttributes(
2212538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    const string16& vfs_file_name,
2222538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    IPC::Message* reply_msg) {
2232538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
2242538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  int32 attributes = -1;
2252538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  base::FilePath db_file =
2262538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar      DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name);
2272538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  if (!db_file.empty())
2282538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    attributes = VfsBackend::GetFileAttributes(db_file);
2292538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
2302538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  DatabaseHostMsg_GetFileAttributes::WriteReplyParams(
2312538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar      reply_msg, attributes);
2322538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  Send(reply_msg);
2332538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar}
2342538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
2352538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbarvoid DatabaseMessageFilter::OnDatabaseGetFileSize(
2362538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    const string16& vfs_file_name, IPC::Message* reply_msg) {
2372538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
2382538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  int64 size = 0;
2392538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  base::FilePath db_file =
2402538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar      DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_, vfs_file_name);
2412538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  if (!db_file.empty())
2422538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    size = VfsBackend::GetFileSize(db_file);
2432538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
2442538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  DatabaseHostMsg_GetFileSize::WriteReplyParams(reply_msg, size);
2452538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  Send(reply_msg);
2462538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar}
2472538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
2482538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbarvoid DatabaseMessageFilter::OnDatabaseGetSpaceAvailable(
2492538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    const string16& origin_identifier, IPC::Message* reply_msg) {
2502538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2512538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  DCHECK(db_tracker_->quota_manager_proxy());
2522538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
2532538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  QuotaManager* quota_manager =
2542538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar      db_tracker_->quota_manager_proxy()->quota_manager();
2552538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  if (!quota_manager) {
2562538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    NOTREACHED();  // The system is shutting down, messages are unexpected.
2572538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    DatabaseHostMsg_GetSpaceAvailable::WriteReplyParams(
2582538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar        reply_msg, static_cast<int64>(0));
2592538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    Send(reply_msg);
2602538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    return;
2610165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar  }
2622d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar
2632d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar  quota_manager->GetUsageAndQuota(
2642d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar      DatabaseUtil::GetOriginFromIdentifier(origin_identifier),
2652d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar      quota::kStorageTypeTemporary,
2662d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar      base::Bind(&DatabaseMessageFilter::OnDatabaseGetUsageAndQuota,
2672d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar                 this, reply_msg));
2682d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar}
2692d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar
2702d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbarvoid DatabaseMessageFilter::OnDatabaseGetUsageAndQuota(
2712d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar    IPC::Message* reply_msg,
2722d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar    quota::QuotaStatusCode status,
2732d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar    int64 usage,
2740165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar    int64 quota) {
2750165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar  int64 available = 0;
2760165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar  if ((status == quota::kQuotaStatusOk) && (usage < quota))
2772d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar    available = quota - usage;
2782d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar  DatabaseHostMsg_GetSpaceAvailable::WriteReplyParams(reply_msg, available);
2790165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar  Send(reply_msg);
2800165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar}
2810165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar
2822d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbarvoid DatabaseMessageFilter::OnDatabaseOpened(const string16& origin_identifier,
2832d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar                                             const string16& database_name,
2840165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar                                             const string16& description,
2850165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar                                             int64 estimated_size) {
2860165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
2872d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar
2882d8bc0fe70c55664b89605dbfa5c2f591446469cDaniel Dunbar  if (!DatabaseUtil::IsValidOriginIdentifier(origin_identifier)) {
2890165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar    RecordAction(UserMetricsAction("BadMessageTerminate_DBMF"));
2900165a2ca897598bb95baec031362921565e24f2bDaniel Dunbar    BadMessageReceived();
2912538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    return;
2922538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  }
2932538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
2942538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  int64 database_size = 0;
2952538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  db_tracker_->DatabaseOpened(origin_identifier, database_name, description,
2962538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar                              estimated_size, &database_size);
2972538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  database_connections_.AddConnection(origin_identifier, database_name);
2982538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  Send(new DatabaseMsg_UpdateSize(origin_identifier, database_name,
2992538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar                                  database_size));
3002538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar}
3012538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
3022538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbarvoid DatabaseMessageFilter::OnDatabaseModified(
3032538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    const string16& origin_identifier,
3042538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    const string16& database_name) {
3052538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
3062538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  if (!database_connections_.IsDatabaseOpened(
3072538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar          origin_identifier, database_name)) {
308763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar    RecordAction(UserMetricsAction("BadMessageTerminate_DBMF"));
309763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar    BadMessageReceived();
310763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar    return;
311763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar  }
312763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar
313763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar  db_tracker_->DatabaseModified(origin_identifier, database_name);
314763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar}
315763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar
316763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbarvoid DatabaseMessageFilter::OnDatabaseClosed(const string16& origin_identifier,
317763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar                                             const string16& database_name) {
318763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
319763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar  if (!database_connections_.IsDatabaseOpened(
320763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar          origin_identifier, database_name)) {
321763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar    RecordAction(UserMetricsAction("BadMessageTerminate_DBMF"));
322763457e70bc9c5c2def89d24a133808b8a971f9fDaniel Dunbar    BadMessageReceived();
3232538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    return;
3245149932068f535e1ff13b91c9669f55718c60a07Daniel Dunbar  }
3255149932068f535e1ff13b91c9669f55718c60a07Daniel Dunbar
3265149932068f535e1ff13b91c9669f55718c60a07Daniel Dunbar  database_connections_.RemoveConnection(origin_identifier, database_name);
3275149932068f535e1ff13b91c9669f55718c60a07Daniel Dunbar  db_tracker_->DatabaseClosed(origin_identifier, database_name);
3285149932068f535e1ff13b91c9669f55718c60a07Daniel Dunbar}
3295149932068f535e1ff13b91c9669f55718c60a07Daniel Dunbar
3305149932068f535e1ff13b91c9669f55718c60a07Daniel Dunbarvoid DatabaseMessageFilter::OnHandleSqliteError(
3315149932068f535e1ff13b91c9669f55718c60a07Daniel Dunbar    const string16& origin_identifier,
3325149932068f535e1ff13b91c9669f55718c60a07Daniel Dunbar    const string16& database_name,
3335149932068f535e1ff13b91c9669f55718c60a07Daniel Dunbar    int error) {
3342538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
3352538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  if (!DatabaseUtil::IsValidOriginIdentifier(origin_identifier)) {
3362538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    RecordAction(UserMetricsAction("BadMessageTerminate_DBMF"));
3372538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    BadMessageReceived();
3382538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    return;
3392538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  }
3402538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
3412538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  db_tracker_->HandleSqliteError(origin_identifier, database_name, error);
3422538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar}
3432538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
3442538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbarvoid DatabaseMessageFilter::OnDatabaseSizeChanged(
3452538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    const string16& origin_identifier,
3462538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    const string16& database_name,
3472538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    int64 database_size) {
3482538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
3492538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  if (database_connections_.IsOriginUsed(origin_identifier)) {
3502538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    Send(new DatabaseMsg_UpdateSize(origin_identifier, database_name,
3512538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar                                    database_size));
3522538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  }
3532538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar}
3542538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
3552538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbarvoid DatabaseMessageFilter::OnDatabaseScheduledForDeletion(
3562538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    const string16& origin_identifier,
3572538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar    const string16& database_name) {
3582538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
3592538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar  Send(new DatabaseMsg_CloseImmediately(origin_identifier, database_name));
3602538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar}
3612538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar
3622538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar}  // namespace content
3632538f7ab2ef39ab1a5e48744548d66b560d1fee6Daniel Dunbar