1 // Copyright 2013 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.
5 #include "chrome/browser/ui/app_list/search/search_controller.h"
10 #include "base/bind.h"
11 #include "base/command_line.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/metrics/histogram.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/ui/app_list/search/app_search_provider.h"
18 #include "chrome/browser/ui/app_list/search/chrome_search_result.h"
19 #include "chrome/browser/ui/app_list/search/history.h"
20 #include "chrome/browser/ui/app_list/search/history_factory.h"
21 #include "chrome/browser/ui/app_list/search/omnibox_provider.h"
22 #include "chrome/browser/ui/app_list/search/search_provider.h"
23 #include "chrome/browser/ui/app_list/search/webstore_provider.h"
24 #include "content/public/browser/user_metrics.h"
25 #include "grit/generated_resources.h"
26 #include "grit/theme_resources.h"
27 #include "ui/app_list/search_box_model.h"
28 #include "ui/base/l10n/l10n_util.h"
29 #include "ui/base/resource/resource_bundle.h"
32 const char kAppListSearchResultOpenTypeHistogram
[] =
33 "Apps.AppListSearchResultOpenType";
38 SearchController::SearchController(Profile
* profile
,
39 SearchBoxModel
* search_box
,
40 AppListModel::SearchResults
* results
,
41 AppListControllerDelegate
* list_controller
)
43 search_box_(search_box
),
44 list_controller_(list_controller
),
45 dispatching_query_(false),
46 mixer_(new Mixer(results
)),
47 history_(HistoryFactory::GetForBrowserContext(profile
)) {
51 SearchController::~SearchController() {}
53 void SearchController::Init() {
54 search_box_
->SetHintText(
55 l10n_util::GetStringUTF16(IDS_SEARCH_BOX_HINT
));
56 search_box_
->SetIcon(*ui::ResourceBundle::GetSharedInstance().
57 GetImageSkiaNamed(IDR_OMNIBOX_SEARCH
));
61 AddProvider(Mixer::MAIN_GROUP
, scoped_ptr
<SearchProvider
>(
62 new AppSearchProvider(profile_
, list_controller_
)).Pass());
63 AddProvider(Mixer::OMNIBOX_GROUP
, scoped_ptr
<SearchProvider
>(
64 new OmniboxProvider(profile_
)).Pass());
65 AddProvider(Mixer::WEBSTORE_GROUP
, scoped_ptr
<SearchProvider
>(
66 new WebstoreProvider(profile_
, list_controller_
)).Pass());
69 void SearchController::Start() {
73 TrimWhitespace(search_box_
->text(), TRIM_ALL
, &query
);
75 dispatching_query_
= true;
76 for (Providers::iterator it
= providers_
.begin();
77 it
!= providers_
.end();
81 dispatching_query_
= false;
85 // Maximum time (in milliseconds) to wait to the search providers to finish.
86 const int kStopTimeMS
= 1500;
87 stop_timer_
.Start(FROM_HERE
,
88 base::TimeDelta::FromMilliseconds(kStopTimeMS
),
89 base::Bind(&SearchController::Stop
,
90 base::Unretained(this)));
93 void SearchController::Stop() {
96 for (Providers::iterator it
= providers_
.begin();
97 it
!= providers_
.end();
103 void SearchController::OpenResult(SearchResult
* result
, int event_flags
) {
104 // Count AppList.Search here because it is composed of search + action.
105 content::RecordAction(content::UserMetricsAction("AppList_Search"));
107 ChromeSearchResult
* chrome_result
=
108 static_cast<app_list::ChromeSearchResult
*>(result
);
109 UMA_HISTOGRAM_ENUMERATION(kAppListSearchResultOpenTypeHistogram
,
110 chrome_result
->GetType(),
111 SEARCH_RESULT_TYPE_BOUNDARY
);
112 chrome_result
->Open(event_flags
);
114 if (history_
&& history_
->IsReady()) {
115 history_
->AddLaunchEvent(UTF16ToUTF8(search_box_
->text()),
116 chrome_result
->id());
120 void SearchController::InvokeResultAction(SearchResult
* result
,
123 // TODO(xiyuan): Hook up with user learning.
124 static_cast<app_list::ChromeSearchResult
*>(result
)->InvokeAction(
125 action_index
, event_flags
);
128 void SearchController::AddProvider(Mixer::GroupId group
,
129 scoped_ptr
<SearchProvider
> provider
) {
130 provider
->set_result_changed_callback(base::Bind(
131 &SearchController::OnResultsChanged
,
132 base::Unretained(this)));
133 mixer_
->AddProviderToGroup(group
, provider
.get());
134 providers_
.push_back(provider
.release()); // Takes ownership.
137 void SearchController::OnResultsChanged() {
138 if (dispatching_query_
)
141 KnownResults known_results
;
142 if (history_
&& history_
->IsReady()) {
143 history_
->GetKnownResults(UTF16ToUTF8(search_box_
->text()))
144 ->swap(known_results
);
147 mixer_
->MixAndPublish(known_results
);
150 } // namespace app_list