Revert 100017 - broke ProfileManagerTest.CreateProfileAsyncMultipleRequests
on Linux Tests (Views) (dbg).

r100017 was: Make a new integer field in sql::MetaTable (a per-profile db) containing a counter for the next download id, so that this id is unique across sessions. This id will allow us to merge download id with db_handle and merge most/all of the maps in DownloadManager in future CLs.

(Retry of r98656 again. That CL included <iostream> in a "promiscuous" header file, dramatically increasing the number of static initializers, and was reverted. This is the same CL, but includes <iosfwd> instead of <iostream>.)

Make DownloadManager read this field to initialize its next_id_ counter in Init().

Put a fine-grained mutex in DownloadManager::GetNextId() so that it can be called directly from any thread.
Define a thunk wrapping DM::GNI() to be passed around between threads to guard against other threads calling any other DM methods.

This thunk owns a scoped_refptr<DM> to manage life-time issues. This pattern is implemented for DM elsewhere.
Store this thunk in ResourceContext to be called by ResourceDispatchHost/DownloadThrottlingResourceHandler on the IO thread. Pass the returned DownloadId into DownloadResourceHandler.

The alternative way to obtain ids on the IO thread is to jump over to the UI thread and back. This way would add significant latency to a critical path. GetNextId() should be fast and easily accessible from any thread.

Now that ids are per-profile, define a class DownloadId containing a per-profile id and an indication of which profile, currently the DownloadManager*. DownloadIds are hashable, comparable, globally unique, not persistent, and are used by DownloadFileManager.

When the download is added to the history, MetaTable.next_download_id will be set to the new download's id +1 if that number is greater than MT.next_download_id. Increasing this counter at the same time as the download is added to the db prevents the counter from desyncing from the db, which was the primary concern re storing the counter in the BrowserPrefs.

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

[email protected]
Review URL: http://codereview.chromium.org/7847006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@100054 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/download/chrome_download_manager_delegate.cc b/chrome/browser/download/chrome_download_manager_delegate.cc
index 3e992ba..2fd34ca7 100644
--- a/chrome/browser/download/chrome_download_manager_delegate.cc
+++ b/chrome/browser/download/chrome_download_manager_delegate.cc
@@ -60,8 +60,6 @@
   download_history_.reset(new DownloadHistory(profile_));
   download_history_->Load(
       NewCallback(dm, &DownloadManager::OnPersistentStoreQueryComplete));
-  download_history_->GetNextId(
-      NewCallback(dm, &DownloadManager::OnPersistentStoreGetNextId));
 }
 
 void ChromeDownloadManagerDelegate::Shutdown() {
diff --git a/chrome/browser/download/download_history.cc b/chrome/browser/download/download_history.cc
index 426a434..3da198b 100644
--- a/chrome/browser/download/download_history.cc
+++ b/chrome/browser/download/download_history.cc
@@ -27,17 +27,6 @@
     delete i->second.second;
 }
 
-void DownloadHistory::GetNextId(
-    HistoryService::DownloadNextIdCallback* callback) {
-  DCHECK(callback);
-  HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
-  if (!hs) {
-    delete callback;
-    return;
-  }
-  hs->GetNextDownloadId(&history_consumer_, callback);
-}
-
 void DownloadHistory::Load(HistoryService::DownloadQueryCallback* callback) {
   DCHECK(callback);
   HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
diff --git a/chrome/browser/download/download_history.h b/chrome/browser/download/download_history.h
index 45f978b..6d6b237 100644
--- a/chrome/browser/download/download_history.h
+++ b/chrome/browser/download/download_history.h
@@ -27,11 +27,6 @@
   explicit DownloadHistory(Profile* profile);
   ~DownloadHistory();
 
-  // Retrieves the next_id counter from the sql meta_table.
-  // Should be much faster than Load so that we may delay downloads until after
-  // this call with minimal performance penalty.
-  void GetNextId(HistoryService::DownloadNextIdCallback* callback);
-
   // Retrieves DownloadCreateInfos saved in the history.
   void Load(HistoryService::DownloadQueryCallback* callback);
 
diff --git a/chrome/browser/download/download_manager_unittest.cc b/chrome/browser/download/download_manager_unittest.cc
index 5c578a8..3380046c 100644
--- a/chrome/browser/download/download_manager_unittest.cc
+++ b/chrome/browser/download/download_manager_unittest.cc
@@ -10,8 +10,8 @@
 #include "base/i18n/rtl.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/stl_util.h"
-#include "base/string16.h"
 #include "base/string_util.h"
+#include "base/string16.h"
 #include "base/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "chrome/browser/download/chrome_download_manager_delegate.h"
@@ -66,8 +66,7 @@
   }
 
   void AddDownloadToFileManager(int id, DownloadFile* download_file) {
-    file_manager()->downloads_[DownloadId(download_manager_.get(), id)] =
-      download_file;
+    file_manager()->downloads_[id] = download_file;
   }
 
   void OnResponseCompleted(int32 download_id, int64 size,
@@ -101,7 +100,7 @@
         BrowserThread::FILE, FROM_HERE,
         NewRunnableMethod(file_manager_.get(),
                           &DownloadFileManager::UpdateDownload,
-                          DownloadId(download_manager_.get(), id),
+                          id,
                           &download_buffer_));
 
     message_loop_.RunAllPending();
diff --git a/chrome/browser/download/download_throttling_resource_handler.cc b/chrome/browser/download/download_throttling_resource_handler.cc
index 3478d54..403306f 100644
--- a/chrome/browser/download/download_throttling_resource_handler.cc
+++ b/chrome/browser/download/download_throttling_resource_handler.cc
@@ -5,12 +5,8 @@
 #include "chrome/browser/download/download_throttling_resource_handler.h"
 
 #include "base/logging.h"
-#include "content/browser/download/download_id.h"
-#include "content/browser/download/download_resource_handler.h"
 #include "content/browser/download/download_stats.h"
 #include "content/browser/renderer_host/resource_dispatcher_host.h"
-#include "content/browser/renderer_host/resource_dispatcher_host_request_info.h"
-#include "content/browser/resource_context.h"
 #include "content/common/resource_response.h"
 #include "net/base/io_buffer.h"
 #include "net/base/mime_sniffer.h"
diff --git a/chrome/browser/download/download_util.h b/chrome/browser/download/download_util.h
index f71590a..05533d7 100644
--- a/chrome/browser/download/download_util.h
+++ b/chrome/browser/download/download_util.h
@@ -23,6 +23,7 @@
 class BaseDownloadItemModel;
 class CrxInstaller;
 class DownloadItem;
+class DownloadManager;
 class GURL;
 class Profile;
 class ResourceDispatcherHost;
diff --git a/chrome/browser/history/download_database.cc b/chrome/browser/history/download_database.cc
index ccaed51b..906ac83 100644
--- a/chrome/browser/history/download_database.cc
+++ b/chrome/browser/history/download_database.cc
@@ -52,14 +52,9 @@
 
 #endif
 
-// Key in the meta_table containing the next id to use for a new download in
-// this profile.
-static const char kNextDownloadId[] = "next_download_id";
-
 }  // namespace
 
-DownloadDatabase::DownloadDatabase()
-  : next_id_(0) {
+DownloadDatabase::DownloadDatabase() {
 }
 
 DownloadDatabase::~DownloadDatabase() {
@@ -78,8 +73,6 @@
         "state INTEGER NOT NULL)"))
       return false;
   }
-  meta_table_.Init(&GetDB(), 0, 0);
-  meta_table_.GetValue(kNextDownloadId, &next_id_);
   return true;
 }
 
@@ -168,12 +161,8 @@
   statement.BindInt64(4, info.total_bytes);
   statement.BindInt(5, info.state);
 
-  if (statement.Run()) {
-    int64 db_handle = GetDB().GetLastInsertRowId();
-    // TODO(benjhayden) if(info.id>next_id_){setvalue;next_id_=info.id;}
-    meta_table_.SetValue(kNextDownloadId, ++next_id_);
-    return db_handle;
-  }
+  if (statement.Run())
+    return GetDB().GetLastInsertRowId();
   return 0;
 }
 
diff --git a/chrome/browser/history/download_database.h b/chrome/browser/history/download_database.h
index 8f97e55..c77500c 100644
--- a/chrome/browser/history/download_database.h
+++ b/chrome/browser/history/download_database.h
@@ -7,7 +7,6 @@
 #pragma once
 
 #include "chrome/browser/history/history_types.h"
-#include "sql/meta_table.h"
 
 struct DownloadPersistentStoreInfo;
 class FilePath;
@@ -25,8 +24,6 @@
   DownloadDatabase();
   virtual ~DownloadDatabase();
 
-  int next_download_id() const { return next_id_; }
-
   // Get all the downloads from the database.
   void QueryDownloads(std::vector<DownloadPersistentStoreInfo>* results);
 
@@ -66,9 +63,6 @@
   bool DropDownloadTable();
 
  private:
-  int next_id_;
-  sql::MetaTable meta_table_;
-
   DISALLOW_COPY_AND_ASSIGN(DownloadDatabase);
 };
 
diff --git a/chrome/browser/history/history.cc b/chrome/browser/history/history.cc
index 6b62b89..cdab352d 100644
--- a/chrome/browser/history/history.cc
+++ b/chrome/browser/history/history.cc
@@ -511,13 +511,6 @@
                   create_info);
 }
 
-HistoryService::Handle HistoryService::GetNextDownloadId(
-    CancelableRequestConsumerBase* consumer,
-    DownloadNextIdCallback* callback) {
-  return Schedule(PRIORITY_NORMAL, &HistoryBackend::GetNextDownloadId, consumer,
-                  new history::DownloadNextIdRequest(callback));
-}
-
 // Handle queries for a list of all downloads in the history database's
 // 'downloads' table.
 HistoryService::Handle HistoryService::QueryDownloads(
diff --git a/chrome/browser/history/history.h b/chrome/browser/history/history.h
index 0a09a6a..120d764e9 100644
--- a/chrome/browser/history/history.h
+++ b/chrome/browser/history/history.h
@@ -423,13 +423,6 @@
                         CancelableRequestConsumerBase* consumer,
                         DownloadCreateCallback* callback);
 
-  // Implemented by the caller of 'GetNextDownloadId' below.
-  typedef Callback1<int/*next_download_id*/>::Type DownloadNextIdCallback;
-
-  // Runs the callback with the next available download id.
-  Handle GetNextDownloadId(CancelableRequestConsumerBase* consumer,
-                           DownloadNextIdCallback* callback);
-
   // Implemented by the caller of 'QueryDownloads' below, and is called when the
   // history service has retrieved a list of all download state. The call
   typedef Callback1<std::vector<DownloadPersistentStoreInfo>*>::Type
diff --git a/chrome/browser/history/history_backend.cc b/chrome/browser/history/history_backend.cc
index 4ca4e0f..f1ff383c 100644
--- a/chrome/browser/history/history_backend.cc
+++ b/chrome/browser/history/history_backend.cc
@@ -1076,17 +1076,6 @@
 
 // Downloads -------------------------------------------------------------------
 
-void HistoryBackend::GetNextDownloadId(
-    scoped_refptr<DownloadNextIdRequest> request) {
-  if (request->canceled()) return;
-  if (db_.get()) {
-    request->value = db_->next_download_id();
-  } else {
-    request->value = 0;
-  }
-  request->ForwardResult(DownloadNextIdRequest::TupleType(request->value));
-}
-
 // Get all the download entries from the database.
 void HistoryBackend::QueryDownloads(
     scoped_refptr<DownloadQueryRequest> request) {
diff --git a/chrome/browser/history/history_backend.h b/chrome/browser/history/history_backend.h
index c9c3096..a7c7317 100644
--- a/chrome/browser/history/history_backend.h
+++ b/chrome/browser/history/history_backend.h
@@ -236,7 +236,6 @@
 
   // Downloads -----------------------------------------------------------------
 
-  void GetNextDownloadId(scoped_refptr<DownloadNextIdRequest> request);
   void QueryDownloads(scoped_refptr<DownloadQueryRequest> request);
   void CleanUpInProgressEntries();
   void UpdateDownload(int64 received_bytes, int32 state, int64 db_handle);
diff --git a/chrome/browser/history/history_marshaling.h b/chrome/browser/history/history_marshaling.h
index 845ea9c..f0f1073 100644
--- a/chrome/browser/history/history_marshaling.h
+++ b/chrome/browser/history/history_marshaling.h
@@ -55,11 +55,6 @@
 
 // Downloads ------------------------------------------------------------------
 
-typedef CancelableRequest1<HistoryService::DownloadNextIdCallback,
-                           int/*next_id*/>
-    DownloadNextIdRequest;
-
-
 typedef CancelableRequest1<HistoryService::DownloadQueryCallback,
                            std::vector<DownloadPersistentStoreInfo> >
     DownloadQueryRequest;
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc
index 2562d21e..59dd64b6 100644
--- a/chrome/browser/profiles/profile_io_data.cc
+++ b/chrome/browser/profiles/profile_io_data.cc
@@ -55,9 +55,9 @@
 #include "net/url_request/url_request.h"
 #include "webkit/blob/blob_data.h"
 #include "webkit/blob/blob_url_request_job_factory.h"
-#include "webkit/database/database_tracker.h"
 #include "webkit/fileapi/file_system_context.h"
 #include "webkit/fileapi/file_system_url_request_job_factory.h"
+#include "webkit/database/database_tracker.h"
 #include "webkit/quota/quota_manager.h"
 
 #if defined(OS_CHROMEOS)
@@ -193,8 +193,6 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   PrefService* pref_service = profile->GetPrefs();
 
-  next_download_id_thunk_ = profile->GetDownloadManager()->GetNextIdThunk();
-
   scoped_ptr<ProfileParams> params(new ProfileParams);
   params->is_incognito = profile->IsOffTheRecord();
   params->clear_local_state_on_exit =
@@ -499,7 +497,6 @@
   resource_context_.SetUserData(NULL, const_cast<ProfileIOData*>(this));
   resource_context_.set_media_observer(
       io_thread_globals->media.media_internals.get());
-  resource_context_.set_next_download_id_thunk(next_download_id_thunk_);
 
   LazyInitializeInternal(profile_params_.get());
 
diff --git a/chrome/browser/profiles/profile_io_data.h b/chrome/browser/profiles/profile_io_data.h
index 95049264..760a06d 100644
--- a/chrome/browser/profiles/profile_io_data.h
+++ b/chrome/browser/profiles/profile_io_data.h
@@ -16,7 +16,6 @@
 #include "base/synchronization/lock.h"
 #include "chrome/browser/net/chrome_url_request_context.h"
 #include "chrome/browser/prefs/pref_member.h"
-#include "content/browser/download/download_manager.h"
 #include "content/browser/resource_context.h"
 #include "net/base/cookie_monster.h"
 
@@ -282,7 +281,6 @@
   mutable scoped_refptr<fileapi::FileSystemContext> file_system_context_;
   mutable scoped_refptr<quota::QuotaManager> quota_manager_;
   mutable scoped_refptr<HostZoomMap> host_zoom_map_;
-  mutable DownloadManager::GetNextIdThunkType next_download_id_thunk_;
 
   // TODO(willchan): Remove from ResourceContext.
   mutable scoped_refptr<ExtensionInfoMap> extension_info_map_;