190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file.
490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#ifndef CHROME_BROWSER_UI_APP_LIST_SEARCH_MIXER_H_
690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#define CHROME_BROWSER_UI_APP_LIST_SEARCH_MIXER_H_
790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/basictypes.h"
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/gtest_prod_util.h"
1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/memory/scoped_vector.h"
1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/app_list/search/history_types.h"
1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/app_list/app_list_model.h"
1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace app_list {
1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace test {
17116680a4aac90f2aa7413d9095a592090648e557Ben MurdochFORWARD_DECLARE_TEST(MixerTest, Publish);
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass ChromeSearchResult;
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class SearchProvider;
2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Mixer collects results from providers, sorts them and publishes them to the
2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// SearchResults UI model. The targeted results have 6 slots to hold the
2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// result. These slots could be viewed as having three groups: main group
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// (local apps and contacts), omnibox group and web store group. The
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// main group takes no more than 4 slots. The web store takes no more than 2
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// slots. The omnibox group takes all the remaining slots.
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class Mixer {
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public:
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // The enum represents mixer groups. Note this must matches the order
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // of group creation in Init().
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  enum GroupId {
3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    MAIN_GROUP = 0,
3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    OMNIBOX_GROUP = 1,
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    WEBSTORE_GROUP = 2,
3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    PEOPLE_GROUP = 3,
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  };
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  explicit Mixer(AppListModel::SearchResults* ui_results);
4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ~Mixer();
4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Creates mixer groups.
4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void Init();
4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Associates a provider with a mixer group.
4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void AddProviderToGroup(GroupId group, SearchProvider* provider);
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Collects the results, sorts and publishes them.
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void MixAndPublish(const KnownResults& known_results);
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private:
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  FRIEND_TEST_ALL_PREFIXES(test::MixerTest, Publish);
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Used for sorting and mixing results.
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  struct SortData {
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    SortData();
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    SortData(ChromeSearchResult* result, double score);
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bool operator<(const SortData& other) const;
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ChromeSearchResult* result;  // Not owned.
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    double score;
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  };
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  typedef std::vector<Mixer::SortData> SortedResults;
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  class Group;
6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  typedef ScopedVector<Group> Groups;
6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Publishes the given |new_results| to |ui_results|, deleting any existing
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // results that are not in |new_results|. Results that already exist in
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // |ui_results| are reused to avoid flickering caused by icon reload.
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  static void Publish(const SortedResults& results,
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                      AppListModel::SearchResults* ui_results);
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Removes duplicates from |results|.
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  static void RemoveDuplicates(SortedResults* results);
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void FetchResults(const KnownResults& known_results);
8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  AppListModel::SearchResults* ui_results_;  // Not owned.
8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Groups groups_;
8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(Mixer);
8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace app_list
8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif  // CHROME_BROWSER_UI_APP_LIST_SEARCH_MIXER_H_
90