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

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

Powered by Google App Engine
This is Rietveld 408576698