15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/database_message_filter.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/database_messages.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/user_metrics.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/result_codes.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/database/database_util.h"
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/database/vfs_backend.h"
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/quota/quota_manager.h"
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/quota/quota_manager_proxy.h"
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/database/database_identifier.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/sqlite/sqlite3.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_descriptor_posix.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::QuotaManager;
2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::QuotaStatusCode;
2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::DatabaseTracker;
3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::DatabaseUtil;
3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::VfsBackend;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kNumDeleteRetries = 2;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kDelayDeleteRetryMs = 100;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DatabaseMessageFilter::DatabaseMessageFilter(
4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::DatabaseTracker* db_tracker)
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : BrowserMessageFilter(DatabaseMsgStart),
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      db_tracker_(db_tracker),
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      observer_added_(false) {
46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(db_tracker_.get());
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DatabaseMessageFilter::OnChannelClosing() {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (observer_added_) {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observer_added_ = false;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BrowserThread::FILE, FROM_HERE,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DatabaseMessageFilter::RemoveObserver, this));
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DatabaseMessageFilter::AddObserver() {
59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  db_tracker_->AddObserver(this);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DatabaseMessageFilter::RemoveObserver() {
64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  db_tracker_->RemoveObserver(this);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the renderer process died without closing all databases,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // then we need to manually close those connections
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  db_tracker_->CloseDatabases(database_connections_);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  database_connections_.RemoveAllConnections();
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DatabaseMessageFilter::OverrideThreadForMessage(
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const IPC::Message& message,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::ID* thread) {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (message.type() == DatabaseHostMsg_GetSpaceAvailable::ID)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *thread = BrowserThread::IO;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (IPC_MESSAGE_CLASS(message) == DatabaseMsgStart)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *thread = BrowserThread::FILE;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (message.type() == DatabaseHostMsg_Opened::ID && !observer_added_) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observer_added_ = true;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BrowserThread::FILE, FROM_HERE,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DatabaseMessageFilter::AddObserver, this));
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool DatabaseMessageFilter::OnMessageReceived(const IPC::Message& message) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handled = true;
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(DatabaseMessageFilter, message)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_OpenFile,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    OnDatabaseOpenFile)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_DeleteFile,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    OnDatabaseDeleteFile)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_GetFileAttributes,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    OnDatabaseGetFileAttributes)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_GetFileSize,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    OnDatabaseGetFileSize)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER_DELAY_REPLY(DatabaseHostMsg_GetSpaceAvailable,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    OnDatabaseGetSpaceAvailable)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(DatabaseHostMsg_Opened, OnDatabaseOpened)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(DatabaseHostMsg_Modified, OnDatabaseModified)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(DatabaseHostMsg_Closed, OnDatabaseClosed)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(DatabaseHostMsg_HandleSqliteError, OnHandleSqliteError)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handled;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DatabaseMessageFilter::~DatabaseMessageFilter() {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void DatabaseMessageFilter::OnDatabaseOpenFile(
115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& vfs_file_name,
116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int desired_flags,
117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    IPC::Message* reply_msg) {
118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  base::File file;
12046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const base::File* tracked_file = NULL;
1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::string origin_identifier;
122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 database_name;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When in incognito mode, we want to make sure that all DB files are
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // removed when the incognito browser context goes away, so we add the
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SQLITE_OPEN_DELETEONCLOSE flag when opening all files, and keep
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // open handles to them in the database tracker to make sure they're
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // around for as long as needed.
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (vfs_file_name.empty()) {
130effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    file = VfsBackend::OpenTempFileInDirectory(db_tracker_->DatabaseDirectory(),
131effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                               desired_flags);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (DatabaseUtil::CrackVfsFileName(vfs_file_name, &origin_identifier,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            &database_name, NULL) &&
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             !db_tracker_->IsDatabaseScheduledForDeletion(origin_identifier,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                          database_name)) {
136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::FilePath db_file = DatabaseUtil::GetFullFilePathForVfsFile(
137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        db_tracker_.get(), vfs_file_name);
138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!db_file.empty()) {
139effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      if (db_tracker_->IsIncognitoProfile()) {
14046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        tracked_file = db_tracker_->GetIncognitoFile(vfs_file_name);
14146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        if (!tracked_file) {
142effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          file =
143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch              VfsBackend::OpenFile(db_file,
14446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                   desired_flags | SQLITE_OPEN_DELETEONCLOSE);
145effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          if (!(desired_flags & SQLITE_OPEN_DELETEONCLOSE)) {
14646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            tracked_file = db_tracker_->SaveIncognitoFile(vfs_file_name,
14746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                          file.Pass());
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
150effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      } else {
151effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        file = VfsBackend::OpenFile(db_file, desired_flags);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
153effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    }
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Then we duplicate the file handle to make it useable in the renderer
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // process. The original handle is closed, unless we saved it in the
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // database tracker.
15946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  IPC::PlatformFileForTransit target_handle =
16046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      IPC::InvalidPlatformFileForTransit();
161effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (file.IsValid()) {
162effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    target_handle = IPC::TakeFileHandleForProcess(file.Pass(), PeerHandle());
16346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  } else if (tracked_file) {
16446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    DCHECK(tracked_file->IsValid());
16546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    target_handle =
16646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        IPC::GetFileHandleForProcess(tracked_file->GetPlatformFile(),
16746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                     PeerHandle(), false);
168effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DatabaseHostMsg_OpenFile::WriteReplyParams(reply_msg, target_handle);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(reply_msg);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void DatabaseMessageFilter::OnDatabaseDeleteFile(
175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& vfs_file_name,
176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const bool& sync_dir,
177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    IPC::Message* reply_msg) {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DatabaseDeleteFile(vfs_file_name, sync_dir, reply_msg, kNumDeleteRetries);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void DatabaseMessageFilter::DatabaseDeleteFile(
182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& vfs_file_name,
183a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    bool sync_dir,
184a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    IPC::Message* reply_msg,
185a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int reschedule_count) {
186effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return an error if the file name is invalid or if the file could not
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be deleted after kNumDeleteRetries attempts.
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int error_code = SQLITE_IOERR_DELETE;
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath db_file =
192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_.get(), vfs_file_name);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!db_file.empty()) {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // In order to delete a journal file in incognito mode, we only need to
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // close the open handle to it that's stored in the database tracker.
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (db_tracker_->IsIncognitoProfile()) {
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const base::string16 wal_suffix(base::ASCIIToUTF16("-wal"));
198a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::string16 sqlite_suffix;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // WAL files can be deleted without having previously been opened.
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!db_tracker_->HasSavedIncognitoFileHandle(vfs_file_name) &&
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          DatabaseUtil::CrackVfsFileName(vfs_file_name,
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         NULL, NULL, &sqlite_suffix) &&
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sqlite_suffix == wal_suffix) {
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        error_code = SQLITE_OK;
20646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      } else {
20746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        db_tracker_->CloseIncognitoFileHandle(vfs_file_name);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        error_code = SQLITE_OK;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      error_code = VfsBackend::DeleteFile(db_file, sync_dir);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((error_code == SQLITE_IOERR_DELETE) && reschedule_count) {
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If the file could not be deleted, try again.
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::PostDelayedTask(
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          BrowserThread::FILE, FROM_HERE,
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&DatabaseMessageFilter::DatabaseDeleteFile, this,
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     vfs_file_name, sync_dir, reply_msg, reschedule_count - 1),
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::TimeDelta::FromMilliseconds(kDelayDeleteRetryMs));
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DatabaseHostMsg_DeleteFile::WriteReplyParams(reply_msg, error_code);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(reply_msg);
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DatabaseMessageFilter::OnDatabaseGetFileAttributes(
230a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& vfs_file_name,
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC::Message* reply_msg) {
232effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 attributes = -1;
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath db_file =
235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_.get(), vfs_file_name);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!db_file.empty())
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    attributes = VfsBackend::GetFileAttributes(db_file);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DatabaseHostMsg_GetFileAttributes::WriteReplyParams(
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reply_msg, attributes);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(reply_msg);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DatabaseMessageFilter::OnDatabaseGetFileSize(
245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& vfs_file_name, IPC::Message* reply_msg) {
246effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 size = 0;
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath db_file =
249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      DatabaseUtil::GetFullFilePathForVfsFile(db_tracker_.get(), vfs_file_name);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!db_file.empty())
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size = VfsBackend::GetFileSize(db_file);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DatabaseHostMsg_GetFileSize::WriteReplyParams(reply_msg, size);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(reply_msg);
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DatabaseMessageFilter::OnDatabaseGetSpaceAvailable(
2587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::string& origin_identifier, IPC::Message* reply_msg) {
259effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::IO);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(db_tracker_->quota_manager_proxy());
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuotaManager* quota_manager =
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      db_tracker_->quota_manager_proxy()->quota_manager();
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!quota_manager) {
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();  // The system is shutting down, messages are unexpected.
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DatabaseHostMsg_GetSpaceAvailable::WriteReplyParams(
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        reply_msg, static_cast<int64>(0));
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(reply_msg);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  quota_manager->GetUsageAndQuota(
27303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::GetOriginFromIdentifier(origin_identifier),
27403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::kStorageTypeTemporary,
27503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::Bind(
27603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          &DatabaseMessageFilter::OnDatabaseGetUsageAndQuota, this, reply_msg));
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DatabaseMessageFilter::OnDatabaseGetUsageAndQuota(
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC::Message* reply_msg,
28103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::QuotaStatusCode status,
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 usage,
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 quota) {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 available = 0;
28503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if ((status == storage::kQuotaStatusOk) && (usage < quota))
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    available = quota - usage;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DatabaseHostMsg_GetSpaceAvailable::WriteReplyParams(reply_msg, available);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(reply_msg);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void DatabaseMessageFilter::OnDatabaseOpened(
2927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::string& origin_identifier,
293a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& database_name,
294a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& description,
2957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    int64 estimated_size) {
296effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!DatabaseUtil::IsValidOriginIdentifier(origin_identifier)) {
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RecordAction(base::UserMetricsAction("BadMessageTerminate_DBMF"));
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BadMessageReceived();
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 database_size = 0;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  db_tracker_->DatabaseOpened(origin_identifier, database_name, description,
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              estimated_size, &database_size);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  database_connections_.AddConnection(origin_identifier, database_name);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new DatabaseMsg_UpdateSize(origin_identifier, database_name,
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  database_size));
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DatabaseMessageFilter::OnDatabaseModified(
3137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::string& origin_identifier,
314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& database_name) {
315effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!database_connections_.IsDatabaseOpened(
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          origin_identifier, database_name)) {
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RecordAction(base::UserMetricsAction("BadMessageTerminate_DBMF"));
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BadMessageReceived();
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  db_tracker_->DatabaseModified(origin_identifier, database_name);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void DatabaseMessageFilter::OnDatabaseClosed(
3277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::string& origin_identifier,
328a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& database_name) {
329effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!database_connections_.IsDatabaseOpened(
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          origin_identifier, database_name)) {
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RecordAction(base::UserMetricsAction("BadMessageTerminate_DBMF"));
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BadMessageReceived();
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  database_connections_.RemoveConnection(origin_identifier, database_name);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  db_tracker_->DatabaseClosed(origin_identifier, database_name);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DatabaseMessageFilter::OnHandleSqliteError(
3427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::string& origin_identifier,
343a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& database_name,
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int error) {
345effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!DatabaseUtil::IsValidOriginIdentifier(origin_identifier)) {
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RecordAction(base::UserMetricsAction("BadMessageTerminate_DBMF"));
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BadMessageReceived();
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  db_tracker_->HandleSqliteError(origin_identifier, database_name, error);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DatabaseMessageFilter::OnDatabaseSizeChanged(
3567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::string& origin_identifier,
357a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& database_name,
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 database_size) {
359effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (database_connections_.IsOriginUsed(origin_identifier)) {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new DatabaseMsg_UpdateSize(origin_identifier, database_name,
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    database_size));
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DatabaseMessageFilter::OnDatabaseScheduledForDeletion(
3677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::string& origin_identifier,
368a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& database_name) {
369effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new DatabaseMsg_CloseImmediately(origin_identifier, database_name));
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
374