Loads the logo image to the speech UI in app-list.
[chromium-blink-merge.git] / chrome / browser / ui / app_list / app_list_view_delegate.cc
blob43e699ea02fddf87ad8b962de4acbe1622d02a9d
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.
5 #include "chrome/browser/ui/app_list/app_list_view_delegate.h"
7 #include <vector>
9 #include "base/callback.h"
10 #include "base/files/file_path.h"
11 #include "base/stl_util.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/chrome_notification_types.h"
14 #include "chrome/browser/extensions/extension_service.h"
15 #include "chrome/browser/feedback/feedback_util.h"
16 #include "chrome/browser/profiles/profile_info_cache.h"
17 #include "chrome/browser/profiles/profile_manager.h"
18 #include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
19 #include "chrome/browser/ui/app_list/app_list_service.h"
20 #include "chrome/browser/ui/app_list/app_list_syncable_service.h"
21 #include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h"
22 #include "chrome/browser/ui/app_list/search/search_controller.h"
23 #include "chrome/browser/ui/app_list/start_page_service.h"
24 #include "chrome/browser/ui/browser_finder.h"
25 #include "chrome/browser/ui/chrome_pages.h"
26 #include "chrome/browser/ui/host_desktop.h"
27 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
28 #include "chrome/browser/ui/web_applications/web_app_ui.h"
29 #include "chrome/browser/web_applications/web_app.h"
30 #include "chrome/common/extensions/extension_constants.h"
31 #include "chrome/common/url_constants.h"
32 #include "content/public/browser/browser_thread.h"
33 #include "content/public/browser/notification_service.h"
34 #include "content/public/browser/notification_source.h"
35 #include "content/public/browser/page_navigator.h"
36 #include "content/public/browser/user_metrics.h"
37 #include "grit/theme_resources.h"
38 #include "ui/app_list/app_list_switches.h"
39 #include "ui/app_list/app_list_view_delegate_observer.h"
40 #include "ui/app_list/search_box_model.h"
41 #include "ui/app_list/speech_ui_model.h"
42 #include "ui/base/resource/resource_bundle.h"
44 #if defined(USE_ASH)
45 #include "chrome/browser/ui/ash/app_list/app_sync_ui_state_watcher.h"
46 #endif
48 #if defined(OS_WIN)
49 #include "chrome/browser/web_applications/web_app_win.h"
50 #endif
52 namespace {
54 const int kAutoLaunchDefaultTimeoutSec = 3;
56 #if defined(OS_WIN)
57 void CreateShortcutInWebAppDir(
58 const base::FilePath& app_data_dir,
59 base::Callback<void(const base::FilePath&)> callback,
60 const ShellIntegration::ShortcutInfo& info) {
61 content::BrowserThread::PostTaskAndReplyWithResult(
62 content::BrowserThread::FILE,
63 FROM_HERE,
64 base::Bind(web_app::CreateShortcutInWebAppDir, app_data_dir, info),
65 callback);
67 #endif
69 void PopulateUsers(const ProfileInfoCache& profile_info,
70 const base::FilePath& active_profile_path,
71 app_list::AppListViewDelegate::Users* users) {
72 users->clear();
73 const size_t count = profile_info.GetNumberOfProfiles();
74 for (size_t i = 0; i < count; ++i) {
75 // Don't display managed users.
76 if (profile_info.ProfileIsManagedAtIndex(i))
77 continue;
79 app_list::AppListViewDelegate::User user;
80 user.name = profile_info.GetNameOfProfileAtIndex(i);
81 user.email = profile_info.GetUserNameOfProfileAtIndex(i);
82 user.profile_path = profile_info.GetPathOfProfileAtIndex(i);
83 user.active = active_profile_path == user.profile_path;
84 users->push_back(user);
88 } // namespace
90 AppListViewDelegate::AppListViewDelegate(Profile* profile,
91 AppListControllerDelegate* controller)
92 : controller_(controller),
93 profile_(profile),
94 model_(NULL) {
95 CHECK(controller_);
96 RegisterForNotifications();
97 g_browser_process->profile_manager()->GetProfileInfoCache().AddObserver(this);
98 OnProfileChanged(); // sets model_
99 app_list::StartPageService* service =
100 app_list::StartPageService::Get(profile_);
101 if (service)
102 service->AddObserver(this);
104 // Hotword listening is on by default in ChromeOS right now. Here shouldn't
105 // use the current state in the webui because it will be changed to 'hotword
106 // listening' state from 'ready' after the view is initialized.
107 speech_ui_.reset(new app_list::SpeechUIModel(
108 #if defined(OS_CHROMEOS)
109 app_list::switches::IsVoiceSearchEnabled() ?
110 app_list::SPEECH_RECOGNITION_HOTWORD_LISTENING :
111 #endif
112 app_list::SPEECH_RECOGNITION_OFF));
114 #if defined(GOOGLE_CHROME_BUILD)
115 speech_ui_->set_logo(
116 *ui::ResourceBundle::GetSharedInstance().
117 GetImageSkiaNamed(IDR_APP_LIST_GOOGLE_LOGO_VOICE_SEARCH));
118 #endif
121 AppListViewDelegate::~AppListViewDelegate() {
122 app_list::StartPageService* service =
123 app_list::StartPageService::Get(profile_);
124 if (service)
125 service->RemoveObserver(this);
126 g_browser_process->
127 profile_manager()->GetProfileInfoCache().RemoveObserver(this);
130 void AppListViewDelegate::RegisterForNotifications() {
131 registrar_.RemoveAll();
132 DCHECK(profile_);
134 registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL,
135 content::NotificationService::AllSources());
136 registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_SIGNIN_FAILED,
137 content::NotificationService::AllSources());
138 registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_SIGNED_OUT,
139 content::NotificationService::AllSources());
142 void AppListViewDelegate::OnProfileChanged() {
143 model_ = app_list::AppListSyncableServiceFactory::GetForProfile(
144 profile_)->model();
146 search_controller_.reset(new app_list::SearchController(
147 profile_, model_->search_box(), model_->results(), controller_));
149 signin_delegate_.SetProfile(profile_);
151 #if defined(USE_ASH)
152 app_sync_ui_state_watcher_.reset(new AppSyncUIStateWatcher(profile_, model_));
153 #endif
155 // Don't populate the app list users if we are on the ash desktop.
156 chrome::HostDesktopType desktop = chrome::GetHostDesktopTypeForNativeWindow(
157 controller_->GetAppListWindow());
158 if (desktop == chrome::HOST_DESKTOP_TYPE_ASH)
159 return;
161 // Populate the app list users.
162 PopulateUsers(g_browser_process->profile_manager()->GetProfileInfoCache(),
163 profile_->GetPath(), &users_);
165 FOR_EACH_OBSERVER(app_list::AppListViewDelegateObserver,
166 observers_,
167 OnProfilesChanged());
170 bool AppListViewDelegate::ForceNativeDesktop() const {
171 return controller_->ForceNativeDesktop();
174 void AppListViewDelegate::SetProfileByPath(const base::FilePath& profile_path) {
175 DCHECK(model_);
177 // The profile must be loaded before this is called.
178 profile_ =
179 g_browser_process->profile_manager()->GetProfileByPath(profile_path);
180 DCHECK(profile_);
182 RegisterForNotifications();
184 OnProfileChanged();
186 // Clear search query.
187 model_->search_box()->SetText(base::string16());
190 app_list::AppListModel* AppListViewDelegate::GetModel() {
191 return model_;
194 app_list::SigninDelegate* AppListViewDelegate::GetSigninDelegate() {
195 return &signin_delegate_;
198 app_list::SpeechUIModel* AppListViewDelegate::GetSpeechUI() {
199 return speech_ui_.get();
202 void AppListViewDelegate::GetShortcutPathForApp(
203 const std::string& app_id,
204 const base::Callback<void(const base::FilePath&)>& callback) {
205 #if defined(OS_WIN)
206 ExtensionService* service = profile_->GetExtensionService();
207 DCHECK(service);
208 const extensions::Extension* extension =
209 service->GetInstalledExtension(app_id);
210 if (!extension) {
211 callback.Run(base::FilePath());
212 return;
215 base::FilePath app_data_dir(
216 web_app::GetWebAppDataDirectory(profile_->GetPath(),
217 extension->id(),
218 GURL()));
220 web_app::UpdateShortcutInfoAndIconForApp(
221 *extension,
222 profile_,
223 base::Bind(CreateShortcutInWebAppDir, app_data_dir, callback));
224 #else
225 callback.Run(base::FilePath());
226 #endif
229 void AppListViewDelegate::StartSearch() {
230 if (search_controller_)
231 search_controller_->Start();
234 void AppListViewDelegate::StopSearch() {
235 if (search_controller_)
236 search_controller_->Stop();
239 void AppListViewDelegate::OpenSearchResult(
240 app_list::SearchResult* result,
241 int event_flags) {
242 search_controller_->OpenResult(result, event_flags);
245 void AppListViewDelegate::InvokeSearchResultAction(
246 app_list::SearchResult* result,
247 int action_index,
248 int event_flags) {
249 search_controller_->InvokeResultAction(result, action_index, event_flags);
252 base::TimeDelta AppListViewDelegate::GetAutoLaunchTimeout() {
253 return auto_launch_timeout_;
256 void AppListViewDelegate::AutoLaunchCanceled() {
257 auto_launch_timeout_ = base::TimeDelta();
260 void AppListViewDelegate::ViewInitialized() {
261 content::WebContents* contents = GetSpeechRecognitionContents();
262 if (contents) {
263 contents->GetWebUI()->CallJavascriptFunction(
264 "appList.startPage.onAppListShown");
268 void AppListViewDelegate::Dismiss() {
269 controller_->DismissView();
272 void AppListViewDelegate::ViewClosing() {
273 controller_->ViewClosing();
275 content::WebContents* contents = GetSpeechRecognitionContents();
276 if (contents) {
277 contents->GetWebUI()->CallJavascriptFunction(
278 "appList.startPage.onAppListHidden");
282 gfx::ImageSkia AppListViewDelegate::GetWindowIcon() {
283 return controller_->GetWindowIcon();
286 void AppListViewDelegate::OpenSettings() {
287 ExtensionService* service = profile_->GetExtensionService();
288 DCHECK(service);
289 const extensions::Extension* extension = service->GetInstalledExtension(
290 extension_misc::kSettingsAppId);
291 DCHECK(extension);
292 controller_->ActivateApp(profile_,
293 extension,
294 AppListControllerDelegate::LAUNCH_FROM_UNKNOWN,
298 void AppListViewDelegate::OpenHelp() {
299 chrome::HostDesktopType desktop = chrome::GetHostDesktopTypeForNativeWindow(
300 controller_->GetAppListWindow());
301 chrome::ScopedTabbedBrowserDisplayer displayer(profile_, desktop);
302 content::OpenURLParams params(GURL(chrome::kAppLauncherHelpURL),
303 content::Referrer(),
304 NEW_FOREGROUND_TAB,
305 content::PAGE_TRANSITION_LINK,
306 false);
307 displayer.browser()->OpenURL(params);
310 void AppListViewDelegate::OpenFeedback() {
311 chrome::HostDesktopType desktop = chrome::GetHostDesktopTypeForNativeWindow(
312 controller_->GetAppListWindow());
313 Browser* browser = chrome::FindTabbedBrowser(profile_, false, desktop);
314 chrome::ShowFeedbackPage(browser, std::string(),
315 chrome::kAppLauncherCategoryTag);
318 void AppListViewDelegate::ToggleSpeechRecognition() {
319 app_list::StartPageService* service =
320 app_list::StartPageService::Get(profile_);
321 if (service)
322 service->ToggleSpeechRecognition();
325 void AppListViewDelegate::ShowForProfileByPath(
326 const base::FilePath& profile_path) {
327 controller_->ShowForProfileByPath(profile_path);
330 void AppListViewDelegate::OnSpeechResult(const base::string16& result,
331 bool is_final) {
332 speech_ui_->SetSpeechResult(result, is_final);
333 if (is_final) {
334 auto_launch_timeout_ = base::TimeDelta::FromSeconds(
335 kAutoLaunchDefaultTimeoutSec);
336 model_->search_box()->SetText(result);
340 void AppListViewDelegate::OnSpeechSoundLevelChanged(int16 level) {
341 speech_ui_->UpdateSoundLevel(level);
344 void AppListViewDelegate::OnSpeechRecognitionStateChanged(
345 app_list::SpeechRecognitionState new_state) {
346 speech_ui_->SetSpeechRecognitionState(new_state);
349 void AppListViewDelegate::Observe(
350 int type,
351 const content::NotificationSource& source,
352 const content::NotificationDetails& details) {
353 OnProfileChanged();
356 void AppListViewDelegate::OnProfileAdded(const base::FilePath& profile_path) {
357 OnProfileChanged();
360 void AppListViewDelegate::OnProfileWasRemoved(
361 const base::FilePath& profile_path, const base::string16& profile_name) {
362 OnProfileChanged();
365 void AppListViewDelegate::OnProfileNameChanged(
366 const base::FilePath& profile_path,
367 const base::string16& old_profile_name) {
368 OnProfileChanged();
371 content::WebContents* AppListViewDelegate::GetStartPageContents() {
372 app_list::StartPageService* service =
373 app_list::StartPageService::Get(profile_);
374 if (!service)
375 return NULL;
377 return service->GetStartPageContents();
380 content::WebContents* AppListViewDelegate::GetSpeechRecognitionContents() {
381 app_list::StartPageService* service =
382 app_list::StartPageService::Get(profile_);
383 if (!service)
384 return NULL;
386 return service->GetSpeechRecognitionContents();
389 const app_list::AppListViewDelegate::Users&
390 AppListViewDelegate::GetUsers() const {
391 return users_;
394 void AppListViewDelegate::AddObserver(
395 app_list::AppListViewDelegateObserver* observer) {
396 observers_.AddObserver(observer);
399 void AppListViewDelegate::RemoveObserver(
400 app_list::AppListViewDelegateObserver* observer) {
401 observers_.RemoveObserver(observer);