diff options
author | lfg <lfg@chromium.org> | 2014-11-04 14:26:25 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-11-04 22:27:09 +0000 |
commit | 3fba1a6a4f245a326d7221b031a9bf599c0c5874 (patch) | |
tree | 8ab2d1f131bfc010cf7859e9377d7553ed7c4f01 /chrome/browser/extensions/api/management/chrome_management_api_delegate.cc | |
parent | cf09bfbca9ce0280aa31f3c93564bc29031580d7 (diff) | |
download | chromium_src-3fba1a6a4f245a326d7221b031a9bf599c0c5874.zip chromium_src-3fba1a6a4f245a326d7221b031a9bf599c0c5874.tar.gz chromium_src-3fba1a6a4f245a326d7221b031a9bf599c0c5874.tar.bz2 |
Move the chrome.management API to extensions.
BUG=422618
Review URL: https://codereview.chromium.org/696543002
Cr-Commit-Position: refs/heads/master@{#302681}
Diffstat (limited to 'chrome/browser/extensions/api/management/chrome_management_api_delegate.cc')
-rw-r--r-- | chrome/browser/extensions/api/management/chrome_management_api_delegate.cc | 389 |
1 files changed, 389 insertions, 0 deletions
diff --git a/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc b/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc new file mode 100644 index 0000000..c5e5740 --- /dev/null +++ b/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc @@ -0,0 +1,389 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/extensions/api/management/chrome_management_api_delegate.h" + +#include "base/strings/utf_string_conversions.h" +#include "chrome/browser/extensions/bookmark_app_helper.h" +#include "chrome/browser/extensions/chrome_extension_function_details.h" +#include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/extensions/extension_util.h" +#include "chrome/browser/extensions/launch_util.h" +#include "chrome/browser/favicon/favicon_service.h" +#include "chrome/browser/favicon/favicon_service_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser_dialogs.h" +#include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/extensions/app_launch_params.h" +#include "chrome/browser/ui/extensions/application_launch.h" +#include "chrome/browser/ui/webui/extensions/extension_icon_source.h" +#include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h" +#include "chrome/common/extensions/chrome_utility_extensions_messages.h" +#include "chrome/common/extensions/manifest_handlers/app_launch_info.h" +#include "chrome/common/web_application_info.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/utility_process_host.h" +#include "content/public/browser/utility_process_host_client.h" +#include "content/public/browser/web_contents.h" +#include "extensions/browser/api/management/management_api.h" +#include "extensions/browser/api/management/management_api_constants.h" +#include "extensions/browser/extension_prefs.h" +#include "extensions/browser/extension_registry.h" +#include "extensions/browser/extension_system.h" +#include "extensions/common/constants.h" +#include "extensions/common/extension.h" + +namespace { + +// This class helps ManagementGetPermissionWarningsByManifestFunction manage +// sending manifest JSON strings to the utility process for parsing. +class SafeManifestJSONParser : public content::UtilityProcessHostClient { + public: + SafeManifestJSONParser( + extensions::ManagementGetPermissionWarningsByManifestFunction* client, + const std::string& manifest) + : client_(client), manifest_(manifest) {} + + void Start() { + CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + content::BrowserThread::PostTask( + content::BrowserThread::IO, FROM_HERE, + base::Bind(&SafeManifestJSONParser::StartWorkOnIOThread, this)); + } + + void StartWorkOnIOThread() { + CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); + content::UtilityProcessHost* host = content::UtilityProcessHost::Create( + this, base::MessageLoopProxy::current().get()); + host->Send(new ChromeUtilityMsg_ParseJSON(manifest_)); + } + + bool OnMessageReceived(const IPC::Message& message) override { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(SafeManifestJSONParser, message) + IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Succeeded, + OnJSONParseSucceeded) + IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Failed, + OnJSONParseFailed) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; + } + + void OnJSONParseSucceeded(const base::ListValue& wrapper) { + CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); + const base::Value* value = NULL; + CHECK(wrapper.Get(0, &value)); + if (value->IsType(base::Value::TYPE_DICTIONARY)) + parsed_manifest_.reset( + static_cast<const base::DictionaryValue*>(value)->DeepCopy()); + else + error_ = extension_management_api_constants::kManifestParseError; + + content::BrowserThread::PostTask( + content::BrowserThread::UI, FROM_HERE, + base::Bind(&SafeManifestJSONParser::ReportResultFromUIThread, this)); + } + + void OnJSONParseFailed(const std::string& error) { + CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); + error_ = error; + content::BrowserThread::PostTask( + content::BrowserThread::UI, FROM_HERE, + base::Bind(&SafeManifestJSONParser::ReportResultFromUIThread, this)); + } + + void ReportResultFromUIThread() { + CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + if (error_.empty() && parsed_manifest_.get()) + client_->OnParseSuccess(parsed_manifest_.Pass()); + else + client_->OnParseFailure(error_); + } + + private: + ~SafeManifestJSONParser() override {} + + // The client who we'll report results back to. + extensions::ManagementGetPermissionWarningsByManifestFunction* client_; + + // Data to parse. + std::string manifest_; + + // Results of parsing. + scoped_ptr<base::DictionaryValue> parsed_manifest_; + + std::string error_; +}; + +class ManagementSetEnabledFunctionInstallPromptDelegate + : public ExtensionInstallPrompt::Delegate, + public extensions::InstallPromptDelegate { + public: + ManagementSetEnabledFunctionInstallPromptDelegate( + extensions::ManagementSetEnabledFunction* function, + const extensions::Extension* extension) + : function_(function), details_(function) { + install_prompt_.reset( + new ExtensionInstallPrompt(details_.GetAssociatedWebContents())); + install_prompt_->ConfirmReEnable(this, extension); + } + virtual ~ManagementSetEnabledFunctionInstallPromptDelegate() {} + + protected: + // ExtensionInstallPrompt::Delegate. + void InstallUIProceed() override { function_->InstallUIProceed(); } + void InstallUIAbort(bool user_initiated) override { + function_->InstallUIAbort(user_initiated); + } + + private: + extensions::ManagementSetEnabledFunction* function_; + ChromeExtensionFunctionDetails details_; + + // Used for prompting to re-enable items with permissions escalation updates. + scoped_ptr<ExtensionInstallPrompt> install_prompt_; +}; + +class ManagementUninstallFunctionUninstallDialogDelegate + : public extensions::ExtensionUninstallDialog::Delegate, + public extensions::UninstallDialogDelegate { + public: + ManagementUninstallFunctionUninstallDialogDelegate( + extensions::ManagementUninstallFunctionBase* function, + const std::string& target_extension_id) + : function_(function) { + const extensions::Extension* target_extension = + extensions::ExtensionRegistry::Get(function->browser_context()) + ->GetExtensionById(target_extension_id, + extensions::ExtensionRegistry::EVERYTHING); + content::WebContents* web_contents = function->GetAssociatedWebContents(); + extension_uninstall_dialog_.reset( + extensions::ExtensionUninstallDialog::Create( + Profile::FromBrowserContext(function->browser_context()), + web_contents ? web_contents->GetTopLevelNativeWindow() : NULL, + this)); + if (function->extension_id() != target_extension_id) { + extension_uninstall_dialog_->ConfirmProgrammaticUninstall( + target_extension, function->extension()); + } else { + // If this is a self uninstall, show the generic uninstall dialog. + extension_uninstall_dialog_->ConfirmUninstall(target_extension); + } + } + ~ManagementUninstallFunctionUninstallDialogDelegate() override {} + + // ExtensionUninstallDialog::Delegate implementation. + void ExtensionUninstallAccepted() override { + function_->ExtensionUninstallAccepted(); + } + void ExtensionUninstallCanceled() override { + function_->ExtensionUninstallCanceled(); + } + + protected: + extensions::ManagementUninstallFunctionBase* function_; + scoped_ptr<extensions::ExtensionUninstallDialog> extension_uninstall_dialog_; +}; + +class ChromeAppForLinkDelegate : public extensions::AppForLinkDelegate { + public: + ChromeAppForLinkDelegate() {} + ~ChromeAppForLinkDelegate() override {} + + void OnFaviconForApp( + extensions::ManagementGenerateAppForLinkFunction* function, + content::BrowserContext* context, + const std::string& title, + const GURL& launch_url, + const favicon_base::FaviconImageResult& image_result) { + WebApplicationInfo web_app; + web_app.title = base::UTF8ToUTF16(std::string(title)); + web_app.app_url = launch_url; + + if (!image_result.image.IsEmpty()) { + WebApplicationInfo::IconInfo icon; + icon.data = image_result.image.AsBitmap(); + icon.width = icon.data.width(); + icon.height = icon.data.height(); + web_app.icons.push_back(icon); + } + + bookmark_app_helper_.reset(new extensions::BookmarkAppHelper( + extensions::ExtensionSystem::Get(context)->extension_service(), web_app, + NULL)); + bookmark_app_helper_->Create( + base::Bind(&extensions::ManagementGenerateAppForLinkFunction:: + FinishCreateBookmarkApp, + function)); + } + + scoped_ptr<extensions::BookmarkAppHelper> bookmark_app_helper_; + + // Used for favicon loading tasks. + base::CancelableTaskTracker cancelable_task_tracker_; +}; + +} // namespace + +ChromeManagementAPIDelegate::ChromeManagementAPIDelegate() { +} + +ChromeManagementAPIDelegate::~ChromeManagementAPIDelegate() { +} + +bool ChromeManagementAPIDelegate::LaunchAppFunctionDelegate( + const extensions::Extension* extension, + content::BrowserContext* context) const { + // Look at prefs to find the right launch container. + // If the user has not set a preference, the default launch value will be + // returned. + extensions::LaunchContainer launch_container = + GetLaunchContainer(extensions::ExtensionPrefs::Get(context), extension); + OpenApplication(AppLaunchParams(Profile::FromBrowserContext(context), + extension, launch_container, + NEW_FOREGROUND_TAB)); + CoreAppLauncherHandler::RecordAppLaunchType( + extension_misc::APP_LAUNCH_EXTENSION_API, extension->GetType()); + + return true; +} + +GURL ChromeManagementAPIDelegate::GetFullLaunchURL( + const extensions::Extension* extension) const { + return extensions::AppLaunchInfo::GetFullLaunchURL(extension); +} + +extensions::LaunchType ChromeManagementAPIDelegate::GetLaunchType( + const extensions::ExtensionPrefs* prefs, + const extensions::Extension* extension) const { + return extensions::GetLaunchType(prefs, extension); +} + +void ChromeManagementAPIDelegate:: + GetPermissionWarningsByManifestFunctionDelegate( + extensions::ManagementGetPermissionWarningsByManifestFunction* function, + const std::string& manifest_str) const { + scoped_refptr<SafeManifestJSONParser> parser = + new SafeManifestJSONParser(function, manifest_str); + parser->Start(); +} + +scoped_ptr<extensions::InstallPromptDelegate> +ChromeManagementAPIDelegate::SetEnabledFunctionDelegate( + extensions::ManagementSetEnabledFunction* function, + const extensions::Extension* extension) const { + return scoped_ptr<ManagementSetEnabledFunctionInstallPromptDelegate>( + new ManagementSetEnabledFunctionInstallPromptDelegate(function, + extension)); +} + +scoped_ptr<extensions::UninstallDialogDelegate> +ChromeManagementAPIDelegate::UninstallFunctionDelegate( + extensions::ManagementUninstallFunctionBase* function, + const std::string& target_extension_id) const { + return scoped_ptr<extensions::UninstallDialogDelegate>( + new ManagementUninstallFunctionUninstallDialogDelegate( + function, target_extension_id)); +} + +bool ChromeManagementAPIDelegate::CreateAppShortcutFunctionDelegate( + extensions::ManagementCreateAppShortcutFunction* function, + const extensions::Extension* extension) const { + Browser* browser = chrome::FindBrowserWithProfile( + Profile::FromBrowserContext(function->browser_context()), + chrome::HOST_DESKTOP_TYPE_NATIVE); + if (!browser) { + // Shouldn't happen if we have user gesture. + function->SetError( + extension_management_api_constants::kNoBrowserToCreateShortcut); + return false; + } + + chrome::ShowCreateChromeAppShortcutsDialog( + browser->window()->GetNativeWindow(), browser->profile(), extension, + base::Bind(&extensions::ManagementCreateAppShortcutFunction:: + OnCloseShortcutPrompt, + function)); + + return true; +} + +scoped_ptr<extensions::AppForLinkDelegate> +ChromeManagementAPIDelegate::GenerateAppForLinkFunctionDelegate( + extensions::ManagementGenerateAppForLinkFunction* function, + content::BrowserContext* context, + const std::string& title, + const GURL& launch_url) const { + FaviconService* favicon_service = FaviconServiceFactory::GetForProfile( + Profile::FromBrowserContext(context), Profile::EXPLICIT_ACCESS); + DCHECK(favicon_service); + + ChromeAppForLinkDelegate* delegate = new ChromeAppForLinkDelegate; + + favicon_service->GetFaviconImageForPageURL( + launch_url, + base::Bind( + &ChromeAppForLinkDelegate::OnFaviconForApp, + base::Unretained(delegate), + scoped_refptr<extensions::ManagementGenerateAppForLinkFunction>( + function), + context, title, launch_url), + &delegate->cancelable_task_tracker_); + + return scoped_ptr<extensions::AppForLinkDelegate>(delegate); +} + +bool ChromeManagementAPIDelegate::IsStreamlinedHostedAppsEnabled() const { + return extensions::util::IsStreamlinedHostedAppsEnabled(); +} + +void ChromeManagementAPIDelegate::EnableExtension( + content::BrowserContext* context, + const std::string& extension_id) const { + extensions::ExtensionSystem::Get(context) + ->extension_service() + ->EnableExtension(extension_id); +} + +void ChromeManagementAPIDelegate::DisableExtension( + content::BrowserContext* context, + const std::string& extension_id, + extensions::Extension::DisableReason disable_reason) const { + extensions::ExtensionSystem::Get(context) + ->extension_service() + ->DisableExtension(extension_id, disable_reason); +} + +bool ChromeManagementAPIDelegate::UninstallExtension( + content::BrowserContext* context, + const std::string& transient_extension_id, + extensions::UninstallReason reason, + const base::Closure& deletion_done_callback, + base::string16* error) const { + return extensions::ExtensionSystem::Get(context) + ->extension_service() + ->UninstallExtension(transient_extension_id, reason, + deletion_done_callback, error); +} + +void ChromeManagementAPIDelegate::SetLaunchType( + content::BrowserContext* context, + const std::string& extension_id, + extensions::LaunchType launch_type) const { + extensions::SetLaunchType( + extensions::ExtensionSystem::Get(context)->extension_service(), + extension_id, launch_type); +} + +GURL ChromeManagementAPIDelegate::GetIconURL( + const extensions::Extension* extension, + int icon_size, + ExtensionIconSet::MatchType match, + bool grayscale, + bool* exists) const { + return extensions::ExtensionIconSource::GetIconURL(extension, icon_size, + match, grayscale, exists); +} |