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_controller_delegate.h"
6
7#include "chrome/browser/extensions/extension_service.h"
8#include "chrome/browser/extensions/extension_util.h"
9#include "chrome/browser/extensions/install_tracker_factory.h"
10#include "chrome/browser/extensions/launch_util.h"
11#include "chrome/browser/profiles/profile.h"
12#include "chrome/browser/ui/app_list/app_list_syncable_service.h"
13#include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h"
14#include "chrome/browser/ui/app_list/extension_uninstaller.h"
15#include "chrome/browser/ui/apps/app_info_dialog.h"
16#include "chrome/browser/ui/browser_navigator.h"
17#include "chrome/common/extensions/extension_constants.h"
18#include "chrome/common/extensions/manifest_url_handler.h"
19#include "extensions/browser/extension_prefs.h"
20#include "extensions/browser/extension_registry.h"
21#include "extensions/browser/extension_system.h"
22#include "extensions/browser/management_policy.h"
23#include "extensions/common/extension.h"
24#include "extensions/common/extension_set.h"
25#include "extensions/common/manifest_handlers/options_page_info.h"
26#include "net/base/url_util.h"
27#include "ui/app_list/app_list_folder_item.h"
28#include "ui/app_list/app_list_item.h"
29#include "ui/app_list/app_list_model.h"
30#include "ui/app_list/app_list_switches.h"
31
32#if defined(ENABLE_RLZ)
33#include "chrome/browser/rlz/rlz.h"
34#endif
35
36using extensions::ExtensionRegistry;
37
38namespace {
39
40const extensions::Extension* GetExtension(Profile* profile,
41                                          const std::string& extension_id) {
42  const ExtensionService* service =
43      extensions::ExtensionSystem::Get(profile)->extension_service();
44  const extensions::Extension* extension =
45      service->GetInstalledExtension(extension_id);
46  return extension;
47}
48
49}  // namespace
50
51AppListControllerDelegate::~AppListControllerDelegate() {}
52
53bool AppListControllerDelegate::ForceNativeDesktop() const {
54  return false;
55}
56
57void AppListControllerDelegate::ViewClosing() {}
58
59gfx::Rect AppListControllerDelegate::GetAppListBounds() {
60  return gfx::Rect();
61}
62
63void AppListControllerDelegate::OnShowChildDialog() {
64}
65void AppListControllerDelegate::OnCloseChildDialog() {
66}
67
68std::string AppListControllerDelegate::AppListSourceToString(
69    AppListSource source) {
70  switch (source) {
71    case LAUNCH_FROM_APP_LIST:
72      return extension_urls::kLaunchSourceAppList;
73    case LAUNCH_FROM_APP_LIST_SEARCH:
74      return extension_urls::kLaunchSourceAppListSearch;
75    default:
76      return std::string();
77  }
78}
79
80bool AppListControllerDelegate::UserMayModifySettings(
81    Profile* profile,
82    const std::string& app_id) {
83  const extensions::Extension* extension = GetExtension(profile, app_id);
84  const extensions::ManagementPolicy* policy =
85      extensions::ExtensionSystem::Get(profile)->management_policy();
86  return extension &&
87         policy->UserMayModifySettings(extension, NULL);
88}
89
90bool AppListControllerDelegate::CanDoShowAppInfoFlow() {
91  return app_list::switches::IsAppInfoEnabled();
92}
93
94void AppListControllerDelegate::DoShowAppInfoFlow(
95    Profile* profile,
96    const std::string& extension_id) {
97  DCHECK(CanDoShowAppInfoFlow());
98  ExtensionService* service =
99      extensions::ExtensionSystem::Get(profile)->extension_service();
100  DCHECK(service);
101  const extensions::Extension* extension = service->GetInstalledExtension(
102      extension_id);
103  DCHECK(extension);
104
105  OnShowChildDialog();
106
107  // Since the AppListControllerDelegate is a leaky singleton, passing its raw
108  // pointer around is OK.
109  ShowAppInfoDialog(GetAppListWindow(),
110                    GetAppListBounds(),
111                    profile,
112                    extension,
113                    base::Bind(&AppListControllerDelegate::OnCloseChildDialog,
114                               base::Unretained(this)));
115}
116
117void AppListControllerDelegate::UninstallApp(Profile* profile,
118                                             const std::string& app_id) {
119  // ExtensionUninstall deletes itself when done or aborted.
120  ExtensionUninstaller* uninstaller =
121      new ExtensionUninstaller(profile, app_id, this);
122  uninstaller->Run();
123}
124
125bool AppListControllerDelegate::IsAppFromWebStore(
126    Profile* profile,
127    const std::string& app_id) {
128  const extensions::Extension* extension = GetExtension(profile, app_id);
129  return extension && extension->from_webstore();
130}
131
132void AppListControllerDelegate::ShowAppInWebStore(
133    Profile* profile,
134    const std::string& app_id,
135    bool is_search_result) {
136  const extensions::Extension* extension = GetExtension(profile, app_id);
137  if (!extension)
138    return;
139
140  const GURL url = extensions::ManifestURL::GetDetailsURL(extension);
141  DCHECK_NE(url, GURL::EmptyGURL());
142
143  const std::string source = AppListSourceToString(
144      is_search_result ?
145          AppListControllerDelegate::LAUNCH_FROM_APP_LIST_SEARCH :
146          AppListControllerDelegate::LAUNCH_FROM_APP_LIST);
147  chrome::NavigateParams params(
148      profile,
149      net::AppendQueryParameter(url,
150                                extension_urls::kWebstoreSourceField,
151                                source),
152      ui::PAGE_TRANSITION_LINK);
153  chrome::Navigate(&params);
154}
155
156bool AppListControllerDelegate::HasOptionsPage(
157    Profile* profile,
158    const std::string& app_id) {
159  const extensions::Extension* extension = GetExtension(profile, app_id);
160  return extensions::util::IsAppLaunchableWithoutEnabling(app_id, profile) &&
161         extension && extensions::OptionsPageInfo::HasOptionsPage(extension);
162}
163
164void AppListControllerDelegate::ShowOptionsPage(
165    Profile* profile,
166    const std::string& app_id) {
167  const extensions::Extension* extension = GetExtension(profile, app_id);
168  if (!extension)
169    return;
170
171  chrome::NavigateParams params(
172      profile,
173      extensions::OptionsPageInfo::GetOptionsPage(extension),
174      ui::PAGE_TRANSITION_LINK);
175  chrome::Navigate(&params);
176}
177
178extensions::LaunchType AppListControllerDelegate::GetExtensionLaunchType(
179    Profile* profile,
180    const std::string& app_id) {
181  return extensions::GetLaunchType(extensions::ExtensionPrefs::Get(profile),
182                                   GetExtension(profile, app_id));
183}
184
185void AppListControllerDelegate::SetExtensionLaunchType(
186    Profile* profile,
187    const std::string& extension_id,
188    extensions::LaunchType launch_type) {
189  ExtensionService* service =
190      extensions::ExtensionSystem::Get(profile)->extension_service();
191  extensions::SetLaunchType(
192      service, extension_id, launch_type);
193}
194
195bool AppListControllerDelegate::IsExtensionInstalled(
196    Profile* profile, const std::string& app_id) {
197  return !!GetExtension(profile, app_id);
198}
199
200extensions::InstallTracker* AppListControllerDelegate::GetInstallTrackerFor(
201    Profile* profile) {
202  if (extensions::ExtensionSystem::Get(profile)->extension_service())
203    return extensions::InstallTrackerFactory::GetForBrowserContext(profile);
204  return NULL;
205}
206
207void AppListControllerDelegate::GetApps(Profile* profile,
208                                        extensions::ExtensionSet* out_apps) {
209  ExtensionRegistry* registry = ExtensionRegistry::Get(profile);
210  DCHECK(registry);
211  out_apps->InsertAll(registry->enabled_extensions());
212  out_apps->InsertAll(registry->disabled_extensions());
213  out_apps->InsertAll(registry->terminated_extensions());
214}
215
216void AppListControllerDelegate::OnSearchStarted() {
217#if defined(ENABLE_RLZ)
218  RLZTracker::RecordAppListSearch();
219#endif
220}
221