1// Copyright (c) 2012 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 CHROME_BROWSER_UI_WEBUI_NTP_SUGGESTIONS_COMBINER_H_
6#define CHROME_BROWSER_UI_WEBUI_NTP_SUGGESTIONS_COMBINER_H_
7
8#include <vector>
9
10#include "base/basictypes.h"
11#include "base/memory/scoped_ptr.h"
12#include "base/memory/scoped_vector.h"
13
14class GURL;
15class SuggestionsHandler;
16class SuggestionsSource;
17class Profile;
18
19namespace base {
20class DictionaryValue;
21class ListValue;
22}
23
24// Combines many different sources of suggestions and generates data from it.
25class SuggestionsCombiner {
26 public:
27  // Interface to be implemented by classes that will be notified of events from
28  // the SuggestionsCombiner.
29  class Delegate {
30   public:
31    virtual ~Delegate() {}
32
33    // Method that is called when new suggestions are ready from the
34    // SuggestionsCombiner.
35    virtual void OnSuggestionsReady() = 0;
36  };
37
38  virtual ~SuggestionsCombiner();
39
40  explicit SuggestionsCombiner(SuggestionsCombiner::Delegate* delegate,
41                               Profile* profile);
42
43  // Add a new source. The SuggestionsCombiner takes ownership of |source|.
44  void AddSource(SuggestionsSource* source);
45
46  // Enables or disables debug mode. If debug mode is enabled, the sources are
47  // expected to provide additional data, which could be displayed, for example,
48  // in the chrome://suggestions-internals/ page.
49  void EnableDebug(bool enable);
50
51  // Fetch a new set of items from the various suggestion sources.
52  void FetchItems(Profile* profile);
53
54  base::ListValue* GetPageValues();
55
56  // Called by a source when its items are ready. Make sure suggestion sources
57  // call this method exactly once for each call to
58  // SuggestionsSource::FetchItems.
59  void OnItemsReady();
60
61  void SetSuggestionsCount(size_t suggestions_count);
62
63 private:
64  friend class SuggestionsCombinerTest;
65
66  // Fill the page values from the suggestion sources so they can be sent to
67  // the JavaScript side. This should only be called when all the suggestion
68  // sources have items ready.
69  void FillPageValues();
70
71  // Add extra information to page values that should be common across all
72  // suggestion sources.
73  void AddExtendedInformation(base::DictionaryValue* page_value);
74
75  // Checks if a URL is already open for the current profile. URLs open in an
76  // incognito window are not reported.
77  bool IsUrlAlreadyOpen(const GURL& url);
78
79  typedef ScopedVector<SuggestionsSource> SuggestionsSources;
80
81  // List of all the suggestions sources that will be combined to generate a
82  // single list of suggestions.
83  SuggestionsSources sources_;
84
85  // Counter tracking the number of sources that are currently asynchronously
86  // fetching their data.
87  int sources_fetching_count_;
88
89  // The delegate to notify once items are ready.
90  SuggestionsCombiner::Delegate* delegate_;
91
92  // Number of suggestions to generate. Used to distribute the suggestions
93  // between the various sources.
94  size_t suggestions_count_;
95
96  // Informations to send to the javascript side.
97  scoped_ptr<base::ListValue> page_values_;
98
99  // Whether debug mode is enabled or not (debug mode provides more data in the
100  // results).
101  bool debug_enabled_;
102
103  Profile* profile_;
104
105  DISALLOW_COPY_AND_ASSIGN(SuggestionsCombiner);
106};
107
108#endif  // CHROME_BROWSER_UI_WEBUI_NTP_SUGGESTIONS_COMBINER_H_
109