1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef COMPONENTS_HISTORY_CORE_BROWSER_HISTORY_TYPES_H_
6#define COMPONENTS_HISTORY_CORE_BROWSER_HISTORY_TYPES_H_
7
8#include <deque>
9#include <map>
10#include <set>
11#include <string>
12#include <vector>
13
14#include "base/basictypes.h"
15#include "base/containers/stack_container.h"
16#include "base/memory/ref_counted_memory.h"
17#include "base/memory/scoped_vector.h"
18#include "base/strings/string16.h"
19#include "base/time/time.h"
20#include "components/favicon_base/favicon_types.h"
21#include "components/history/core/browser/url_row.h"
22#include "components/history/core/common/thumbnail_score.h"
23#include "ui/base/page_transition_types.h"
24#include "ui/gfx/size.h"
25#include "url/gurl.h"
26
27class PageUsageData;
28
29// TODO(sdefresne): remove, http://crbug.com/371816
30namespace content {
31class WebContents;
32}
33
34namespace history {
35
36// Forward declaration for friend statements.
37class HistoryBackend;
38class URLDatabase;
39
40// Container for a list of URLs.
41typedef std::vector<GURL> RedirectList;
42
43typedef int64 FaviconBitmapID; // Identifier for a bitmap in a favicon.
44typedef int64 SegmentID;  // URL segments for the most visited view.
45typedef int64 IconMappingID; // For page url and icon mapping.
46
47// Identifier for a context to scope page ids. (ContextIDs are used in
48// comparisons only and are never dereferenced.)
49// NB: The use of WebContents here is temporary; when the dependency on content
50// is broken, some other type will take its place.
51typedef content::WebContents* ContextID;
52
53// The enumeration of all possible sources of visits is listed below.
54// The source will be propagated along with a URL or a visit item
55// and eventually be stored in the history database,
56// visit_source table specifically.
57// Different from page transition types, they describe the origins of visits.
58// (Warning): Please don't change any existing values while it is ok to add
59// new values when needed.
60enum VisitSource {
61  SOURCE_SYNCED = 0,         // Synchronized from somewhere else.
62  SOURCE_BROWSED = 1,        // User browsed.
63  SOURCE_EXTENSION = 2,      // Added by an extension.
64  SOURCE_FIREFOX_IMPORTED = 3,
65  SOURCE_IE_IMPORTED = 4,
66  SOURCE_SAFARI_IMPORTED = 5,
67};
68
69typedef int64 VisitID;
70// Structure to hold the mapping between each visit's id and its source.
71typedef std::map<VisitID, VisitSource> VisitSourceMap;
72
73// VisitRow -------------------------------------------------------------------
74
75// Holds all information associated with a specific visit. A visit holds time
76// and referrer information for one time a URL is visited.
77class VisitRow {
78 public:
79  VisitRow();
80  VisitRow(URLID arg_url_id,
81           base::Time arg_visit_time,
82           VisitID arg_referring_visit,
83           ui::PageTransition arg_transition,
84           SegmentID arg_segment_id);
85  ~VisitRow();
86
87  // ID of this row (visit ID, used a a referrer for other visits).
88  VisitID visit_id;
89
90  // Row ID into the URL table of the URL that this page is.
91  URLID url_id;
92
93  base::Time visit_time;
94
95  // Indicates another visit that was the referring page for this one.
96  // 0 indicates no referrer.
97  VisitID referring_visit;
98
99  // A combination of bits from PageTransition.
100  ui::PageTransition transition;
101
102  // The segment id (see visitsegment_database.*).
103  // If 0, the segment id is null in the table.
104  SegmentID segment_id;
105
106  // Record how much time a user has this visit starting from the user
107  // opened this visit to the user closed or ended this visit.
108  // This includes both active and inactive time as long as
109  // the visit was present.
110  base::TimeDelta visit_duration;
111
112  // Compares two visits based on dates, for sorting.
113  bool operator<(const VisitRow& other) {
114    return visit_time < other.visit_time;
115  }
116
117  // We allow the implicit copy constuctor and operator=.
118};
119
120// We pass around vectors of visits a lot
121typedef std::vector<VisitRow> VisitVector;
122
123// The basic information associated with a visit (timestamp, type of visit),
124// used by HistoryBackend::AddVisits() to create new visits for a URL.
125typedef std::pair<base::Time, ui::PageTransition> VisitInfo;
126
127// PageVisit ------------------------------------------------------------------
128
129// Represents a simplified version of a visit for external users. Normally,
130// views are only interested in the time, and not the other information
131// associated with a VisitRow.
132struct PageVisit {
133  URLID page_id;
134  base::Time visit_time;
135};
136
137// QueryResults ----------------------------------------------------------------
138
139// Encapsulates the results of a history query. It supports an ordered list of
140// URLResult objects, plus an efficient way of looking up the index of each time
141// a given URL appears in those results.
142class QueryResults {
143 public:
144  typedef std::vector<URLResult*> URLResultVector;
145
146  QueryResults();
147  ~QueryResults();
148
149  // Indicates the first time that the query includes results for (queries are
150  // clipped at the beginning, so it will always include to the end of the time
151  // queried).
152  //
153  // If the number of results was clipped as a result of the max count, this
154  // will be the time of the first query returned. If there were fewer results
155  // than we were allowed to return, this represents the first date considered
156  // in the query (this will be before the first result if there was time
157  // queried with no results).
158  //
159  // TODO(brettw): bug 1203054: This field is not currently set properly! Do
160  // not use until the bug is fixed.
161  base::Time first_time_searched() const { return first_time_searched_; }
162  void set_first_time_searched(base::Time t) { first_time_searched_ = t; }
163  // Note: If you need end_time_searched, it can be added.
164
165  void set_reached_beginning(bool reached) { reached_beginning_ = reached; }
166  bool reached_beginning() { return reached_beginning_; }
167
168  size_t size() const { return results_.size(); }
169  bool empty() const { return results_.empty(); }
170
171  URLResult& back() { return *results_.back(); }
172  const URLResult& back() const { return *results_.back(); }
173
174  URLResult& operator[](size_t i) { return *results_[i]; }
175  const URLResult& operator[](size_t i) const { return *results_[i]; }
176
177  URLResultVector::const_iterator begin() const { return results_.begin(); }
178  URLResultVector::const_iterator end() const { return results_.end(); }
179  URLResultVector::const_reverse_iterator rbegin() const {
180    return results_.rbegin();
181  }
182  URLResultVector::const_reverse_iterator rend() const {
183    return results_.rend();
184  }
185
186  // Returns a pointer to the beginning of an array of all matching indices
187  // for entries with the given URL. The array will be |*num_matches| long.
188  // |num_matches| can be NULL if the caller is not interested in the number of
189  // results (commonly it will only be interested in the first one and can test
190  // the pointer for NULL).
191  //
192  // When there is no match, it will return NULL and |*num_matches| will be 0.
193  const size_t* MatchesForURL(const GURL& url, size_t* num_matches) const;
194
195  // Swaps the current result with another. This allows ownership to be
196  // efficiently transferred without copying.
197  void Swap(QueryResults* other);
198
199  // Adds the given result to the map, using swap() on the members to avoid
200  // copying (there are a lot of strings and vectors). This means the parameter
201  // object will be cleared after this call.
202  void AppendURLBySwapping(URLResult* result);
203
204  // Removes all instances of the given URL from the result set.
205  void DeleteURL(const GURL& url);
206
207  // Deletes the given range of items in the result set.
208  void DeleteRange(size_t begin, size_t end);
209
210 private:
211  // Maps the given URL to a list of indices into results_ which identify each
212  // time an entry with that URL appears. Normally, each URL will have one or
213  // very few indices after it, so we optimize this to use statically allocated
214  // memory when possible.
215  typedef std::map<GURL, base::StackVector<size_t, 4> > URLToResultIndices;
216
217  // Inserts an entry into the |url_to_results_| map saying that the given URL
218  // is at the given index in the results_.
219  void AddURLUsageAtIndex(const GURL& url, size_t index);
220
221  // Adds |delta| to each index in url_to_results_ in the range [begin,end]
222  // (this is inclusive). This is used when inserting or deleting.
223  void AdjustResultMap(size_t begin, size_t end, ptrdiff_t delta);
224
225  base::Time first_time_searched_;
226
227  // Whether the query reaches the beginning of the database.
228  bool reached_beginning_;
229
230  // The ordered list of results. The pointers inside this are owned by this
231  // QueryResults object.
232  ScopedVector<URLResult> results_;
233
234  // Maps URLs to entries in results_.
235  URLToResultIndices url_to_results_;
236
237  DISALLOW_COPY_AND_ASSIGN(QueryResults);
238};
239
240// QueryOptions ----------------------------------------------------------------
241
242struct QueryOptions {
243  QueryOptions();
244
245  // The time range to search for matches in. The beginning is inclusive and
246  // the ending is exclusive. Either one (or both) may be null.
247  //
248  // This will match only the one recent visit of a URL. For text search
249  // queries, if the URL was visited in the given time period, but has also
250  // been visited more recently than that, it will not be returned. When the
251  // text query is empty, this will return the most recent visit within the
252  // time range.
253  base::Time begin_time;
254  base::Time end_time;
255
256  // Sets the query time to the last |days_ago| days to the present time.
257  void SetRecentDayRange(int days_ago);
258
259  // The maximum number of results to return. The results will be sorted with
260  // the most recent first, so older results may not be returned if there is not
261  // enough room. When 0, this will return everything (the default).
262  int max_count;
263
264  enum DuplicateHandling {
265    // Omit visits for which there is a more recent visit to the same URL.
266    // Each URL in the results will appear only once.
267    REMOVE_ALL_DUPLICATES,
268
269    // Omit visits for which there is a more recent visit to the same URL on
270    // the same day. Each URL will appear no more than once per day, where the
271    // day is defined by the local timezone.
272    REMOVE_DUPLICATES_PER_DAY,
273
274    // Return all visits without deduping.
275    KEEP_ALL_DUPLICATES
276  };
277
278  // Allows the caller to specify how duplicate URLs in the result set should
279  // be handled. The default is REMOVE_DUPLICATES.
280  DuplicateHandling duplicate_policy;
281
282  // Helpers to get the effective parameters values, since a value of 0 means
283  // "unspecified".
284  int EffectiveMaxCount() const;
285  int64 EffectiveBeginTime() const;
286  int64 EffectiveEndTime() const;
287};
288
289// QueryURLResult -------------------------------------------------------------
290
291// QueryURLResult encapsulates the result of a call to HistoryBackend::QueryURL.
292struct QueryURLResult {
293  QueryURLResult();
294  ~QueryURLResult();
295
296  // Indicates whether the call to HistoryBackend::QueryURL was successfull
297  // or not. If false, then both |row| and |visits| fields are undefined.
298  bool success;
299  URLRow row;
300  VisitVector visits;
301};
302
303// VisibleVisitCountToHostResult ----------------------------------------------
304
305// VisibleVisitCountToHostResult encapsulates the result of a call to
306// HistoryBackend::GetVisibleVisitCountToHost.
307struct VisibleVisitCountToHostResult {
308  // Indicates whether the call to HistoryBackend::GetVisibleVisitCountToHost
309  // was successfull or not. If false, then both |count| and |first_visit| are
310  // undefined.
311  bool success;
312  int count;
313  base::Time first_visit;
314};
315
316// MostVisitedURL --------------------------------------------------------------
317
318// Holds the per-URL information of the most visited query.
319struct MostVisitedURL {
320  MostVisitedURL();
321  MostVisitedURL(const GURL& url, const base::string16& title);
322  MostVisitedURL(const GURL& url,
323                 const base::string16& title,
324                 const base::Time& last_forced_time);
325  ~MostVisitedURL();
326
327  GURL url;
328  base::string16 title;
329
330  // If this is a URL for which we want to force a thumbnail, records the last
331  // time it was forced so we can evict it when more recent URLs are requested.
332  // If it's not a forced thumbnail, keep a time of 0.
333  base::Time last_forced_time;
334
335  RedirectList redirects;
336
337  bool operator==(const MostVisitedURL& other) {
338    return url == other.url;
339  }
340};
341
342// FilteredURL -----------------------------------------------------------------
343
344// Holds the per-URL information of the filterd url query.
345struct FilteredURL {
346  struct ExtendedInfo {
347    ExtendedInfo();
348    // The absolute number of visits.
349    unsigned int total_visits;
350    // The number of visits, as seen by the Most Visited NTP pane.
351    unsigned int visits;
352    // The total number of seconds that the page was open.
353    int64 duration_opened;
354    // The time when the page was last visited.
355    base::Time last_visit_time;
356  };
357
358  FilteredURL();
359  explicit FilteredURL(const PageUsageData& data);
360  ~FilteredURL();
361
362  GURL url;
363  base::string16 title;
364  double score;
365  ExtendedInfo extended_info;
366};
367
368// Navigation -----------------------------------------------------------------
369
370// Marshalling structure for AddPage.
371struct HistoryAddPageArgs {
372  // The default constructor is equivalent to:
373  //
374  //   HistoryAddPageArgs(
375  //       GURL(), base::Time(), NULL, 0, GURL(),
376  //       history::RedirectList(), ui::PAGE_TRANSITION_LINK,
377  //       SOURCE_BROWSED, false)
378  HistoryAddPageArgs();
379  HistoryAddPageArgs(const GURL& url,
380                     base::Time time,
381                     ContextID context_id,
382                     int32 page_id,
383                     const GURL& referrer,
384                     const history::RedirectList& redirects,
385                     ui::PageTransition transition,
386                     VisitSource source,
387                     bool did_replace_entry);
388  ~HistoryAddPageArgs();
389
390  GURL url;
391  base::Time time;
392
393  ContextID context_id;
394  int32 page_id;
395
396  GURL referrer;
397  history::RedirectList redirects;
398  ui::PageTransition transition;
399  VisitSource visit_source;
400  bool did_replace_entry;
401};
402
403// TopSites -------------------------------------------------------------------
404
405typedef std::vector<MostVisitedURL> MostVisitedURLList;
406typedef std::vector<FilteredURL> FilteredURLList;
407
408// Used by TopSites to store the thumbnails.
409struct Images {
410  Images();
411  ~Images();
412
413  scoped_refptr<base::RefCountedMemory> thumbnail;
414  ThumbnailScore thumbnail_score;
415
416  // TODO(brettw): this will eventually store the favicon.
417  // scoped_refptr<base::RefCountedBytes> favicon;
418};
419
420struct MostVisitedURLWithRank {
421  MostVisitedURL url;
422  int rank;
423};
424
425typedef std::vector<MostVisitedURLWithRank> MostVisitedURLWithRankList;
426
427struct TopSitesDelta {
428  TopSitesDelta();
429  ~TopSitesDelta();
430
431  MostVisitedURLList deleted;
432  MostVisitedURLWithRankList added;
433  MostVisitedURLWithRankList moved;
434};
435
436typedef std::map<GURL, scoped_refptr<base::RefCountedBytes> > URLToThumbnailMap;
437
438// Used when migrating most visited thumbnails out of history and into topsites.
439struct ThumbnailMigration {
440  ThumbnailMigration();
441  ~ThumbnailMigration();
442
443  MostVisitedURLList most_visited;
444  URLToThumbnailMap url_to_thumbnail_map;
445};
446
447typedef std::map<GURL, Images> URLToImagesMap;
448
449class MostVisitedThumbnails
450    : public base::RefCountedThreadSafe<MostVisitedThumbnails> {
451 public:
452  MostVisitedThumbnails();
453
454  MostVisitedURLList most_visited;
455  URLToImagesMap url_to_images_map;
456
457 private:
458  friend class base::RefCountedThreadSafe<MostVisitedThumbnails>;
459  virtual ~MostVisitedThumbnails();
460
461  DISALLOW_COPY_AND_ASSIGN(MostVisitedThumbnails);
462};
463
464// Favicons -------------------------------------------------------------------
465
466// Used for the mapping between the page and icon.
467struct IconMapping {
468  IconMapping();
469  ~IconMapping();
470
471  // The unique id of the mapping.
472  IconMappingID mapping_id;
473
474  // The url of a web page.
475  GURL page_url;
476
477  // The unique id of the icon.
478  favicon_base::FaviconID icon_id;
479
480  // The url of the icon.
481  GURL icon_url;
482
483  // The type of icon.
484  favicon_base::IconType icon_type;
485};
486
487// Defines a favicon bitmap and its associated pixel size.
488struct FaviconBitmapIDSize {
489  FaviconBitmapIDSize();
490  ~FaviconBitmapIDSize();
491
492  // The unique id of the favicon bitmap.
493  FaviconBitmapID bitmap_id;
494
495  // The pixel dimensions of the associated bitmap.
496  gfx::Size pixel_size;
497};
498
499// Defines a favicon bitmap stored in the history backend.
500struct FaviconBitmap {
501  FaviconBitmap();
502  ~FaviconBitmap();
503
504  // The unique id of the bitmap.
505  FaviconBitmapID bitmap_id;
506
507  // The id of the favicon to which the bitmap belongs to.
508  favicon_base::FaviconID icon_id;
509
510  // Time at which |bitmap_data| was last updated.
511  base::Time last_updated;
512
513  // The bits of the bitmap.
514  scoped_refptr<base::RefCountedMemory> bitmap_data;
515
516  // The pixel dimensions of bitmap_data.
517  gfx::Size pixel_size;
518};
519
520// Abbreviated information about a visit.
521struct BriefVisitInfo {
522  URLID url_id;
523  base::Time time;
524  ui::PageTransition transition;
525};
526
527// An observer of VisitDatabase.
528class VisitDatabaseObserver {
529 public:
530  virtual ~VisitDatabaseObserver();
531  virtual void OnAddVisit(const BriefVisitInfo& info) = 0;
532};
533
534struct ExpireHistoryArgs {
535  ExpireHistoryArgs();
536  ~ExpireHistoryArgs();
537
538  // Sets |begin_time| and |end_time| to the beginning and end of the day (in
539  // local time) on which |time| occurs.
540  void SetTimeRangeForOneDay(base::Time time);
541
542  std::set<GURL> urls;
543  base::Time begin_time;
544  base::Time end_time;
545};
546
547}  // namespace history
548
549#endif  // COMPONENTS_HISTORY_CORE_BROWSER_HISTORY_TYPES_H_
550