Delete HTML5 database in BrowsingDataRemover, part 1.

This part deletes databases except for when they're currently used by a renderer.

BUG=34633
TEST=open the webkit html5 database demo, create some notes. close the tab. clear browsing data. open the demo again. notes should be gone.

Review URL: http://codereview.chromium.org/570032

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38296 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index db2a310e..9fecc88 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -259,8 +259,7 @@
   SQLitePersistentCookieStore::ClearLocalState(profile_path.Append(
       chrome::kCookieFilename));
   DOMStorageContext::ClearLocalState(profile_path, chrome::kExtensionScheme);
-  webkit_database::DatabaseTracker::ClearLocalState(profile_path,
-      chrome::kExtensionScheme);
+  webkit_database::DatabaseTracker::ClearLocalState(profile_path);
   ChromeAppCacheService::ClearLocalState(profile_path);
 }
 
diff --git a/chrome/browser/browsing_data_remover.cc b/chrome/browser/browsing_data_remover.cc
index 37b4cd4..312297f 100644
--- a/chrome/browser/browsing_data_remover.cc
+++ b/chrome/browser/browsing_data_remover.cc
@@ -19,9 +19,11 @@
 #include "chrome/common/notification_service.h"
 #include "chrome/common/url_constants.h"
 #include "net/base/cookie_monster.h"
+#include "net/base/net_errors.h"
 #include "net/disk_cache/disk_cache.h"
 #include "net/http/http_cache.h"
 #include "net/url_request/url_request_context.h"
+#include "webkit/database/database_tracker.h"
 #include "webkit/glue/password_form.h"
 
 // Done so that we can use PostTask on BrowsingDataRemovers and not have
@@ -40,6 +42,9 @@
     : profile_(profile),
       delete_begin_(delete_begin),
       delete_end_(delete_end),
+      ALLOW_THIS_IN_INITIALIZER_LIST(database_cleared_callback_(
+          this, &BrowsingDataRemover::OnClearedDatabases)),
+      waiting_for_clear_databases_(false),
       waiting_for_clear_history_(false),
       waiting_for_clear_cache_(false) {
   DCHECK(profile);
@@ -51,6 +56,9 @@
     : profile_(profile),
       delete_begin_(CalculateBeginDeleteTime(time_period)),
       delete_end_(delete_end),
+      ALLOW_THIS_IN_INITIALIZER_LIST(database_cleared_callback_(
+          this, &BrowsingDataRemover::OnClearedDatabases)),
+      waiting_for_clear_databases_(false),
       waiting_for_clear_history_(false),
       waiting_for_clear_cache_(false) {
   DCHECK(profile);
@@ -115,6 +123,17 @@
       cookie_monster->DeleteAllCreatedBetween(delete_begin_, delete_end_, true);
     profile_->GetWebKitContext()->DeleteDataModifiedSince(
         delete_begin_, chrome::kExtensionScheme);
+
+    database_tracker_ = profile_->GetDatabaseTracker();
+    if (database_tracker_.get()) {
+      waiting_for_clear_databases_ = true;
+      ChromeThread::PostTask(
+          ChromeThread::FILE, FROM_HERE,
+          NewRunnableMethod(
+              this,
+              &BrowsingDataRemover::ClearDatabasesOnFILEThread,
+              delete_begin_));
+    }
   }
 
   if (remove_mask & REMOVE_PASSWORDS) {
@@ -276,3 +295,28 @@
       ChromeThread::UI, FROM_HERE,
       NewRunnableMethod(this, &BrowsingDataRemover::ClearedCache));
 }
+
+void BrowsingDataRemover::OnClearedDatabases(int rv) {
+  if (!ChromeThread::CurrentlyOn(ChromeThread::UI)) {
+    bool result = ChromeThread::PostTask(
+        ChromeThread::UI, FROM_HERE,
+        NewRunnableMethod(this, &BrowsingDataRemover::OnClearedDatabases, rv));
+    DCHECK(result);
+    return;
+  }
+  // Notify the UI thread that we are done.
+  database_tracker_ = NULL;
+  waiting_for_clear_databases_ = false;
+
+  NotifyAndDeleteIfDone();
+}
+
+void BrowsingDataRemover::ClearDatabasesOnFILEThread(base::Time delete_begin) {
+  // This function should be called on the FILE thread.
+  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
+
+  int rv = database_tracker_->DeleteDataModifiedSince(
+      delete_begin, &database_cleared_callback_);
+  if (rv != net::ERR_IO_PENDING)
+    OnClearedDatabases(rv);
+}
diff --git a/chrome/browser/browsing_data_remover.h b/chrome/browser/browsing_data_remover.h
index 8fccfe03..1a9d5fa 100644
--- a/chrome/browser/browsing_data_remover.h
+++ b/chrome/browser/browsing_data_remover.h
@@ -6,9 +6,11 @@
 #define CHROME_BROWSER_BROWSING_DATA_REMOVER_H_
 
 #include "base/observer_list.h"
+#include "base/scoped_ptr.h"
 #include "base/time.h"
 #include "chrome/browser/cancelable_request.h"
 #include "chrome/common/notification_registrar.h"
+#include "webkit/database/database_tracker.h"
 
 class Profile;
 class URLRequestContextGetter;
@@ -94,13 +96,20 @@
                             base::Time delete_begin,
                             base::Time delete_end);
 
+  // Callback when HTML5 databases have been deleted. Invokes
+  // NotifyAndDeleteIfDone.
+  void OnClearedDatabases(int rv);
+
+  // Invoked on the FILE thread to delete HTML5 databases.
+  void ClearDatabasesOnFILEThread(base::Time delete_begin);
+
   // Calculate the begin time for the deletion range specified by |time_period|.
   base::Time CalculateBeginDeleteTime(TimePeriod time_period);
 
   // Returns true if we're all done.
   bool all_done() {
     return registrar_.IsEmpty() && !waiting_for_clear_cache_ &&
-           !waiting_for_clear_history_;
+           !waiting_for_clear_history_ && !waiting_for_clear_databases_;
   }
 
   NotificationRegistrar registrar_;
@@ -117,6 +126,14 @@
   // True if Remove has been invoked.
   static bool removing_;
 
+  // Reference to database tracker held while deleting databases.
+  scoped_refptr<webkit_database::DatabaseTracker> database_tracker_;
+
+  net::CompletionCallbackImpl<BrowsingDataRemover> database_cleared_callback_;
+
+  // True if we're waiting for HTML5 databases to be deleted.
+  bool waiting_for_clear_databases_;
+
   // True if we're waiting for the history to be deleted.
   bool waiting_for_clear_history_;