Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(737)

Side by Side Diff: chrome/browser/extensions/api/management/chrome_management_api_delegate.cc

Issue 696543002: Move the chrome.management API to extensions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "chrome/browser/extensions/api/management/chrome_management_api_delegat e.h"
6
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/extension_service.h"
11 #include "chrome/browser/extensions/extension_util.h"
12 #include "chrome/browser/extensions/launch_util.h"
13 #include "chrome/browser/favicon/favicon_service.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/browser/ui/webui/ntp/core_app_launcher_handler.h"
23 #include "chrome/common/extensions/chrome_utility_extensions_messages.h"
24 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
25 #include "chrome/common/web_application_info.h"
26 #include "content/public/browser/browser_context.h"
27 #include "content/public/browser/utility_process_host.h"
28 #include "content/public/browser/utility_process_host_client.h"
29 #include "content/public/browser/web_contents.h"
30 #include "extensions/browser/api/management/management_api.h"
31 #include "extensions/browser/api/management/management_api_constants.h"
32 #include "extensions/browser/extension_prefs.h"
33 #include "extensions/browser/extension_registry.h"
34 #include "extensions/browser/extension_system.h"
35 #include "extensions/common/constants.h"
36 #include "extensions/common/extension.h"
37
38 namespace {
39
40 // This class helps ManagementGetPermissionWarningsByManifestFunction manage
41 // sending manifest JSON strings to the utility process for parsing.
42 class SafeManifestJSONParser : public content::UtilityProcessHostClient {
43 public:
44 SafeManifestJSONParser(
45 extensions::ManagementGetPermissionWarningsByManifestFunction* client,
46 const std::string& manifest)
47 : client_(client), manifest_(manifest) {}
48
49 void Start() {
50 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
51 content::BrowserThread::PostTask(
52 content::BrowserThread::IO,
53 FROM_HERE,
54 base::Bind(&SafeManifestJSONParser::StartWorkOnIOThread, this));
55 }
56
57 void StartWorkOnIOThread() {
58 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
59 content::UtilityProcessHost* host = content::UtilityProcessHost::Create(
60 this, base::MessageLoopProxy::current().get());
61 host->Send(new ChromeUtilityMsg_ParseJSON(manifest_));
62 }
63
64 bool OnMessageReceived(const IPC::Message& message) override {
65 bool handled = true;
66 IPC_BEGIN_MESSAGE_MAP(SafeManifestJSONParser, message)
67 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Succeeded,
68 OnJSONParseSucceeded)
69 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Failed,
70 OnJSONParseFailed)
71 IPC_MESSAGE_UNHANDLED(handled = false)
72 IPC_END_MESSAGE_MAP()
73 return handled;
74 }
75
76 void OnJSONParseSucceeded(const base::ListValue& wrapper) {
77 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
78 const base::Value* value = NULL;
79 CHECK(wrapper.Get(0, &value));
80 if (value->IsType(base::Value::TYPE_DICTIONARY))
81 parsed_manifest_.reset(
82 static_cast<const base::DictionaryValue*>(value)->DeepCopy());
83 else
84 error_ = extension_management_api_constants::kManifestParseError;
85
86 content::BrowserThread::PostTask(
87 content::BrowserThread::UI,
88 FROM_HERE,
89 base::Bind(&SafeManifestJSONParser::ReportResultFromUIThread, this));
90 }
91
92 void OnJSONParseFailed(const std::string& error) {
93 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
94 error_ = error;
95 content::BrowserThread::PostTask(
96 content::BrowserThread::UI,
97 FROM_HERE,
98 base::Bind(&SafeManifestJSONParser::ReportResultFromUIThread, this));
99 }
100
101 void ReportResultFromUIThread() {
102 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
103 if (error_.empty() && parsed_manifest_.get())
104 client_->OnParseSuccess(parsed_manifest_.Pass());
105 else
106 client_->OnParseFailure(error_);
107 }
108
109 private:
110 ~SafeManifestJSONParser() override {}
111
112 // The client who we'll report results back to.
113 extensions::ManagementGetPermissionWarningsByManifestFunction* client_;
114
115 // Data to parse.
116 std::string manifest_;
117
118 // Results of parsing.
119 scoped_ptr<base::DictionaryValue> parsed_manifest_;
120
121 std::string error_;
122 };
123
124 class ManagementSetEnabledFunctionInstallPromptDelegate
125 : public ExtensionInstallPrompt::Delegate,
126 public extensions::InstallPromptDelegate {
127 public:
128 ManagementSetEnabledFunctionInstallPromptDelegate(
129 extensions::ManagementSetEnabledFunction* function,
130 const extensions::Extension* extension)
131 : function_(function), details_(function) {
132 install_prompt_.reset(
133 new ExtensionInstallPrompt(details_.GetAssociatedWebContents()));
134 install_prompt_->ConfirmReEnable(this, extension);
135 }
136 virtual ~ManagementSetEnabledFunctionInstallPromptDelegate() {}
137
138 protected:
139 // ExtensionInstallPrompt::Delegate.
140 void InstallUIProceed() override { function_->InstallUIProceed(); }
141 void InstallUIAbort(bool user_initiated) override {
142 function_->InstallUIAbort(user_initiated);
143 }
144
145 private:
146 extensions::ManagementSetEnabledFunction* function_;
147 ChromeExtensionFunctionDetails details_;
148
149 // Used for prompting to re-enable items with permissions escalation updates.
150 scoped_ptr<ExtensionInstallPrompt> install_prompt_;
151 };
152
153 class ManagementUninstallFunctionUninstallDialogDelegate
154 : public extensions::ExtensionUninstallDialog::Delegate,
155 public extensions::UninstallDialogDelegate {
156 public:
157 ManagementUninstallFunctionUninstallDialogDelegate(
158 extensions::ManagementUninstallFunctionBase* function,
159 const std::string& target_extension_id)
160 : function_(function) {
161 const extensions::Extension* target_extension =
162 extensions::ExtensionRegistry::Get(function->browser_context())
163 ->GetExtensionById(target_extension_id,
164 extensions::ExtensionRegistry::EVERYTHING);
165 content::WebContents* web_contents = function->GetAssociatedWebContents();
166 extension_uninstall_dialog_.reset(
167 extensions::ExtensionUninstallDialog::Create(
168 Profile::FromBrowserContext(function->browser_context()),
169 web_contents ? web_contents->GetTopLevelNativeWindow() : NULL,
170 this));
171 if (function->extension_id() != target_extension_id) {
172 extension_uninstall_dialog_->ConfirmProgrammaticUninstall(
173 target_extension, function->extension());
174 } else {
175 // If this is a self uninstall, show the generic uninstall dialog.
176 extension_uninstall_dialog_->ConfirmUninstall(target_extension);
177 }
178 }
179 ~ManagementUninstallFunctionUninstallDialogDelegate() override {}
180
181 // ExtensionUninstallDialog::Delegate implementation.
182 void ExtensionUninstallAccepted() override {
183 function_->ExtensionUninstallAccepted();
184 }
185 void ExtensionUninstallCanceled() override {
186 function_->ExtensionUninstallCanceled();
187 }
188
189 protected:
190 extensions::ManagementUninstallFunctionBase* function_;
191 scoped_ptr<extensions::ExtensionUninstallDialog> extension_uninstall_dialog_;
192 };
193
194 class ChromeAppForLinkDelegate : public extensions::AppForLinkDelegate {
195 public:
196 ChromeAppForLinkDelegate() {}
197 ~ChromeAppForLinkDelegate() override {}
198
199 void OnFaviconForApp(
200 extensions::ManagementGenerateAppForLinkFunction* function,
201 content::BrowserContext* context,
202 const std::string& title,
203 const GURL& launch_url,
204 const favicon_base::FaviconImageResult& image_result) {
205 WebApplicationInfo web_app;
206 web_app.title = base::UTF8ToUTF16(std::string(title));
207 web_app.app_url = launch_url;
208
209 if (!image_result.image.IsEmpty()) {
210 WebApplicationInfo::IconInfo icon;
211 icon.data = image_result.image.AsBitmap();
212 icon.width = icon.data.width();
213 icon.height = icon.data.height();
214 web_app.icons.push_back(icon);
215 }
216
217 bookmark_app_helper_.reset(new extensions::BookmarkAppHelper(
218 extensions::ExtensionSystem::Get(context)->extension_service(),
219 web_app,
220 NULL));
221 bookmark_app_helper_->Create(
222 base::Bind(&extensions::ManagementGenerateAppForLinkFunction::
223 FinishCreateBookmarkApp,
224 function));
225 }
226
227 scoped_ptr<extensions::BookmarkAppHelper> bookmark_app_helper_;
228
229 // Used for favicon loading tasks.
230 base::CancelableTaskTracker cancelable_task_tracker_;
231 };
232
233 } // namespace
234
235 namespace extensions {
236
237 ChromeManagementAPIDelegate::ChromeManagementAPIDelegate() {
238 }
239
240 ChromeManagementAPIDelegate::~ChromeManagementAPIDelegate() {
241 }
242
243 bool ChromeManagementAPIDelegate::LaunchAppFunctionDelegate(
244 const Extension* extension,
245 content::BrowserContext* context) const {
246 // Look at prefs to find the right launch container.
247 // If the user has not set a preference, the default launch value will be
248 // returned.
249 LaunchContainer launch_container =
250 GetLaunchContainer(ExtensionPrefs::Get(context), extension);
251 OpenApplication(AppLaunchParams(Profile::FromBrowserContext(context),
252 extension,
253 launch_container,
254 NEW_FOREGROUND_TAB));
255 CoreAppLauncherHandler::RecordAppLaunchType(
256 extension_misc::APP_LAUNCH_EXTENSION_API, extension->GetType());
257
258 return true;
259 }
260
261 GURL ChromeManagementAPIDelegate::GetFullLaunchURL(
262 const Extension* extension) const {
263 return AppLaunchInfo::GetFullLaunchURL(extension);
264 }
265
266 LaunchType ChromeManagementAPIDelegate::GetLaunchType(
267 const ExtensionPrefs* prefs,
268 const Extension* extension) const {
269 return extensions::GetLaunchType(prefs, extension);
270 }
271
272 void
273 ChromeManagementAPIDelegate::GetPermissionWarningsByManifestFunctionDelegate(
274 ManagementGetPermissionWarningsByManifestFunction* function,
275 const std::string& manifest_str) const {
276 scoped_refptr<SafeManifestJSONParser> parser =
277 new SafeManifestJSONParser(function, manifest_str);
278 parser->Start();
279 }
280
281 scoped_ptr<InstallPromptDelegate>
282 ChromeManagementAPIDelegate::SetEnabledFunctionDelegate(
283 ManagementSetEnabledFunction* function,
284 const Extension* extension) const {
285 return scoped_ptr<ManagementSetEnabledFunctionInstallPromptDelegate>(
286 new ManagementSetEnabledFunctionInstallPromptDelegate(function,
287 extension));
288 }
289
290 scoped_ptr<UninstallDialogDelegate>
291 ChromeManagementAPIDelegate::UninstallFunctionDelegate(
292 ManagementUninstallFunctionBase* function,
293 const std::string& target_extension_id) const {
294 return scoped_ptr<UninstallDialogDelegate>(
295 new ManagementUninstallFunctionUninstallDialogDelegate(
296 function, target_extension_id));
297 }
298
299 bool ChromeManagementAPIDelegate::CreateAppShortcutFunctionDelegate(
300 ManagementCreateAppShortcutFunction* function,
301 const Extension* extension) const {
302 Browser* browser = chrome::FindBrowserWithProfile(
303 Profile::FromBrowserContext(function->browser_context()),
304 chrome::HOST_DESKTOP_TYPE_NATIVE);
305 if (!browser) {
306 // Shouldn't happen if we have user gesture.
307 function->SetError(
308 extension_management_api_constants::kNoBrowserToCreateShortcut);
309 return false;
310 }
311
312 chrome::ShowCreateChromeAppShortcutsDialog(
313 browser->window()->GetNativeWindow(),
314 browser->profile(),
315 extension,
316 base::Bind(&ManagementCreateAppShortcutFunction::OnCloseShortcutPrompt,
317 function));
318
319 return true;
320 }
321
322 scoped_ptr<AppForLinkDelegate>
323 ChromeManagementAPIDelegate::GenerateAppForLinkFunctionDelegate(
324 ManagementGenerateAppForLinkFunction* function,
325 content::BrowserContext* context,
326 const std::string& title,
327 const GURL& launch_url) const {
328 FaviconService* favicon_service = FaviconServiceFactory::GetForProfile(
329 Profile::FromBrowserContext(context), Profile::EXPLICIT_ACCESS);
330 DCHECK(favicon_service);
331
332 ChromeAppForLinkDelegate* delegate = new ChromeAppForLinkDelegate;
333
334 favicon_service->GetFaviconImageForPageURL(
335 launch_url,
336 base::Bind(&ChromeAppForLinkDelegate::OnFaviconForApp,
337 base::Unretained(delegate),
338 scoped_refptr<ManagementGenerateAppForLinkFunction>(function),
339 context,
340 title,
341 launch_url),
342 &delegate->cancelable_task_tracker_);
343
344 return scoped_ptr<AppForLinkDelegate>(delegate);
345 }
346
347 bool ChromeManagementAPIDelegate::IsStreamlinedHostedAppsEnabled() const {
348 return util::IsStreamlinedHostedAppsEnabled();
349 }
350
351 void ChromeManagementAPIDelegate::EnableExtension(
352 content::BrowserContext* context,
353 const std::string& extension_id) const {
354 ExtensionSystem::Get(context)->extension_service()->EnableExtension(
355 extension_id);
356 }
357
358 void ChromeManagementAPIDelegate::DisableExtension(
359 content::BrowserContext* context,
360 const std::string& extension_id,
361 Extension::DisableReason disable_reason) const {
362 ExtensionSystem::Get(context)->extension_service()->DisableExtension(
363 extension_id, disable_reason);
364 }
365
366 bool ChromeManagementAPIDelegate::UninstallExtension(
367 content::BrowserContext* context,
368 const std::string& transient_extension_id,
369 UninstallReason reason,
370 const base::Closure& deletion_done_callback,
371 base::string16* error) const {
372 return ExtensionSystem::Get(context)->extension_service()->UninstallExtension(
373 transient_extension_id, reason, deletion_done_callback, error);
374 }
375
376 void ChromeManagementAPIDelegate::SetLaunchType(
377 content::BrowserContext* context,
378 const std::string& extension_id,
379 LaunchType launch_type) const {
380 extensions::SetLaunchType(
381 extensions::ExtensionSystem::Get(context)->extension_service(),
382 extension_id,
383 launch_type);
384 }
385
386 GURL ChromeManagementAPIDelegate::GetIconURL(const Extension* extension,
387 int icon_size,
388 ExtensionIconSet::MatchType match,
389 bool grayscale,
390 bool* exists) const {
391 return ExtensionIconSource::GetIconURL(
392 extension, icon_size, match, grayscale, exists);
393 }
394
395 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698