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#include "chrome/browser/ui/app_list/app_list_view_delegate.h"
6
7#include "base/callback.h"
8#include "base/files/file_path.h"
9#include "chrome/browser/browser_process.h"
10#include "chrome/browser/extensions/extension_service.h"
11#include "chrome/browser/feedback/feedback_util.h"
12#include "chrome/browser/profiles/profile_manager.h"
13#include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
14#include "chrome/browser/ui/app_list/apps_model_builder.h"
15#include "chrome/browser/ui/app_list/chrome_app_list_item.h"
16#include "chrome/browser/ui/app_list/chrome_signin_delegate.h"
17#include "chrome/browser/ui/app_list/search/search_controller.h"
18#include "chrome/browser/ui/browser_finder.h"
19#include "chrome/browser/ui/chrome_pages.h"
20#include "chrome/browser/ui/host_desktop.h"
21#include "chrome/browser/ui/web_applications/web_app_ui.h"
22#include "chrome/browser/web_applications/web_app.h"
23#include "chrome/common/extensions/extension_constants.h"
24#include "chrome/common/url_constants.h"
25#include "content/public/browser/browser_thread.h"
26#include "content/public/browser/page_navigator.h"
27#include "content/public/browser/user_metrics.h"
28
29#if defined(USE_ASH)
30#include "chrome/browser/ui/ash/app_list/app_sync_ui_state_watcher.h"
31#endif
32
33#if defined(OS_WIN)
34#include "chrome/browser/web_applications/web_app_win.h"
35#endif
36
37namespace {
38
39#if defined(OS_WIN)
40void CreateShortcutInWebAppDir(
41    const base::FilePath& app_data_dir,
42    base::Callback<void(const base::FilePath&)> callback,
43    const ShellIntegration::ShortcutInfo& info) {
44  content::BrowserThread::PostTaskAndReplyWithResult(
45      content::BrowserThread::FILE,
46      FROM_HERE,
47      base::Bind(web_app::CreateShortcutInWebAppDir, app_data_dir, info),
48      callback);
49}
50#endif
51
52}  // namespace
53
54AppListViewDelegate::AppListViewDelegate(AppListControllerDelegate* controller,
55                                         Profile* profile)
56    : controller_(controller),
57      profile_(profile) {}
58
59AppListViewDelegate::~AppListViewDelegate() {}
60
61void AppListViewDelegate::SetModel(app_list::AppListModel* model) {
62  if (model) {
63    apps_builder_.reset(new AppsModelBuilder(profile_,
64                                             model->apps(),
65                                             controller_.get()));
66    apps_builder_->Build();
67
68    search_controller_.reset(new app_list::SearchController(
69        profile_, model->search_box(), model->results(), controller_.get()));
70
71    signin_delegate_.reset(new ChromeSigninDelegate(profile_));
72
73#if defined(USE_ASH)
74    app_sync_ui_state_watcher_.reset(new AppSyncUIStateWatcher(profile_,
75                                                               model));
76#endif
77  } else {
78    apps_builder_.reset();
79    search_controller_.reset();
80#if defined(USE_ASH)
81    app_sync_ui_state_watcher_.reset();
82#endif
83  }
84}
85
86app_list::SigninDelegate* AppListViewDelegate::GetSigninDelegate() {
87  return signin_delegate_.get();
88}
89
90void AppListViewDelegate::ActivateAppListItem(
91    app_list::AppListItemModel* item,
92    int event_flags) {
93  content::RecordAction(content::UserMetricsAction("AppList_ClickOnApp"));
94  static_cast<ChromeAppListItem*>(item)->Activate(event_flags);
95}
96
97void AppListViewDelegate::GetShortcutPathForApp(
98    const std::string& app_id,
99    const base::Callback<void(const base::FilePath&)>& callback) {
100#if defined(OS_WIN)
101  ExtensionService* service = profile_->GetExtensionService();
102  DCHECK(service);
103  const extensions::Extension* extension =
104      service->GetInstalledExtension(app_id);
105  if (!extension) {
106    callback.Run(base::FilePath());
107    return;
108  }
109
110  base::FilePath app_data_dir(
111      web_app::GetWebAppDataDirectory(profile_->GetPath(),
112                                      extension->id(),
113                                      GURL()));
114
115  web_app::UpdateShortcutInfoAndIconForApp(
116      *extension,
117      profile_,
118      base::Bind(CreateShortcutInWebAppDir, app_data_dir, callback));
119#else
120  callback.Run(base::FilePath());
121#endif
122}
123
124void AppListViewDelegate::StartSearch() {
125  if (search_controller_.get())
126    search_controller_->Start();
127}
128
129void AppListViewDelegate::StopSearch() {
130  if (search_controller_.get())
131    search_controller_->Stop();
132}
133
134void AppListViewDelegate::OpenSearchResult(
135    app_list::SearchResult* result,
136    int event_flags) {
137  search_controller_->OpenResult(result, event_flags);
138}
139
140void AppListViewDelegate::InvokeSearchResultAction(
141    app_list::SearchResult* result,
142    int action_index,
143    int event_flags) {
144  search_controller_->InvokeResultAction(result, action_index, event_flags);
145}
146
147void AppListViewDelegate::Dismiss()  {
148  controller_->DismissView();
149}
150
151void AppListViewDelegate::ViewClosing() {
152  controller_->ViewClosing();
153}
154
155void AppListViewDelegate::ViewActivationChanged(bool active) {
156  controller_->ViewActivationChanged(active);
157}
158
159gfx::ImageSkia AppListViewDelegate::GetWindowIcon() {
160  return controller_->GetWindowIcon();
161}
162
163string16 AppListViewDelegate::GetCurrentUserName() {
164  ProfileInfoCache& cache =
165      g_browser_process->profile_manager()->GetProfileInfoCache();
166  size_t profile_index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
167  if (profile_index != std::string::npos)
168    return cache.GetNameOfProfileAtIndex(profile_index);
169
170  return string16();
171}
172
173string16 AppListViewDelegate::GetCurrentUserEmail()  {
174  ProfileInfoCache& cache =
175      g_browser_process->profile_manager()->GetProfileInfoCache();
176  size_t profile_index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
177  if (profile_index != std::string::npos)
178    return cache.GetUserNameOfProfileAtIndex(profile_index);
179
180  return string16();
181}
182
183void AppListViewDelegate::OpenSettings() {
184  ExtensionService* service = profile_->GetExtensionService();
185  DCHECK(service);
186  const extensions::Extension* extension = service->GetInstalledExtension(
187      extension_misc::kSettingsAppId);
188  DCHECK(extension);
189  controller_->ActivateApp(profile_, extension, 0);
190}
191
192void AppListViewDelegate::OpenHelp() {
193  chrome::HostDesktopType desktop = chrome::GetHostDesktopTypeForNativeWindow(
194      controller_->GetAppListWindow());
195  Browser* browser = chrome::FindOrCreateTabbedBrowser(
196      profile_, desktop);
197  browser->OpenURL(content::OpenURLParams(GURL(chrome::kAppLauncherHelpURL),
198                                          content::Referrer(),
199                                          NEW_FOREGROUND_TAB,
200                                          content::PAGE_TRANSITION_LINK,
201                                          false));
202}
203
204void AppListViewDelegate::OpenFeedback() {
205  chrome::HostDesktopType desktop = chrome::GetHostDesktopTypeForNativeWindow(
206      controller_->GetAppListWindow());
207  Browser* browser = chrome::FindOrCreateTabbedBrowser(
208      profile_, desktop);
209  chrome::ShowFeedbackPage(browser, std::string(),
210                           chrome::kAppLauncherCategoryTag);
211}
212