Componentize history_types.{cc,h} and android_history_types.{cc,h}

Move history_types.{cc,h} and android_history_types.{cc,h} to the
history component and create a new target history_core_android.

BUG=371816

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

Cr-Commit-Position: refs/heads/master@{#296684}
diff --git a/components/components_tests.gyp b/components/components_tests.gyp
index 8d9721b..76044be 100644
--- a/components/components_tests.gyp
+++ b/components/components_tests.gyp
@@ -133,6 +133,8 @@
             'gcm_driver/gcm_stats_recorder_impl_unittest.cc',
             'google/core/browser/google_url_tracker_unittest.cc',
             'google/core/browser/google_util_unittest.cc',
+            'history/core/android/android_history_types_unittest.cc',
+            'history/core/browser/history_types_unittest.cc',
             'history/core/browser/url_database_unittest.cc',
             'history/core/common/thumbnail_score_unittest.cc',
             'invalidation/invalidation_logger_unittest.cc',
@@ -616,6 +618,7 @@
               ],
               'dependencies': [
                 '../testing/android/native_test.gyp:native_test_native_code',
+                'components.gyp:history_core_android',
               ],
               'dependencies!': [
                 'components.gyp:feedback_component',
diff --git a/components/history.gypi b/components/history.gypi
index e413d34..c2431f5 100644
--- a/components/history.gypi
+++ b/components/history.gypi
@@ -15,6 +15,7 @@
         '../base/base.gyp:base',
         '../net/net.gyp:net',
         '../sql/sql.gyp:sql',
+        '../ui/base/ui_base.gyp:ui_base',
         '../ui/gfx/gfx.gyp:gfx',
         '../url/url.gyp:url_lib',
         'favicon_base',
@@ -78,4 +79,27 @@
       ],
     },
   ],
+  'conditions': [
+    ['OS=="android"', {
+      'targets': [
+        {
+          # GN version: //components/history/code/android
+          'target_name': 'history_core_android',
+          'type': 'static_library',
+          'include_dirs': [
+            '..',
+          ],
+          'dependencies': [
+            '../base/base.gyp:base',
+            '../sql/sql.gyp:sql',
+            'history_core_browser',
+          ],
+          'sources': [
+            'history/core/android/android_history_types.cc',
+            'history/core/android/android_history_types.h',
+          ],
+        },
+      ],
+    }],
+  ],
 }
diff --git a/components/history/DEPS b/components/history/DEPS
index 26313ed..28b1e19 100644
--- a/components/history/DEPS
+++ b/components/history/DEPS
@@ -4,5 +4,6 @@
   "+components/query_parser",
   "+net",
   "+sql",
+  "+ui/base",
   "+ui/gfx",
 ]
diff --git a/components/history/core/android/BUILD.gn b/components/history/core/android/BUILD.gn
new file mode 100644
index 0000000..b49d8675
--- /dev/null
+++ b/components/history/core/android/BUILD.gn
@@ -0,0 +1,16 @@
+# 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.
+
+static_library("android") {
+  sources = [
+    "android_history_types.cc",
+    "android_history_types.h",
+  ]
+
+  deps = [
+    "//base",
+    "//components/history/core/browser",
+    "//sql",
+  ]
+}
diff --git a/components/history/core/android/android_history_types.cc b/components/history/core/android/android_history_types.cc
new file mode 100644
index 0000000..96e7ca3
--- /dev/null
+++ b/components/history/core/android/android_history_types.cc
@@ -0,0 +1,143 @@
+// Copyright (c) 2012 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 "components/history/core/android/android_history_types.h"
+
+namespace history {
+
+namespace {
+// The column name defined in android.provider.Browser.BookmarkColumns
+const char* const kAndroidBookmarkColumn[] = {
+    "_id",
+    "url",
+    "title",
+    "created",
+    "date",
+    "visits",
+    "favicon",
+    "bookmark",
+    "raw_url",
+};
+
+// The column name defined in android.provider.Browser.SearchColumns
+const char* const kAndroidSearchColumn[] = {
+    "_id",
+    "search",
+    "date",
+};
+
+class BookmarkIDMapping : public std::map<std::string,
+                                          HistoryAndBookmarkRow::ColumnID> {
+ public:
+  BookmarkIDMapping() {
+    COMPILE_ASSERT(arraysize(kAndroidBookmarkColumn) <=
+                   HistoryAndBookmarkRow::COLUMN_END,
+                   Array_size_must_not_exceed_enum);
+    for (size_t i = 0; i < arraysize(kAndroidBookmarkColumn); ++i) {
+      (*this)[kAndroidBookmarkColumn[i]] =
+          static_cast<HistoryAndBookmarkRow::ColumnID>(i);
+    }
+  }
+};
+
+// The mapping from Android column name to ColumnID; It is initialized
+// once it used.
+BookmarkIDMapping* g_bookmark_id_mapping = NULL;
+
+class SearchIDMapping : public std::map<std::string,
+                                        SearchRow::ColumnID> {
+ public:
+  SearchIDMapping() {
+    COMPILE_ASSERT(arraysize(kAndroidSearchColumn) <= SearchRow::COLUMN_END,
+                   Array_size_must_not_exceed_enum);
+    for (size_t i = 0; i < arraysize(kAndroidSearchColumn); ++i) {
+      (*this)[kAndroidSearchColumn[i]] =
+              static_cast<SearchRow::ColumnID>(i);
+    }
+  }
+};
+
+// The mapping from Android column name to ColumnID; It is initialized
+// once it used.
+SearchIDMapping* g_search_id_mapping = NULL;
+
+}  // namespace
+
+HistoryAndBookmarkRow::HistoryAndBookmarkRow()
+    : id_(0),
+      created_(base::Time()),
+      last_visit_time_(base::Time()),
+      visit_count_(0),
+      is_bookmark_(false),
+      parent_id_(0),
+      url_id_(0) {
+}
+
+HistoryAndBookmarkRow::~HistoryAndBookmarkRow() {
+}
+
+std::string HistoryAndBookmarkRow::GetAndroidName(ColumnID id) {
+  return kAndroidBookmarkColumn[id];
+}
+
+HistoryAndBookmarkRow::ColumnID HistoryAndBookmarkRow::GetColumnID(
+    const std::string& name) {
+  if (!g_bookmark_id_mapping)
+    g_bookmark_id_mapping = new BookmarkIDMapping();
+
+  BookmarkIDMapping::const_iterator i = g_bookmark_id_mapping->find(name);
+  if (i == g_bookmark_id_mapping->end())
+    return HistoryAndBookmarkRow::COLUMN_END;
+  else
+    return i->second;
+}
+
+SearchRow::SearchRow()
+    : id_(0),
+      keyword_id_(0) {
+}
+
+SearchRow::~SearchRow() {
+}
+
+std::string SearchRow::GetAndroidName(ColumnID id) {
+  return kAndroidSearchColumn[id];
+}
+
+SearchRow::ColumnID SearchRow::GetColumnID(
+    const std::string& name) {
+  if (!g_search_id_mapping)
+    g_search_id_mapping = new SearchIDMapping();
+
+  SearchIDMapping::const_iterator i = g_search_id_mapping->find(name);
+  if (i == g_search_id_mapping->end())
+    return SearchRow:: COLUMN_END;
+  else
+    return i->second;
+}
+
+AndroidURLRow::AndroidURLRow()
+    : id(0),
+      url_id(0) {
+}
+
+AndroidURLRow::~AndroidURLRow() {
+}
+
+SearchTermRow::SearchTermRow()
+    : id(0) {
+}
+
+SearchTermRow::~SearchTermRow() {
+}
+
+AndroidStatement::AndroidStatement(sql::Statement* statement, int favicon_index)
+    : statement_(statement),
+      favicon_index_(favicon_index) {
+}
+
+AndroidStatement::~AndroidStatement() {
+}
+
+}  // namespace history.
diff --git a/components/history/core/android/android_history_types.h b/components/history/core/android/android_history_types.h
new file mode 100644
index 0000000..3c642f3
--- /dev/null
+++ b/components/history/core/android/android_history_types.h
@@ -0,0 +1,332 @@
+// Copyright (c) 2012 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_ANDROID_ANDROID_HISTORY_TYPES_H_
+#define COMPONENTS_HISTORY_CORE_ANDROID_ANDROID_HISTORY_TYPES_H_
+
+#include <map>
+
+#include "base/memory/scoped_ptr.h"
+#include "components/history/core/browser/history_types.h"
+#include "components/history/core/browser/keyword_id.h"
+#include "sql/statement.h"
+
+namespace sql {
+class Statement;
+}
+
+namespace history {
+
+typedef int64 AndroidURLID;
+typedef int64 SearchTermID;
+
+// Wraps all columns needed to support android.provider.Browser.BookmarkColumns.
+// It is used in insert() and update() to specify the columns need to insert or
+// update.
+// The column is not valid until it set. Using is_valid() to find out whether
+// the specific column could be used.
+//
+// The defult copy constructor is used.
+class HistoryAndBookmarkRow {
+ public:
+  enum ColumnID {
+    ID,
+    URL,
+    TITLE,
+    CREATED,
+    LAST_VISIT_TIME,
+    VISIT_COUNT,
+    FAVICON,
+    BOOKMARK,
+    RAW_URL,
+    PARENT_ID,
+    URL_ID,
+    COLUMN_END // This must be the last.
+  };
+
+  HistoryAndBookmarkRow();
+  virtual ~HistoryAndBookmarkRow();
+
+  // Returns the column name defined in Android.
+  static std::string GetAndroidName(ColumnID id);
+
+  static ColumnID GetColumnID(const std::string& name);
+
+  // URLs for the page.
+  void set_url(const GURL& url) {
+    set_value_explicitly(URL);
+    url_ = url;
+  }
+  const GURL& url() const {
+    return url_;
+  }
+
+  // Raw input URL
+  void set_raw_url(const std::string& raw_url) {
+    set_value_explicitly(RAW_URL);
+    raw_url_ = raw_url;
+  }
+  const std::string& raw_url() const {
+    return raw_url_;
+  }
+
+  // The title of page.
+  void set_title(const base::string16& title) {
+    set_value_explicitly(TITLE);
+    title_ = title;
+  }
+  const base::string16& title() const {
+    return title_;
+  }
+
+  // The page's first visit time.
+  void set_created(const base::Time created) {
+    set_value_explicitly(CREATED);
+    created_ = created;
+  }
+  const base::Time& created() const {
+    return created_;
+  }
+
+  // The page's last visit time.
+  void set_last_visit_time(const base::Time last_visit_time) {
+    set_value_explicitly(LAST_VISIT_TIME);
+    last_visit_time_ = last_visit_time;
+  }
+  const base::Time& last_visit_time() const {
+    return last_visit_time_;
+  }
+
+  // The visit times
+  void set_visit_count(int visit_count) {
+    set_value_explicitly(VISIT_COUNT);
+    visit_count_ = visit_count;
+  }
+  int visit_count() const {
+    return visit_count_;
+  }
+
+  // Whether the page is bookmarked.
+  void set_is_bookmark(bool is_bookmark) {
+    set_value_explicitly(BOOKMARK);
+    is_bookmark_ = is_bookmark;
+  }
+  bool is_bookmark() const {
+    return is_bookmark_;
+  }
+
+  // The favicon related to page if any.
+  void set_favicon(const scoped_refptr<base::RefCountedMemory>& data) {
+    set_value_explicitly(FAVICON);
+    favicon_ = data;
+  }
+  const scoped_refptr<base::RefCountedMemory>& favicon() const {
+    return favicon_;
+  }
+
+  bool favicon_valid() const {
+    return favicon_.get() && favicon_->size();
+  }
+
+  // The id of android url.
+  void set_id(AndroidURLID id) {
+    set_value_explicitly(ID);
+    id_ = id;
+  }
+  AndroidURLID id() const {
+    return id_;
+  }
+
+  // The id of the parent folder containing the bookmark, if any.
+  void set_parent_id(int64 parent_id) {
+    set_value_explicitly(PARENT_ID);
+    parent_id_ = parent_id;
+  }
+  const int64 parent_id() const {
+    return parent_id_;
+  }
+
+  // The internal URLID
+  void set_url_id(URLID url_id) {
+    set_value_explicitly(URL_ID);
+    url_id_ = url_id;
+  }
+  URLID url_id() const {
+    return url_id_;
+  }
+
+  // Returns true if the given |id| has been set explicitly.
+  bool is_value_set_explicitly(ColumnID id) const {
+    return values_set_.find(id) != values_set_.end();
+  }
+
+ private:
+  void set_value_explicitly(ColumnID id) {
+    values_set_.insert(id);
+  }
+
+  AndroidURLID id_;
+  GURL url_;
+  std::string raw_url_;
+  base::string16 title_;
+  base::Time created_;
+  base::Time last_visit_time_;
+  scoped_refptr<base::RefCountedMemory> favicon_;
+  int visit_count_;
+  bool is_bookmark_;
+  int64 parent_id_;
+  URLID url_id_;
+
+  // Used to find whether a column has been set a value explicitly.
+  std::set<ColumnID> values_set_;
+
+  // We support the implicit copy constuctor and operator=.
+};
+
+// Wraps all columns needed to support android.provider.Browser.SearchColumns.
+// It is used in insert() and update() to specify the columns need to insert or
+// update.
+//
+// The column is not valid until it set. Using is_valid() to find out whether
+// the specific column could be used.
+//
+// The defult copy constructor is used.
+class SearchRow {
+ public:
+  enum ColumnID {
+    ID,
+    SEARCH_TERM,
+    SEARCH_TIME,
+    URL,
+    KEYWORD_ID,
+    COLUMN_END
+  };
+
+  SearchRow();
+  virtual ~SearchRow();
+
+  // Returns the column name defined in Android.
+  static std::string GetAndroidName(ColumnID id);
+
+  static ColumnID GetColumnID(const std::string& name);
+
+  SearchTermID id() const {
+    return id_;
+  }
+  void set_id(SearchTermID id) {
+    set_value_explicitly(SearchRow::ID);
+    id_ = id;
+  }
+
+  const base::string16& search_term() const {
+    return search_term_;
+  }
+  void set_search_term(const base::string16& search_term) {
+    set_value_explicitly(SearchRow::SEARCH_TERM);
+    search_term_ = search_term;
+  }
+
+  const base::Time search_time() const {
+    return search_time_;
+  }
+  void set_search_time(const base::Time& time) {
+    set_value_explicitly(SearchRow::SEARCH_TIME);
+    search_time_ = time;
+  }
+
+  const GURL& url() const {
+    return url_;
+  }
+  void set_url(const GURL& url) {
+    set_value_explicitly(SearchRow::URL);
+    url_ = url;
+  }
+
+  KeywordID keyword_id() const {
+    return keyword_id_;
+  }
+  void set_keyword_id(KeywordID keyword_id) {
+    set_value_explicitly(SearchRow::KEYWORD_ID);
+    keyword_id_ = keyword_id;
+  }
+
+ // Returns true if the given |id| has been set explicitly.
+  bool is_value_set_explicitly(ColumnID id) const {
+    return values_set_.find(id) != values_set_.end();
+  }
+
+ private:
+  void set_value_explicitly(ColumnID id) {
+    values_set_.insert(id);
+  }
+
+  SearchTermID id_;
+  base::string16 search_term_;
+  base::Time search_time_;
+  GURL url_;
+  KeywordID keyword_id_;
+
+  // Used to find whether a column has been set a value.
+  std::set<ColumnID> values_set_;
+
+  // We support the implicit copy constuctor and operator=.
+};
+
+// Defines the row stored in android_urls table.
+struct AndroidURLRow {
+  AndroidURLRow();
+  ~AndroidURLRow();
+
+  // The unique id of the row
+  AndroidURLID id;
+  // The corresponding URLID in the url table.
+  URLID url_id;
+  // The orignal URL string passed in by client.
+  std::string raw_url;
+};
+
+// Defines the row of keyword_cache table.
+struct SearchTermRow {
+  SearchTermRow();
+  ~SearchTermRow();
+
+  // The unique id of the row.
+  SearchTermID id;
+  // The keyword.
+  base::string16 term;
+  // The last visit time.
+  base::Time last_visit_time;
+};
+
+// This class wraps the sql statement and favicon column index in statement if
+// any. It is returned by AndroidProviderBackend::Query().
+//
+// Using favicon_index() to get the index of favicon; The value of that column
+// is the Favicon ID, Client should call HistoryService::GetFavicon() to get the
+// actual value.
+class AndroidStatement {
+ public:
+  AndroidStatement(sql::Statement* statement, int favicon_index);
+  ~AndroidStatement();
+
+  sql::Statement* statement() {
+    return statement_.get();
+  }
+
+  // The favicon index in statement; -1 is returned if favicon is not in
+  // the statement.
+  int favicon_index() const {
+    return favicon_index_;
+  }
+
+ private:
+  scoped_ptr<sql::Statement> statement_;
+  int favicon_index_;
+
+  DISALLOW_COPY_AND_ASSIGN(AndroidStatement);
+};
+
+}  // namespace history
+
+#endif  // COMPONENTS_HISTORY_CORE_ANDROID_ANDROID_HISTORY_TYPES_H_
diff --git a/components/history/core/android/android_history_types_unittest.cc b/components/history/core/android/android_history_types_unittest.cc
new file mode 100644
index 0000000..a3f4e9b0
--- /dev/null
+++ b/components/history/core/android/android_history_types_unittest.cc
@@ -0,0 +1,38 @@
+// Copyright (c) 2012 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 "components/history/core/android/android_history_types.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace history {
+
+TEST(AndroidHistoryTypesTest, TestGetBookmarkColumnID) {
+  EXPECT_EQ(HistoryAndBookmarkRow::ID,
+            HistoryAndBookmarkRow::GetColumnID("_id"));
+  EXPECT_EQ(HistoryAndBookmarkRow::URL,
+            HistoryAndBookmarkRow::GetColumnID("url"));
+  EXPECT_EQ(HistoryAndBookmarkRow::TITLE,
+            HistoryAndBookmarkRow::GetColumnID("title"));
+  EXPECT_EQ(HistoryAndBookmarkRow::CREATED,
+            HistoryAndBookmarkRow::GetColumnID("created"));
+  EXPECT_EQ(HistoryAndBookmarkRow::LAST_VISIT_TIME,
+            HistoryAndBookmarkRow::GetColumnID("date"));
+  EXPECT_EQ(HistoryAndBookmarkRow::VISIT_COUNT,
+            HistoryAndBookmarkRow::GetColumnID("visits"));
+  EXPECT_EQ(HistoryAndBookmarkRow::FAVICON,
+            HistoryAndBookmarkRow::GetColumnID("favicon"));
+  EXPECT_EQ(HistoryAndBookmarkRow::BOOKMARK,
+            HistoryAndBookmarkRow::GetColumnID("bookmark"));
+  EXPECT_EQ(HistoryAndBookmarkRow::RAW_URL,
+            HistoryAndBookmarkRow::GetColumnID("raw_url"));
+}
+
+TEST(AndroidHistoryTypesTest, TestGetSearchColumnID) {
+  EXPECT_EQ(SearchRow::ID, SearchRow::GetColumnID("_id"));
+  EXPECT_EQ(SearchRow::SEARCH_TERM, SearchRow::GetColumnID("search"));
+  EXPECT_EQ(SearchRow::SEARCH_TIME, SearchRow::GetColumnID("date"));
+}
+
+}  // namespace history
diff --git a/components/history/core/browser/BUILD.gn b/components/history/core/browser/BUILD.gn
index d6196493..18d561e 100644
--- a/components/history/core/browser/BUILD.gn
+++ b/components/history/core/browser/BUILD.gn
@@ -31,6 +31,7 @@
     "//components/query_parser",
     "//net",
     "//sql",
+    "//ui/base",
     "//ui/gfx",
   ]
 }
diff --git a/components/history/core/browser/history_types.cc b/components/history/core/browser/history_types.cc
index abcee11..48c19bd 100644
--- a/components/history/core/browser/history_types.cc
+++ b/components/history/core/browser/history_types.cc
@@ -12,6 +12,32 @@
 
 namespace history {
 
+// VisitRow --------------------------------------------------------------------
+
+VisitRow::VisitRow()
+    : visit_id(0),
+      url_id(0),
+      referring_visit(0),
+      transition(ui::PAGE_TRANSITION_LINK),
+      segment_id(0) {
+}
+
+VisitRow::VisitRow(URLID arg_url_id,
+                   base::Time arg_visit_time,
+                   VisitID arg_referring_visit,
+                   ui::PageTransition arg_transition,
+                   SegmentID arg_segment_id)
+    : visit_id(0),
+      url_id(arg_url_id),
+      visit_time(arg_visit_time),
+      referring_visit(arg_referring_visit),
+      transition(arg_transition),
+      segment_id(arg_segment_id) {
+}
+
+VisitRow::~VisitRow() {
+}
+
 // QueryResults ----------------------------------------------------------------
 
 QueryResults::QueryResults() : reached_beginning_(false) {
@@ -151,6 +177,14 @@
   return max_count ? max_count : std::numeric_limits<int>::max();
 }
 
+// QueryURLResult -------------------------------------------------------------
+
+QueryURLResult::QueryURLResult() : success(false) {
+}
+
+QueryURLResult::~QueryURLResult() {
+}
+
 // MostVisitedURL --------------------------------------------------------------
 
 MostVisitedURL::MostVisitedURL() {}
@@ -203,6 +237,38 @@
 
 TopSitesDelta::~TopSitesDelta() {}
 
+// HistoryAddPageArgs ---------------------------------------------------------
+
+HistoryAddPageArgs::HistoryAddPageArgs()
+    : context_id(NULL),
+      page_id(0),
+      transition(ui::PAGE_TRANSITION_LINK),
+      visit_source(SOURCE_BROWSED),
+      did_replace_entry(false) {}
+
+HistoryAddPageArgs::HistoryAddPageArgs(
+    const GURL& url,
+    base::Time time,
+    ContextID context_id,
+    int32 page_id,
+    const GURL& referrer,
+    const history::RedirectList& redirects,
+    ui::PageTransition transition,
+    VisitSource source,
+    bool did_replace_entry)
+      : url(url),
+        time(time),
+        context_id(context_id),
+        page_id(page_id),
+        referrer(referrer),
+        redirects(redirects),
+        transition(transition),
+        visit_source(source),
+        did_replace_entry(did_replace_entry) {
+}
+
+HistoryAddPageArgs::~HistoryAddPageArgs() {}
+
 // ThumbnailMigration ---------------------------------------------------------
 
 ThumbnailMigration::ThumbnailMigration() {}
@@ -241,6 +307,10 @@
 FaviconBitmap::~FaviconBitmap() {
 }
 
+// VisitDatabaseObserver -------------------------------------------------------
+
+VisitDatabaseObserver::~VisitDatabaseObserver() {}
+
 // ExpireHistoryArgs ----------------------------------------------------------
 
 ExpireHistoryArgs::ExpireHistoryArgs() {
diff --git a/components/history/core/browser/history_types.h b/components/history/core/browser/history_types.h
index 05c740a7..0301a94 100644
--- a/components/history/core/browser/history_types.h
+++ b/components/history/core/browser/history_types.h
@@ -20,11 +20,17 @@
 #include "components/favicon_base/favicon_types.h"
 #include "components/history/core/browser/url_row.h"
 #include "components/history/core/common/thumbnail_score.h"
+#include "ui/base/page_transition_types.h"
 #include "ui/gfx/size.h"
 #include "url/gurl.h"
 
 class PageUsageData;
 
+// TODO(sdefresne): remove, http://crbug.com/371816
+namespace content {
+class WebContents;
+}
+
 namespace history {
 
 // Forward declaration for friend statements.
@@ -38,6 +44,12 @@
 typedef int64 SegmentID;  // URL segments for the most visited view.
 typedef int64 IconMappingID; // For page url and icon mapping.
 
+// Identifier for a context to scope page ids. (ContextIDs are used in
+// comparisons only and are never dereferenced.)
+// NB: The use of WebContents here is temporary; when the dependency on content
+// is broken, some other type will take its place.
+typedef content::WebContents* ContextID;
+
 // The enumeration of all possible sources of visits is listed below.
 // The source will be propagated along with a URL or a visit item
 // and eventually be stored in the history database,
@@ -58,6 +70,60 @@
 // Structure to hold the mapping between each visit's id and its source.
 typedef std::map<VisitID, VisitSource> VisitSourceMap;
 
+// VisitRow -------------------------------------------------------------------
+
+// Holds all information associated with a specific visit. A visit holds time
+// and referrer information for one time a URL is visited.
+class VisitRow {
+ public:
+  VisitRow();
+  VisitRow(URLID arg_url_id,
+           base::Time arg_visit_time,
+           VisitID arg_referring_visit,
+           ui::PageTransition arg_transition,
+           SegmentID arg_segment_id);
+  ~VisitRow();
+
+  // ID of this row (visit ID, used a a referrer for other visits).
+  VisitID visit_id;
+
+  // Row ID into the URL table of the URL that this page is.
+  URLID url_id;
+
+  base::Time visit_time;
+
+  // Indicates another visit that was the referring page for this one.
+  // 0 indicates no referrer.
+  VisitID referring_visit;
+
+  // A combination of bits from PageTransition.
+  ui::PageTransition transition;
+
+  // The segment id (see visitsegment_database.*).
+  // If 0, the segment id is null in the table.
+  SegmentID segment_id;
+
+  // Record how much time a user has this visit starting from the user
+  // opened this visit to the user closed or ended this visit.
+  // This includes both active and inactive time as long as
+  // the visit was present.
+  base::TimeDelta visit_duration;
+
+  // Compares two visits based on dates, for sorting.
+  bool operator<(const VisitRow& other) {
+    return visit_time < other.visit_time;
+  }
+
+  // We allow the implicit copy constuctor and operator=.
+};
+
+// We pass around vectors of visits a lot
+typedef std::vector<VisitRow> VisitVector;
+
+// The basic information associated with a visit (timestamp, type of visit),
+// used by HistoryBackend::AddVisits() to create new visits for a URL.
+typedef std::pair<base::Time, ui::PageTransition> VisitInfo;
+
 // PageVisit ------------------------------------------------------------------
 
 // Represents a simplified version of a visit for external users. Normally,
@@ -220,6 +286,20 @@
   int64 EffectiveEndTime() const;
 };
 
+// QueryURLResult -------------------------------------------------------------
+
+// QueryURLResult encapsulates the result of a call to HistoryBackend::QueryURL.
+struct QueryURLResult {
+  QueryURLResult();
+  ~QueryURLResult();
+
+  // Indicates whether the call to HistoryBackend::QueryURL was successfull
+  // or not. If false, then both |row| and |visits| fields are undefined.
+  bool success;
+  URLRow row;
+  VisitVector visits;
+};
+
 // VisibleVisitCountToHostResult ----------------------------------------------
 
 // VisibleVisitCountToHostResult encapsulates the result of a call to
@@ -285,6 +365,41 @@
   ExtendedInfo extended_info;
 };
 
+// Navigation -----------------------------------------------------------------
+
+// Marshalling structure for AddPage.
+struct HistoryAddPageArgs {
+  // The default constructor is equivalent to:
+  //
+  //   HistoryAddPageArgs(
+  //       GURL(), base::Time(), NULL, 0, GURL(),
+  //       history::RedirectList(), ui::PAGE_TRANSITION_LINK,
+  //       SOURCE_BROWSED, false)
+  HistoryAddPageArgs();
+  HistoryAddPageArgs(const GURL& url,
+                     base::Time time,
+                     ContextID context_id,
+                     int32 page_id,
+                     const GURL& referrer,
+                     const history::RedirectList& redirects,
+                     ui::PageTransition transition,
+                     VisitSource source,
+                     bool did_replace_entry);
+  ~HistoryAddPageArgs();
+
+  GURL url;
+  base::Time time;
+
+  ContextID context_id;
+  int32 page_id;
+
+  GURL referrer;
+  history::RedirectList redirects;
+  ui::PageTransition transition;
+  VisitSource visit_source;
+  bool did_replace_entry;
+};
+
 // TopSites -------------------------------------------------------------------
 
 typedef std::vector<MostVisitedURL> MostVisitedURLList;
@@ -402,6 +517,20 @@
   gfx::Size pixel_size;
 };
 
+// Abbreviated information about a visit.
+struct BriefVisitInfo {
+  URLID url_id;
+  base::Time time;
+  ui::PageTransition transition;
+};
+
+// An observer of VisitDatabase.
+class VisitDatabaseObserver {
+ public:
+  virtual ~VisitDatabaseObserver();
+  virtual void OnAddVisit(const BriefVisitInfo& info) = 0;
+};
+
 struct ExpireHistoryArgs {
   ExpireHistoryArgs();
   ~ExpireHistoryArgs();
diff --git a/components/history/core/browser/history_types_unittest.cc b/components/history/core/browser/history_types_unittest.cc
new file mode 100644
index 0000000..92c2f90
--- /dev/null
+++ b/components/history/core/browser/history_types_unittest.cc
@@ -0,0 +1,118 @@
+// Copyright (c) 2011 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 "base/strings/utf_string_conversions.h"
+#include "components/history/core/browser/history_types.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace history {
+
+namespace {
+
+// Validates the consistency of the given history result. We just make sure
+// that the URL rows match the indices structure. The unit tests themselves
+// test the index structure to verify things are in the right order, so we
+// don't need to.
+void CheckHistoryResultConsistency(const QueryResults& result) {
+  for (size_t i = 0; i < result.size(); i++) {
+    size_t match_count;
+    const size_t* matches = result.MatchesForURL(result[i].url(), &match_count);
+
+    bool found = false;
+    for (size_t match = 0; match < match_count; match++) {
+      if (matches[match] == i) {
+        found = true;
+        break;
+      }
+    }
+
+    EXPECT_TRUE(found) << "The URL had no index referring to it.";
+  }
+}
+
+const char kURL1[] = "http://www.google.com/";
+const char kURL2[] = "http://news.google.com/";
+
+// Adds kURL1 twice and kURL2 once.
+void AddSimpleData(QueryResults* results) {
+  GURL url1(kURL1);
+  GURL url2(kURL2);
+  URLResult result1(url1, base::Time::Now());
+  URLResult result2(url1, base::Time::Now());
+  URLResult result3(url2, base::Time::Now());
+
+  // The URLResults are invalid after being inserted.
+  results->AppendURLBySwapping(&result1);
+  results->AppendURLBySwapping(&result2);
+  results->AppendURLBySwapping(&result3);
+  CheckHistoryResultConsistency(*results);
+}
+
+}  // namespace
+
+// Tests insertion and deletion by range.
+TEST(HistoryQueryResult, DeleteRange) {
+  GURL url1(kURL1);
+  GURL url2(kURL2);
+  QueryResults results;
+  AddSimpleData(&results);
+
+  // Make sure the first URL is in there twice. The indices can be in either
+  // order.
+  size_t match_count;
+  const size_t* matches = results.MatchesForURL(url1, &match_count);
+  ASSERT_EQ(2U, match_count);
+  EXPECT_TRUE((matches[0] == 0 && matches[1] == 1) ||
+              (matches[0] == 1 && matches[1] == 0));
+
+  // Check the second one.
+  matches = results.MatchesForURL(url2, &match_count);
+  ASSERT_EQ(1U, match_count);
+  EXPECT_TRUE(matches[0] == 2);
+
+  // Delete the first instance of the first URL.
+  results.DeleteRange(0, 0);
+  CheckHistoryResultConsistency(results);
+
+  // Check the two URLs.
+  matches = results.MatchesForURL(url1, &match_count);
+  ASSERT_EQ(1U, match_count);
+  EXPECT_TRUE(matches[0] == 0);
+  matches = results.MatchesForURL(url2, &match_count);
+  ASSERT_EQ(1U, match_count);
+  EXPECT_TRUE(matches[0] == 1);
+
+  // Now delete everything and make sure it's deleted.
+  results.DeleteRange(0, 1);
+  EXPECT_EQ(0U, results.size());
+  EXPECT_FALSE(results.MatchesForURL(url1, NULL));
+  EXPECT_FALSE(results.MatchesForURL(url2, NULL));
+}
+
+// Tests insertion and deletion by URL.
+TEST(HistoryQueryResult, ResultDeleteURL) {
+  GURL url1(kURL1);
+  GURL url2(kURL2);
+  QueryResults results;
+  AddSimpleData(&results);
+
+  // Delete the first URL.
+  results.DeleteURL(url1);
+  CheckHistoryResultConsistency(results);
+  EXPECT_EQ(1U, results.size());
+
+  // The first one should be gone, and the second one should be at [0].
+  size_t match_count;
+  EXPECT_FALSE(results.MatchesForURL(url1, NULL));
+  const size_t* matches = results.MatchesForURL(url2, &match_count);
+  ASSERT_EQ(1U, match_count);
+  EXPECT_TRUE(matches[0] == 0);
+
+  // Delete the second URL, there should be nothing left.
+  results.DeleteURL(url2);
+  EXPECT_EQ(0U, results.size());
+  EXPECT_FALSE(results.MatchesForURL(url2, NULL));
+}
+
+}  // namespace history