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"
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 "ui/app_list/app_list_view_delegate_observer.h"
38 #include "ui/app_list/search_box_model.h"
39 #include "ui/app_list/speech_ui_model.h"
42 #include "chrome/browser/ui/ash/app_list/app_sync_ui_state_watcher.h"
46 #include "chrome/browser/web_applications/web_app_win.h"
52 void CreateShortcutInWebAppDir(
53 const base::FilePath
& app_data_dir
,
54 base::Callback
<void(const base::FilePath
&)> callback
,
55 const ShellIntegration::ShortcutInfo
& info
) {
56 content::BrowserThread::PostTaskAndReplyWithResult(
57 content::BrowserThread::FILE,
59 base::Bind(web_app::CreateShortcutInWebAppDir
, app_data_dir
, info
),
64 void PopulateUsers(const ProfileInfoCache
& profile_info
,
65 const base::FilePath
& active_profile_path
,
66 app_list::AppListViewDelegate::Users
* users
) {
68 const size_t count
= profile_info
.GetNumberOfProfiles();
69 for (size_t i
= 0; i
< count
; ++i
) {
70 // Don't display managed users.
71 if (profile_info
.ProfileIsManagedAtIndex(i
))
74 app_list::AppListViewDelegate::User user
;
75 user
.name
= profile_info
.GetNameOfProfileAtIndex(i
);
76 user
.email
= profile_info
.GetUserNameOfProfileAtIndex(i
);
77 user
.profile_path
= profile_info
.GetPathOfProfileAtIndex(i
);
78 user
.active
= active_profile_path
== user
.profile_path
;
79 users
->push_back(user
);
85 AppListViewDelegate::AppListViewDelegate(Profile
* profile
,
86 AppListControllerDelegate
* controller
)
87 : controller_(controller
),
91 RegisterForNotifications();
92 g_browser_process
->profile_manager()->GetProfileInfoCache().AddObserver(this);
93 OnProfileChanged(); // sets model_
94 app_list::StartPageService
* service
=
95 app_list::StartPageService::Get(profile_
);
97 service
->AddObserver(this);
100 AppListViewDelegate::~AppListViewDelegate() {
101 app_list::StartPageService
* service
=
102 app_list::StartPageService::Get(profile_
);
104 service
->RemoveObserver(this);
106 profile_manager()->GetProfileInfoCache().RemoveObserver(this);
109 void AppListViewDelegate::RegisterForNotifications() {
110 registrar_
.RemoveAll();
113 registrar_
.Add(this, chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL
,
114 content::NotificationService::AllSources());
115 registrar_
.Add(this, chrome::NOTIFICATION_GOOGLE_SIGNIN_FAILED
,
116 content::NotificationService::AllSources());
117 registrar_
.Add(this, chrome::NOTIFICATION_GOOGLE_SIGNED_OUT
,
118 content::NotificationService::AllSources());
121 void AppListViewDelegate::OnProfileChanged() {
122 model_
= app_list::AppListSyncableServiceFactory::GetForProfile(
125 search_controller_
.reset(new app_list::SearchController(
126 profile_
, model_
->search_box(), model_
->results(), controller_
));
128 signin_delegate_
.SetProfile(profile_
);
131 app_sync_ui_state_watcher_
.reset(new AppSyncUIStateWatcher(profile_
, model_
));
134 // Don't populate the app list users if we are on the ash desktop.
135 chrome::HostDesktopType desktop
= chrome::GetHostDesktopTypeForNativeWindow(
136 controller_
->GetAppListWindow());
137 if (desktop
== chrome::HOST_DESKTOP_TYPE_ASH
)
140 // Populate the app list users.
141 PopulateUsers(g_browser_process
->profile_manager()->GetProfileInfoCache(),
142 profile_
->GetPath(), &users_
);
144 FOR_EACH_OBSERVER(app_list::AppListViewDelegateObserver
,
146 OnProfilesChanged());
149 bool AppListViewDelegate::ForceNativeDesktop() const {
150 return controller_
->ForceNativeDesktop();
153 void AppListViewDelegate::SetProfileByPath(const base::FilePath
& profile_path
) {
156 // The profile must be loaded before this is called.
158 g_browser_process
->profile_manager()->GetProfileByPath(profile_path
);
161 RegisterForNotifications();
165 // Clear search query.
166 model_
->search_box()->SetText(base::string16());
169 app_list::AppListModel
* AppListViewDelegate::GetModel() {
173 app_list::SigninDelegate
* AppListViewDelegate::GetSigninDelegate() {
174 return &signin_delegate_
;
177 app_list::SpeechUIModel
* AppListViewDelegate::GetSpeechUI() {
181 void AppListViewDelegate::GetShortcutPathForApp(
182 const std::string
& app_id
,
183 const base::Callback
<void(const base::FilePath
&)>& callback
) {
185 ExtensionService
* service
= profile_
->GetExtensionService();
187 const extensions::Extension
* extension
=
188 service
->GetInstalledExtension(app_id
);
190 callback
.Run(base::FilePath());
194 base::FilePath
app_data_dir(
195 web_app::GetWebAppDataDirectory(profile_
->GetPath(),
199 web_app::UpdateShortcutInfoAndIconForApp(
202 base::Bind(CreateShortcutInWebAppDir
, app_data_dir
, callback
));
204 callback
.Run(base::FilePath());
208 void AppListViewDelegate::StartSearch() {
209 if (search_controller_
)
210 search_controller_
->Start();
213 void AppListViewDelegate::StopSearch() {
214 if (search_controller_
)
215 search_controller_
->Stop();
218 void AppListViewDelegate::OpenSearchResult(
219 app_list::SearchResult
* result
,
221 search_controller_
->OpenResult(result
, event_flags
);
224 void AppListViewDelegate::InvokeSearchResultAction(
225 app_list::SearchResult
* result
,
228 search_controller_
->InvokeResultAction(result
, action_index
, event_flags
);
231 void AppListViewDelegate::ViewInitialized() {
232 content::WebContents
* contents
= GetSpeechRecognitionContents();
234 contents
->GetWebUI()->CallJavascriptFunction(
235 "appList.startPage.onAppListShown");
239 void AppListViewDelegate::Dismiss() {
240 controller_
->DismissView();
243 void AppListViewDelegate::ViewClosing() {
244 controller_
->ViewClosing();
246 content::WebContents
* contents
= GetSpeechRecognitionContents();
248 contents
->GetWebUI()->CallJavascriptFunction(
249 "appList.startPage.onAppListHidden");
253 gfx::ImageSkia
AppListViewDelegate::GetWindowIcon() {
254 return controller_
->GetWindowIcon();
257 void AppListViewDelegate::OpenSettings() {
258 ExtensionService
* service
= profile_
->GetExtensionService();
260 const extensions::Extension
* extension
= service
->GetInstalledExtension(
261 extension_misc::kSettingsAppId
);
263 controller_
->ActivateApp(profile_
,
265 AppListControllerDelegate::LAUNCH_FROM_UNKNOWN
,
269 void AppListViewDelegate::OpenHelp() {
270 chrome::HostDesktopType desktop
= chrome::GetHostDesktopTypeForNativeWindow(
271 controller_
->GetAppListWindow());
272 chrome::ScopedTabbedBrowserDisplayer
displayer(profile_
, desktop
);
273 content::OpenURLParams
params(GURL(chrome::kAppLauncherHelpURL
),
276 content::PAGE_TRANSITION_LINK
,
278 displayer
.browser()->OpenURL(params
);
281 void AppListViewDelegate::OpenFeedback() {
282 chrome::HostDesktopType desktop
= chrome::GetHostDesktopTypeForNativeWindow(
283 controller_
->GetAppListWindow());
284 Browser
* browser
= chrome::FindTabbedBrowser(profile_
, false, desktop
);
285 chrome::ShowFeedbackPage(browser
, std::string(),
286 chrome::kAppLauncherCategoryTag
);
289 void AppListViewDelegate::ToggleSpeechRecognition() {
290 app_list::StartPageService
* service
=
291 app_list::StartPageService::Get(profile_
);
293 service
->ToggleSpeechRecognition();
296 void AppListViewDelegate::ShowForProfileByPath(
297 const base::FilePath
& profile_path
) {
298 controller_
->ShowForProfileByPath(profile_path
);
301 void AppListViewDelegate::OnSpeechResult(const base::string16
& result
,
303 speech_ui_
.SetSpeechResult(result
, is_final
);
305 model_
->search_box()->SetText(result
);
308 void AppListViewDelegate::OnSpeechSoundLevelChanged(int16 level
) {
309 speech_ui_
.UpdateSoundLevel(level
);
312 void AppListViewDelegate::OnSpeechRecognitionStateChanged(
313 app_list::SpeechRecognitionState new_state
) {
314 speech_ui_
.SetSpeechRecognitionState(new_state
);
317 void AppListViewDelegate::Observe(
319 const content::NotificationSource
& source
,
320 const content::NotificationDetails
& details
) {
324 void AppListViewDelegate::OnProfileAdded(const base::FilePath
& profile_path
) {
328 void AppListViewDelegate::OnProfileWasRemoved(
329 const base::FilePath
& profile_path
, const base::string16
& profile_name
) {
333 void AppListViewDelegate::OnProfileNameChanged(
334 const base::FilePath
& profile_path
,
335 const base::string16
& old_profile_name
) {
339 content::WebContents
* AppListViewDelegate::GetStartPageContents() {
340 app_list::StartPageService
* service
=
341 app_list::StartPageService::Get(profile_
);
345 return service
->GetStartPageContents();
348 content::WebContents
* AppListViewDelegate::GetSpeechRecognitionContents() {
349 app_list::StartPageService
* service
=
350 app_list::StartPageService::Get(profile_
);
354 return service
->GetSpeechRecognitionContents();
357 const app_list::AppListViewDelegate::Users
&
358 AppListViewDelegate::GetUsers() const {
362 void AppListViewDelegate::AddObserver(
363 app_list::AppListViewDelegateObserver
* observer
) {
364 observers_
.AddObserver(observer
);
367 void AppListViewDelegate::RemoveObserver(
368 app_list::AppListViewDelegateObserver
* observer
) {
369 observers_
.RemoveObserver(observer
);