Introduce HistoryClient interface

Introduce the HistoryClient interface that will abstract the embedder for
the history component. The implementation in //chrome ChromeHistoryClient
owns the HistoryService and implements the KeyedService interface.

BUG=371825
TBR=sky, zea

Review URL: https://codereview.chromium.org/305443004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@273846 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index abd3c8a..08d20ee 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -25,6 +25,7 @@
   "+components/feedback",
   "+components/gcm_driver",
   "+components/google",
+  "+components/history",
   "+components/infobars",
   "+components/invalidation",
   "+components/keyed_service",
diff --git a/chrome/browser/history/chrome_history_client.cc b/chrome/browser/history/chrome_history_client.cc
new file mode 100644
index 0000000..d6310c8
--- /dev/null
+++ b/chrome/browser/history/chrome_history_client.cc
@@ -0,0 +1,8 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/history/chrome_history_client.h"
+
+ChromeHistoryClient::ChromeHistoryClient() {
+}
diff --git a/chrome/browser/history/chrome_history_client.h b/chrome/browser/history/chrome_history_client.h
new file mode 100644
index 0000000..f6f8d35f
--- /dev/null
+++ b/chrome/browser/history/chrome_history_client.h
@@ -0,0 +1,19 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_HISTORY_CHROME_HISTORY_CLIENT_H_
+#define CHROME_BROWSER_HISTORY_CHROME_HISTORY_CLIENT_H_
+
+#include "base/macros.h"
+#include "components/history/core/browser/history_client.h"
+
+class ChromeHistoryClient : public history::HistoryClient {
+ public:
+  ChromeHistoryClient();
+
+ protected:
+  DISALLOW_COPY_AND_ASSIGN(ChromeHistoryClient);
+};
+
+#endif  // CHROME_BROWSER_HISTORY_CHROME_HISTORY_CLIENT_H_
diff --git a/chrome/browser/history/chrome_history_client_factory.cc b/chrome/browser/history/chrome_history_client_factory.cc
new file mode 100644
index 0000000..5e89dd6
--- /dev/null
+++ b/chrome/browser/history/chrome_history_client_factory.cc
@@ -0,0 +1,45 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/history/chrome_history_client_factory.h"
+
+#include "chrome/browser/history/chrome_history_client.h"
+#include "chrome/browser/profiles/incognito_helpers.h"
+#include "chrome/browser/profiles/profile.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+
+// static
+ChromeHistoryClient* ChromeHistoryClientFactory::GetForProfile(
+    Profile* profile) {
+  return static_cast<ChromeHistoryClient*>(
+      GetInstance()->GetServiceForBrowserContext(profile, true));
+}
+
+// static
+ChromeHistoryClientFactory* ChromeHistoryClientFactory::GetInstance() {
+  return Singleton<ChromeHistoryClientFactory>::get();
+}
+
+ChromeHistoryClientFactory::ChromeHistoryClientFactory()
+    : BrowserContextKeyedServiceFactory(
+          "ChromeHistoryClient",
+          BrowserContextDependencyManager::GetInstance()) {
+}
+
+ChromeHistoryClientFactory::~ChromeHistoryClientFactory() {
+}
+
+KeyedService* ChromeHistoryClientFactory::BuildServiceInstanceFor(
+    content::BrowserContext* context) const {
+  return new ChromeHistoryClient();
+}
+
+content::BrowserContext* ChromeHistoryClientFactory::GetBrowserContextToUse(
+    content::BrowserContext* context) const {
+  return chrome::GetBrowserContextRedirectedInIncognito(context);
+}
+
+bool ChromeHistoryClientFactory::ServiceIsNULLWhileTesting() const {
+  return true;
+}
diff --git a/chrome/browser/history/chrome_history_client_factory.h b/chrome/browser/history/chrome_history_client_factory.h
new file mode 100644
index 0000000..6278bf9
--- /dev/null
+++ b/chrome/browser/history/chrome_history_client_factory.h
@@ -0,0 +1,36 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_HISTORY_CHROME_HISTORY_CLIENT_FACTORY_H_
+#define CHROME_BROWSER_HISTORY_CHROME_HISTORY_CLIENT_FACTORY_H_
+
+#include "base/memory/singleton.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+class ChromeHistoryClient;
+class Profile;
+
+// Singleton that owns all ChromeHistoryClients and associates them with
+// Profiles.
+class ChromeHistoryClientFactory : public BrowserContextKeyedServiceFactory {
+ public:
+  static ChromeHistoryClient* GetForProfile(Profile* profile);
+
+  static ChromeHistoryClientFactory* GetInstance();
+
+ private:
+  friend struct DefaultSingletonTraits<ChromeHistoryClientFactory>;
+
+  ChromeHistoryClientFactory();
+  virtual ~ChromeHistoryClientFactory();
+
+  // BrowserContextKeyedServiceFactory:
+  virtual KeyedService* BuildServiceInstanceFor(
+      content::BrowserContext* context) const OVERRIDE;
+  virtual content::BrowserContext* GetBrowserContextToUse(
+      content::BrowserContext* context) const OVERRIDE;
+  virtual bool ServiceIsNULLWhileTesting() const OVERRIDE;
+};
+
+#endif  // CHROME_BROWSER_HISTORY_CHROME_HISTORY_CLIENT_FACTORY_H_
diff --git a/chrome/browser/history/history_service.cc b/chrome/browser/history/history_service.cc
index 3a4c0a5..8104392 100644
--- a/chrome/browser/history/history_service.cc
+++ b/chrome/browser/history/history_service.cc
@@ -57,6 +57,7 @@
 #include "chrome/common/thumbnail_score.h"
 #include "chrome/common/url_constants.h"
 #include "components/bookmarks/browser/bookmark_model.h"
+#include "components/history/core/browser/history_client.h"
 #include "components/visitedlink/browser/visitedlink_master.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/download_item.h"
@@ -192,15 +193,17 @@
 HistoryService::HistoryService()
     : weak_ptr_factory_(this),
       thread_(new base::Thread(kHistoryThreadName)),
+      history_client_(NULL),
       profile_(NULL),
       backend_loaded_(false),
       bookmark_service_(NULL),
       no_db_(false) {
 }
 
-HistoryService::HistoryService(Profile* profile)
+HistoryService::HistoryService(history::HistoryClient* client, Profile* profile)
     : weak_ptr_factory_(this),
       thread_(new base::Thread(kHistoryThreadName)),
+      history_client_(client),
       profile_(profile),
       visitedlink_master_(new visitedlink::VisitedLinkMaster(
           profile, this, true)),
diff --git a/chrome/browser/history/history_service.h b/chrome/browser/history/history_service.h
index b2c05ca..eb59902 100644
--- a/chrome/browser/history/history_service.h
+++ b/chrome/browser/history/history_service.h
@@ -41,6 +41,7 @@
 #if defined(OS_ANDROID)
 class AndroidHistoryProviderService;
 #endif
+
 class BookmarkService;
 class GURL;
 class HistoryURLProvider;
@@ -62,6 +63,7 @@
 namespace history {
 
 class HistoryBackend;
+class HistoryClient;
 class HistoryDatabase;
 class HistoryDBTask;
 class HistoryQueryTest;
@@ -91,8 +93,9 @@
   // Miscellaneous commonly-used types.
   typedef std::vector<PageUsageData*> PageUsageDataList;
 
-  // Must call Init after construction.
-  explicit HistoryService(Profile* profile);
+  // Must call Init after construction. The |history::HistoryClient| object
+  // must be valid for the whole lifetime of |HistoryService|.
+  explicit HistoryService(history::HistoryClient* client, Profile* profile);
   // The empty constructor is provided only for testing.
   HistoryService();
 
@@ -562,6 +565,9 @@
   // history. We filter out some URLs such as JavaScript.
   static bool CanAddURL(const GURL& url);
 
+  // Returns the HistoryClient.
+  history::HistoryClient* history_client() { return history_client_; }
+
   base::WeakPtr<HistoryService> AsWeakPtr();
 
   // syncer::SyncableService implementation.
@@ -1019,6 +1025,10 @@
   // TODO(mrossetti): Consider changing ownership. See http://crbug.com/138321
   scoped_ptr<history::InMemoryHistoryBackend> in_memory_backend_;
 
+  // The history client, may be null when testing. The object should otherwise
+  // outlive |HistoryService|.
+  history::HistoryClient* history_client_;
+
   // The profile, may be null when testing.
   Profile* profile_;
 
diff --git a/chrome/browser/history/history_service_factory.cc b/chrome/browser/history/history_service_factory.cc
index 13f137f..79b5074 100644
--- a/chrome/browser/history/history_service_factory.cc
+++ b/chrome/browser/history/history_service_factory.cc
@@ -6,6 +6,8 @@
 
 #include "base/prefs/pref_service.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
+#include "chrome/browser/history/chrome_history_client.h"
+#include "chrome/browser/history/chrome_history_client_factory.h"
 #include "chrome/browser/history/history_service.h"
 #include "chrome/browser/profiles/incognito_helpers.h"
 #include "chrome/common/pref_names.h"
@@ -59,6 +61,7 @@
     : BrowserContextKeyedServiceFactory(
           "HistoryService", BrowserContextDependencyManager::GetInstance()) {
   DependsOn(BookmarkModelFactory::GetInstance());
+  DependsOn(ChromeHistoryClientFactory::GetInstance());
 }
 
 HistoryServiceFactory::~HistoryServiceFactory() {
@@ -67,7 +70,8 @@
 KeyedService* HistoryServiceFactory::BuildServiceInstanceFor(
     content::BrowserContext* context) const {
   Profile* profile = static_cast<Profile*>(context);
-  HistoryService* history_service = new HistoryService(profile);
+  HistoryService* history_service = new HistoryService(
+      ChromeHistoryClientFactory::GetForProfile(profile), profile);
   if (!history_service->Init(profile->GetPath(),
                              BookmarkModelFactory::GetForProfile(profile))) {
     return NULL;
diff --git a/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc b/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc
index 4e2e4618..36fd925 100644
--- a/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc
+++ b/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc
@@ -51,7 +51,8 @@
 
 class HistoryMock : public HistoryService {
  public:
-  explicit HistoryMock(Profile* profile) : HistoryService(profile) {}
+  explicit HistoryMock(history::HistoryClient* client, Profile* profile)
+      : HistoryService(client, profile) {}
   MOCK_METHOD0(BackendLoaded, bool(void));
 
  protected:
@@ -81,7 +82,7 @@
 }
 
 KeyedService* BuildHistoryService(content::BrowserContext* profile) {
-  return new HistoryMock(static_cast<Profile*>(profile));
+  return new HistoryMock(NULL, static_cast<Profile*>(profile));
 }
 
 }  // namespace
diff --git a/chrome/browser/sync/profile_sync_service_typed_url_unittest.cc b/chrome/browser/sync/profile_sync_service_typed_url_unittest.cc
index b94dbc9c..fc2db873 100644
--- a/chrome/browser/sync/profile_sync_service_typed_url_unittest.cc
+++ b/chrome/browser/sync/profile_sync_service_typed_url_unittest.cc
@@ -105,7 +105,8 @@
 
 class HistoryServiceMock : public HistoryService {
  public:
-  explicit HistoryServiceMock(Profile* profile) : HistoryService(profile) {}
+  explicit HistoryServiceMock(history::HistoryClient* client, Profile* profile)
+      : HistoryService(client, profile) {}
   MOCK_METHOD2(ScheduleDBTask, void(history::HistoryDBTask*,
                                     CancelableRequestConsumerBase*));
   MOCK_METHOD0(Shutdown, void());
@@ -119,7 +120,7 @@
 };
 
 KeyedService* BuildHistoryService(content::BrowserContext* profile) {
-  return new HistoryServiceMock(static_cast<Profile*>(profile));
+  return new HistoryServiceMock(NULL, static_cast<Profile*>(profile));
 }
 
 class TestTypedUrlModelAssociator : public TypedUrlModelAssociator {
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 23005a5a..9f81cd8 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -39,6 +39,7 @@
         '../components/components.gyp:feedback_component',
         '../components/components.gyp:gcm_driver',
         '../components/components.gyp:google_core_browser',
+        '../components/components.gyp:history_core_browser',
         '../components/components.gyp:infobars_core',
         '../components/components.gyp:invalidation',
         '../components/components.gyp:metrics',
@@ -775,6 +776,10 @@
         'browser/history/android/visit_sql_handler.h',
         'browser/history/archived_database.cc',
         'browser/history/archived_database.h',
+        'browser/history/chrome_history_client.cc',
+        'browser/history/chrome_history_client.h',
+        'browser/history/chrome_history_client_factory.cc',
+        'browser/history/chrome_history_client_factory.h',
         'browser/history/delete_directive_handler.cc',
         'browser/history/delete_directive_handler.h',
         'browser/history/download_database.cc',
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc
index 166fcc16..d5e6b7a 100644
--- a/chrome/test/base/testing_profile.cc
+++ b/chrome/test/base/testing_profile.cc
@@ -426,7 +426,7 @@
 }
 
 static KeyedService* BuildHistoryService(content::BrowserContext* profile) {
-  return new HistoryService(static_cast<Profile*>(profile));
+  return new HistoryService(NULL, static_cast<Profile*>(profile));
 }
 
 bool TestingProfile::CreateHistoryService(bool delete_file, bool no_db) {
diff --git a/components/components.gyp b/components/components.gyp
index f334768b..2783682 100644
--- a/components/components.gyp
+++ b/components/components.gyp
@@ -24,6 +24,7 @@
     'favicon.gypi',
     'favicon_base.gypi',
     'google.gypi',
+    'history.gypi',
     'infobars.gypi',
     'json_schema.gypi',
     'keyed_service.gypi',
diff --git a/components/history.gypi b/components/history.gypi
new file mode 100644
index 0000000..8b7821e
--- /dev/null
+++ b/components/history.gypi
@@ -0,0 +1,22 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+  'targets': [
+    {
+      'target_name': 'history_core_browser',
+      'type': 'none',
+      'include_dirs': [
+        '..',
+      ],
+      'dependencies': [
+        '../base/base.gyp:base',
+        'keyed_service_core',
+      ],
+      'sources': [
+        'history/core/browser/history_client.h',
+      ],
+    },
+  ],
+}
diff --git a/components/history/DEPS b/components/history/DEPS
new file mode 100644
index 0000000..a82819d6
--- /dev/null
+++ b/components/history/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+components/keyed_service",
+]
diff --git a/components/history/OWNERS b/components/history/OWNERS
new file mode 100644
index 0000000..40c23c5
--- /dev/null
+++ b/components/history/OWNERS
@@ -0,0 +1,10 @@
[email protected]
[email protected]
+
+per-file download_database.*[email protected]
+
+# Temporary owner, for refactoring changes only.
[email protected]
+
+# Temporary owner, for refactoring changes only.
[email protected]
diff --git a/components/history/core/browser/history_client.h b/components/history/core/browser/history_client.h
new file mode 100644
index 0000000..cc2da58
--- /dev/null
+++ b/components/history/core/browser/history_client.h
@@ -0,0 +1,24 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_HISTORY_CORE_BROWSER_HISTORY_CLIENT_H_
+#define COMPONENTS_HISTORY_CORE_BROWSER_HISTORY_CLIENT_H_
+
+#include "base/macros.h"
+#include "components/keyed_service/core/keyed_service.h"
+
+namespace history {
+
+// This class abstracts operations that depend on the embedder's environment,
+// e.g. Chrome.
+class HistoryClient : public KeyedService {
+ protected:
+  HistoryClient() {}
+
+  DISALLOW_COPY_AND_ASSIGN(HistoryClient);
+};
+
+}  // namespace history
+
+#endif  // COMPONENTS_HISTORY_CORE_BROWSER_HISTORY_CLIENT_H_