1 // Copyright 2014 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/extensions/api/management/chrome_management_api_delegate.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/extensions/bookmark_app_helper.h"
9 #include "chrome/browser/extensions/chrome_extension_function_details.h"
10 #include "chrome/browser/extensions/chrome_requirements_checker.h"
11 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/extensions/extension_util.h"
13 #include "chrome/browser/extensions/launch_util.h"
14 #include "chrome/browser/favicon/favicon_service_factory.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/ui/browser_dialogs.h"
17 #include "chrome/browser/ui/browser_finder.h"
18 #include "chrome/browser/ui/browser_window.h"
19 #include "chrome/browser/ui/extensions/app_launch_params.h"
20 #include "chrome/browser/ui/extensions/application_launch.h"
21 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
22 #include "chrome/common/extensions/chrome_utility_extensions_messages.h"
23 #include "chrome/common/extensions/extension_metrics.h"
24 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
25 #include "chrome/common/web_application_info.h"
26 #include "components/favicon/core/favicon_service.h"
27 #include "components/safe_json/safe_json_parser.h"
28 #include "content/public/browser/browser_context.h"
29 #include "content/public/browser/utility_process_host.h"
30 #include "content/public/browser/utility_process_host_client.h"
31 #include "content/public/browser/web_contents.h"
32 #include "extensions/browser/api/management/management_api.h"
33 #include "extensions/browser/api/management/management_api_constants.h"
34 #include "extensions/browser/extension_prefs.h"
35 #include "extensions/browser/extension_registry.h"
36 #include "extensions/browser/extension_system.h"
37 #include "extensions/common/constants.h"
38 #include "extensions/common/extension.h"
42 class ManagementSetEnabledFunctionInstallPromptDelegate
43 : public ExtensionInstallPrompt::Delegate
,
44 public extensions::InstallPromptDelegate
{
46 ManagementSetEnabledFunctionInstallPromptDelegate(
47 extensions::ManagementSetEnabledFunction
* function
,
48 const extensions::Extension
* extension
)
49 : function_(function
) {
50 install_prompt_
.reset(
51 new ExtensionInstallPrompt(function
->GetSenderWebContents()));
52 install_prompt_
->ConfirmReEnable(this, extension
);
54 ~ManagementSetEnabledFunctionInstallPromptDelegate() override
{}
57 // ExtensionInstallPrompt::Delegate.
58 void InstallUIProceed() override
{ function_
->InstallUIProceed(); }
59 void InstallUIAbort(bool user_initiated
) override
{
60 function_
->InstallUIAbort(user_initiated
);
64 extensions::ManagementSetEnabledFunction
* function_
;
66 // Used for prompting to re-enable items with permissions escalation updates.
67 scoped_ptr
<ExtensionInstallPrompt
> install_prompt_
;
69 DISALLOW_COPY_AND_ASSIGN(ManagementSetEnabledFunctionInstallPromptDelegate
);
72 class ManagementUninstallFunctionUninstallDialogDelegate
73 : public extensions::ExtensionUninstallDialog::Delegate
,
74 public extensions::UninstallDialogDelegate
{
76 ManagementUninstallFunctionUninstallDialogDelegate(
77 extensions::ManagementUninstallFunctionBase
* function
,
78 const extensions::Extension
* target_extension
,
79 bool show_programmatic_uninstall_ui
)
80 : function_(function
) {
81 ChromeExtensionFunctionDetails
details(function
);
82 extension_uninstall_dialog_
.reset(
83 extensions::ExtensionUninstallDialog::Create(
84 details
.GetProfile(), details
.GetNativeWindowForUI(), this));
85 extensions::UninstallSource source
=
86 function
->source_context_type() == extensions::Feature::WEBUI_CONTEXT
87 ? extensions::UNINSTALL_SOURCE_CHROME_EXTENSIONS_PAGE
88 : extensions::UNINSTALL_SOURCE_EXTENSION
;
89 if (show_programmatic_uninstall_ui
) {
90 extension_uninstall_dialog_
->ConfirmUninstallByExtension(
91 target_extension
, function
->extension(),
92 extensions::UNINSTALL_REASON_MANAGEMENT_API
, source
);
94 extension_uninstall_dialog_
->ConfirmUninstall(
95 target_extension
, extensions::UNINSTALL_REASON_MANAGEMENT_API
,
99 ~ManagementUninstallFunctionUninstallDialogDelegate() override
{}
101 // ExtensionUninstallDialog::Delegate implementation.
102 void OnExtensionUninstallDialogClosed(bool did_start_uninstall
,
103 const base::string16
& error
) override
{
104 function_
->OnExtensionUninstallDialogClosed(did_start_uninstall
, error
);
108 extensions::ManagementUninstallFunctionBase
* function_
;
109 scoped_ptr
<extensions::ExtensionUninstallDialog
> extension_uninstall_dialog_
;
111 DISALLOW_COPY_AND_ASSIGN(ManagementUninstallFunctionUninstallDialogDelegate
);
114 class ChromeAppForLinkDelegate
: public extensions::AppForLinkDelegate
{
116 ChromeAppForLinkDelegate() {}
117 ~ChromeAppForLinkDelegate() override
{}
119 void OnFaviconForApp(
120 extensions::ManagementGenerateAppForLinkFunction
* function
,
121 content::BrowserContext
* context
,
122 const std::string
& title
,
123 const GURL
& launch_url
,
124 const favicon_base::FaviconImageResult
& image_result
) {
125 WebApplicationInfo web_app
;
126 web_app
.title
= base::UTF8ToUTF16(title
);
127 web_app
.app_url
= launch_url
;
129 if (!image_result
.image
.IsEmpty()) {
130 WebApplicationInfo::IconInfo icon
;
131 icon
.data
= image_result
.image
.AsBitmap();
132 icon
.width
= icon
.data
.width();
133 icon
.height
= icon
.data
.height();
134 web_app
.icons
.push_back(icon
);
137 bookmark_app_helper_
.reset(new extensions::BookmarkAppHelper(
138 Profile::FromBrowserContext(context
), web_app
, NULL
));
139 bookmark_app_helper_
->Create(
140 base::Bind(&extensions::ManagementGenerateAppForLinkFunction::
141 FinishCreateBookmarkApp
,
145 scoped_ptr
<extensions::BookmarkAppHelper
> bookmark_app_helper_
;
147 // Used for favicon loading tasks.
148 base::CancelableTaskTracker cancelable_task_tracker_
;
153 ChromeManagementAPIDelegate::ChromeManagementAPIDelegate() {
156 ChromeManagementAPIDelegate::~ChromeManagementAPIDelegate() {
159 bool ChromeManagementAPIDelegate::LaunchAppFunctionDelegate(
160 const extensions::Extension
* extension
,
161 content::BrowserContext
* context
) const {
162 // Look at prefs to find the right launch container.
163 // If the user has not set a preference, the default launch value will be
165 extensions::LaunchContainer launch_container
=
166 GetLaunchContainer(extensions::ExtensionPrefs::Get(context
), extension
);
167 OpenApplication(AppLaunchParams(
168 Profile::FromBrowserContext(context
), extension
, launch_container
,
169 NEW_FOREGROUND_TAB
, extensions::SOURCE_MANAGEMENT_API
));
170 extensions::RecordAppLaunchType(extension_misc::APP_LAUNCH_EXTENSION_API
,
171 extension
->GetType());
176 GURL
ChromeManagementAPIDelegate::GetFullLaunchURL(
177 const extensions::Extension
* extension
) const {
178 return extensions::AppLaunchInfo::GetFullLaunchURL(extension
);
181 extensions::LaunchType
ChromeManagementAPIDelegate::GetLaunchType(
182 const extensions::ExtensionPrefs
* prefs
,
183 const extensions::Extension
* extension
) const {
184 return extensions::GetLaunchType(prefs
, extension
);
187 void ChromeManagementAPIDelegate::
188 GetPermissionWarningsByManifestFunctionDelegate(
189 extensions::ManagementGetPermissionWarningsByManifestFunction
* function
,
190 const std::string
& manifest_str
) const {
191 safe_json::SafeJsonParser::Parse(
194 &extensions::ManagementGetPermissionWarningsByManifestFunction::
198 &extensions::ManagementGetPermissionWarningsByManifestFunction::
203 scoped_ptr
<extensions::InstallPromptDelegate
>
204 ChromeManagementAPIDelegate::SetEnabledFunctionDelegate(
205 extensions::ManagementSetEnabledFunction
* function
,
206 const extensions::Extension
* extension
) const {
207 return scoped_ptr
<ManagementSetEnabledFunctionInstallPromptDelegate
>(
208 new ManagementSetEnabledFunctionInstallPromptDelegate(function
,
212 scoped_ptr
<extensions::RequirementsChecker
>
213 ChromeManagementAPIDelegate::CreateRequirementsChecker() const {
214 return make_scoped_ptr(new extensions::ChromeRequirementsChecker());
217 scoped_ptr
<extensions::UninstallDialogDelegate
>
218 ChromeManagementAPIDelegate::UninstallFunctionDelegate(
219 extensions::ManagementUninstallFunctionBase
* function
,
220 const extensions::Extension
* target_extension
,
221 bool show_programmatic_uninstall_ui
) const {
222 return scoped_ptr
<extensions::UninstallDialogDelegate
>(
223 new ManagementUninstallFunctionUninstallDialogDelegate(
224 function
, target_extension
, show_programmatic_uninstall_ui
));
227 bool ChromeManagementAPIDelegate::CreateAppShortcutFunctionDelegate(
228 extensions::ManagementCreateAppShortcutFunction
* function
,
229 const extensions::Extension
* extension
) const {
230 Browser
* browser
= chrome::FindBrowserWithProfile(
231 Profile::FromBrowserContext(function
->browser_context()),
232 chrome::HOST_DESKTOP_TYPE_NATIVE
);
234 // Shouldn't happen if we have user gesture.
236 extension_management_api_constants::kNoBrowserToCreateShortcut
);
240 chrome::ShowCreateChromeAppShortcutsDialog(
241 browser
->window()->GetNativeWindow(), browser
->profile(), extension
,
242 base::Bind(&extensions::ManagementCreateAppShortcutFunction::
243 OnCloseShortcutPrompt
,
249 scoped_ptr
<extensions::AppForLinkDelegate
>
250 ChromeManagementAPIDelegate::GenerateAppForLinkFunctionDelegate(
251 extensions::ManagementGenerateAppForLinkFunction
* function
,
252 content::BrowserContext
* context
,
253 const std::string
& title
,
254 const GURL
& launch_url
) const {
255 favicon::FaviconService
* favicon_service
=
256 FaviconServiceFactory::GetForProfile(Profile::FromBrowserContext(context
),
257 ServiceAccessType::EXPLICIT_ACCESS
);
258 DCHECK(favicon_service
);
260 ChromeAppForLinkDelegate
* delegate
= new ChromeAppForLinkDelegate
;
262 favicon_service
->GetFaviconImageForPageURL(
265 &ChromeAppForLinkDelegate::OnFaviconForApp
,
266 base::Unretained(delegate
),
267 scoped_refptr
<extensions::ManagementGenerateAppForLinkFunction
>(
269 context
, title
, launch_url
),
270 &delegate
->cancelable_task_tracker_
);
272 return scoped_ptr
<extensions::AppForLinkDelegate
>(delegate
);
275 bool ChromeManagementAPIDelegate::CanHostedAppsOpenInWindows() const {
276 return extensions::util::CanHostedAppsOpenInWindows();
279 bool ChromeManagementAPIDelegate::IsNewBookmarkAppsEnabled() const {
280 return extensions::util::IsNewBookmarkAppsEnabled();
283 void ChromeManagementAPIDelegate::EnableExtension(
284 content::BrowserContext
* context
,
285 const std::string
& extension_id
) const {
286 extensions::ExtensionSystem::Get(context
)
287 ->extension_service()
288 ->EnableExtension(extension_id
);
291 void ChromeManagementAPIDelegate::DisableExtension(
292 content::BrowserContext
* context
,
293 const std::string
& extension_id
,
294 extensions::Extension::DisableReason disable_reason
) const {
295 extensions::ExtensionSystem::Get(context
)
296 ->extension_service()
297 ->DisableExtension(extension_id
, disable_reason
);
300 bool ChromeManagementAPIDelegate::UninstallExtension(
301 content::BrowserContext
* context
,
302 const std::string
& transient_extension_id
,
303 extensions::UninstallReason reason
,
304 const base::Closure
& deletion_done_callback
,
305 base::string16
* error
) const {
306 return extensions::ExtensionSystem::Get(context
)
307 ->extension_service()
308 ->UninstallExtension(transient_extension_id
, reason
,
309 deletion_done_callback
, error
);
312 void ChromeManagementAPIDelegate::SetLaunchType(
313 content::BrowserContext
* context
,
314 const std::string
& extension_id
,
315 extensions::LaunchType launch_type
) const {
316 extensions::SetLaunchType(context
, extension_id
, launch_type
);
319 GURL
ChromeManagementAPIDelegate::GetIconURL(
320 const extensions::Extension
* extension
,
322 ExtensionIconSet::MatchType match
,
324 bool* exists
) const {
325 return extensions::ExtensionIconSource::GetIconURL(extension
, icon_size
,
326 match
, grayscale
, exists
);