diff options
Diffstat (limited to 'extensions/browser')
10 files changed, 1424 insertions, 3 deletions
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn index 0fb6496..e04baaf 100644 --- a/extensions/browser/BUILD.gn +++ b/extensions/browser/BUILD.gn @@ -50,8 +50,6 @@ source_set("browser") { "api/app_view/app_view_guest_internal_api.h", "api/app_window/app_window_api.cc", "api/app_window/app_window_api.h", - "api/guest_view/guest_view_internal_api.cc", - "api/guest_view/guest_view_internal_api.h", "api/async_api_function.cc", "api/async_api_function.h", "api/bluetooth/bluetooth_api.cc", @@ -143,12 +141,19 @@ source_set("browser") { "api/execute_code_function.h", "api/extensions_api_client.cc", "api/extensions_api_client.h", + "api/guest_view/guest_view_internal_api.cc", + "api/guest_view/guest_view_internal_api.h", "api/hid/hid_api.cc", "api/hid/hid_api.h", "api/hid/hid_connection_resource.cc", "api/hid/hid_connection_resource.h", "api/hid/hid_device_manager.cc", "api/hid/hid_device_manager.h", + "api/management/management_api.cc", + "api/management/management_api.h", + "api/management/management_api_constants.cc", + "api/management/management_api_constants.h", + "api/management/management_api_delegate.h", "api/messaging/native_message_host.cc", "api/power/power_api.cc", "api/power/power_api.h", diff --git a/extensions/browser/api/extensions_api_client.cc b/extensions/browser/api/extensions_api_client.cc index 222e686..d588a6b 100644 --- a/extensions/browser/api/extensions_api_client.cc +++ b/extensions/browser/api/extensions_api_client.cc @@ -81,4 +81,9 @@ ExtensionsAPIClient::CreateVirtualKeyboardDelegate() const { return nullptr; } +ManagementAPIDelegate* ExtensionsAPIClient::CreateManagementAPIDelegate() + const { + return nullptr; +} + } // namespace extensions diff --git a/extensions/browser/api/extensions_api_client.h b/extensions/browser/api/extensions_api_client.h index 96db1b0..f6c9e25 100644 --- a/extensions/browser/api/extensions_api_client.h +++ b/extensions/browser/api/extensions_api_client.h @@ -29,6 +29,7 @@ class ContentRulesRegistry; class DevicePermissionsPrompt; class ExtensionOptionsGuest; class ExtensionOptionsGuestDelegate; +class ManagementAPIDelegate; class MimeHandlerViewGuest; class MimeHandlerViewGuestDelegate; class WebViewGuest; @@ -107,6 +108,9 @@ class ExtensionsAPIClient { virtual scoped_ptr<VirtualKeyboardDelegate> CreateVirtualKeyboardDelegate() const; + // Creates a delegate for handling the management extension api. + virtual ManagementAPIDelegate* CreateManagementAPIDelegate() const; + // NOTE: If this interface gains too many methods (perhaps more than 20) it // should be split into one interface per API. }; diff --git a/extensions/browser/api/management/management_api.cc b/extensions/browser/api/management/management_api.cc new file mode 100644 index 0000000..bcf42b8 --- /dev/null +++ b/extensions/browser/api/management/management_api.cc @@ -0,0 +1,899 @@ +// Copyright (c) 2012 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 "extensions/browser/api/management/management_api.h" + +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/bind.h" +#include "base/json/json_writer.h" +#include "base/lazy_instance.h" +#include "base/logging.h" +#include "base/memory/linked_ptr.h" +#include "base/memory/scoped_ptr.h" +#include "base/metrics/histogram.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" +#include "content/public/browser/browser_context.h" +#include "extensions/browser/api/extensions_api_client.h" +#include "extensions/browser/api/management/management_api_constants.h" +#include "extensions/browser/event_router.h" +#include "extensions/browser/extension_prefs.h" +#include "extensions/browser/extension_registry.h" +#include "extensions/browser/extension_system.h" +#include "extensions/browser/management_policy.h" +#include "extensions/browser/uninstall_reason.h" +#include "extensions/common/api/management.h" +#include "extensions/common/constants.h" +#include "extensions/common/error_utils.h" +#include "extensions/common/extension.h" +#include "extensions/common/extension_icon_set.h" +#include "extensions/common/manifest_handlers/icons_handler.h" +#include "extensions/common/manifest_handlers/offline_enabled_info.h" +#include "extensions/common/manifest_handlers/options_page_info.h" +#include "extensions/common/manifest_url_handlers.h" +#include "extensions/common/permissions/permission_set.h" +#include "extensions/common/permissions/permissions_data.h" +#include "extensions/common/url_pattern.h" + +using base::IntToString; +using content::BrowserThread; + +namespace keys = extension_management_api_constants; + +namespace extensions { + +namespace management = core_api::management; + +namespace { + +typedef std::vector<linked_ptr<management::ExtensionInfo>> ExtensionInfoList; +typedef std::vector<linked_ptr<management::IconInfo>> IconInfoList; + +enum AutoConfirmForTest { DO_NOT_SKIP = 0, PROCEED, ABORT }; + +AutoConfirmForTest auto_confirm_for_test = DO_NOT_SKIP; + +std::vector<std::string> CreateWarningsList(const Extension* extension) { + std::vector<std::string> warnings_list; + PermissionMessages warnings = + extension->permissions_data()->GetPermissionMessages(); + for (PermissionMessages::const_iterator iter = warnings.begin(); + iter != warnings.end(); ++iter) { + warnings_list.push_back(base::UTF16ToUTF8(iter->message())); + } + + return warnings_list; +} + +std::vector<management::LaunchType> GetAvailableLaunchTypes( + const Extension& extension, + const ManagementAPIDelegate* delegate) { + std::vector<management::LaunchType> launch_type_list; + if (extension.is_platform_app()) { + launch_type_list.push_back(management::LAUNCH_TYPE_OPEN_AS_WINDOW); + return launch_type_list; + } + + launch_type_list.push_back(management::LAUNCH_TYPE_OPEN_AS_REGULAR_TAB); + +#if !defined(OS_MACOSX) + launch_type_list.push_back(management::LAUNCH_TYPE_OPEN_AS_WINDOW); +#endif + + if (!delegate->IsStreamlinedHostedAppsEnabled()) { + launch_type_list.push_back(management::LAUNCH_TYPE_OPEN_AS_PINNED_TAB); + launch_type_list.push_back(management::LAUNCH_TYPE_OPEN_FULL_SCREEN); + } + return launch_type_list; +} + +scoped_ptr<management::ExtensionInfo> CreateExtensionInfo( + const Extension& extension, + content::BrowserContext* context) { + ExtensionSystem* system = ExtensionSystem::Get(context); + ExtensionRegistry* registry = ExtensionRegistry::Get(context); + const ManagementAPIDelegate* delegate = + ManagementAPI::GetFactoryInstance()->Get(context)->GetDelegate(); + scoped_ptr<management::ExtensionInfo> info(new management::ExtensionInfo()); + + info->id = extension.id(); + info->name = extension.name(); + info->short_name = extension.short_name(); + info->enabled = registry->enabled_extensions().Contains(info->id); + info->offline_enabled = OfflineEnabledInfo::IsOfflineEnabled(&extension); + info->version = extension.VersionString(); + info->description = extension.description(); + info->options_url = OptionsPageInfo::GetOptionsPage(&extension).spec(); + info->homepage_url.reset( + new std::string(ManifestURL::GetHomepageURL(&extension).spec())); + info->may_disable = + system->management_policy()->UserMayModifySettings(&extension, NULL); + info->is_app = extension.is_app(); + if (info->is_app) { + if (extension.is_legacy_packaged_app()) + info->type = management::ExtensionInfo::TYPE_LEGACY_PACKAGED_APP; + else if (extension.is_hosted_app()) + info->type = management::ExtensionInfo::TYPE_HOSTED_APP; + else + info->type = management::ExtensionInfo::TYPE_PACKAGED_APP; + } else if (extension.is_theme()) { + info->type = management::ExtensionInfo::TYPE_THEME; + } else { + info->type = management::ExtensionInfo::TYPE_EXTENSION; + } + + if (info->enabled) { + info->disabled_reason = management::ExtensionInfo::DISABLED_REASON_NONE; + } else { + ExtensionPrefs* prefs = ExtensionPrefs::Get(context); + if (prefs->DidExtensionEscalatePermissions(extension.id())) { + info->disabled_reason = + management::ExtensionInfo::DISABLED_REASON_PERMISSIONS_INCREASE; + } else { + info->disabled_reason = + management::ExtensionInfo::DISABLED_REASON_UNKNOWN; + } + } + + if (!ManifestURL::GetUpdateURL(&extension).is_empty()) { + info->update_url.reset( + new std::string(ManifestURL::GetUpdateURL(&extension).spec())); + } + + if (extension.is_app()) { + info->app_launch_url.reset( + new std::string(delegate->GetFullLaunchURL(&extension).spec())); + } + + const ExtensionIconSet::IconMap& icons = + IconsInfo::GetIcons(&extension).map(); + if (!icons.empty()) { + info->icons.reset(new IconInfoList()); + ExtensionIconSet::IconMap::const_iterator icon_iter; + for (icon_iter = icons.begin(); icon_iter != icons.end(); ++icon_iter) { + management::IconInfo* icon_info = new management::IconInfo(); + icon_info->size = icon_iter->first; + GURL url = + delegate->GetIconURL(&extension, icon_info->size, + ExtensionIconSet::MATCH_EXACTLY, false, nullptr); + icon_info->url = url.spec(); + info->icons->push_back(make_linked_ptr<management::IconInfo>(icon_info)); + } + } + + const std::set<std::string> perms = + extension.permissions_data()->active_permissions()->GetAPIsAsStrings(); + if (!perms.empty()) { + std::set<std::string>::const_iterator perms_iter; + for (perms_iter = perms.begin(); perms_iter != perms.end(); ++perms_iter) + info->permissions.push_back(*perms_iter); + } + + if (!extension.is_hosted_app()) { + // Skip host permissions for hosted apps. + const URLPatternSet host_perms = + extension.permissions_data()->active_permissions()->explicit_hosts(); + if (!host_perms.is_empty()) { + for (URLPatternSet::const_iterator iter = host_perms.begin(); + iter != host_perms.end(); ++iter) { + info->host_permissions.push_back(iter->GetAsString()); + } + } + } + + switch (extension.location()) { + case Manifest::INTERNAL: + info->install_type = management::ExtensionInfo::INSTALL_TYPE_NORMAL; + break; + case Manifest::UNPACKED: + case Manifest::COMMAND_LINE: + info->install_type = management::ExtensionInfo::INSTALL_TYPE_DEVELOPMENT; + break; + case Manifest::EXTERNAL_PREF: + case Manifest::EXTERNAL_REGISTRY: + case Manifest::EXTERNAL_PREF_DOWNLOAD: + info->install_type = management::ExtensionInfo::INSTALL_TYPE_SIDELOAD; + break; + case Manifest::EXTERNAL_POLICY: + case Manifest::EXTERNAL_POLICY_DOWNLOAD: + info->install_type = management::ExtensionInfo::INSTALL_TYPE_ADMIN; + break; + case Manifest::NUM_LOCATIONS: + NOTREACHED(); + case Manifest::INVALID_LOCATION: + case Manifest::COMPONENT: + case Manifest::EXTERNAL_COMPONENT: + info->install_type = management::ExtensionInfo::INSTALL_TYPE_OTHER; + break; + } + + info->launch_type = management::LAUNCH_TYPE_NONE; + if (extension.is_app()) { + LaunchType launch_type; + if (extension.is_platform_app()) { + launch_type = LAUNCH_TYPE_WINDOW; + } else { + launch_type = + delegate->GetLaunchType(ExtensionPrefs::Get(context), &extension); + } + + switch (launch_type) { + case LAUNCH_TYPE_PINNED: + info->launch_type = management::LAUNCH_TYPE_OPEN_AS_PINNED_TAB; + break; + case LAUNCH_TYPE_REGULAR: + info->launch_type = management::LAUNCH_TYPE_OPEN_AS_REGULAR_TAB; + break; + case LAUNCH_TYPE_FULLSCREEN: + info->launch_type = management::LAUNCH_TYPE_OPEN_FULL_SCREEN; + break; + case LAUNCH_TYPE_WINDOW: + info->launch_type = management::LAUNCH_TYPE_OPEN_AS_WINDOW; + break; + case LAUNCH_TYPE_INVALID: + case NUM_LAUNCH_TYPES: + NOTREACHED(); + } + + info->available_launch_types.reset(new std::vector<management::LaunchType>( + GetAvailableLaunchTypes(extension, delegate))); + } + + return info.Pass(); +} + +bool ShouldNotBeVisible(const Extension* extension, + content::BrowserContext* context) { + return (extension->ShouldNotBeVisible() || + ExtensionPrefs::Get(context)->IsEphemeralApp(extension->id())); +} + +void AddExtensionInfo(const ExtensionSet& extensions, + ExtensionInfoList* extension_list, + content::BrowserContext* context) { + for (ExtensionSet::const_iterator iter = extensions.begin(); + iter != extensions.end(); ++iter) { + const Extension& extension = *iter->get(); + + if (ShouldNotBeVisible(&extension, context)) + continue; // Skip built-in extensions/apps. + + extension_list->push_back(make_linked_ptr<management::ExtensionInfo>( + CreateExtensionInfo(extension, context).release())); + } +} + +} // namespace + +bool ManagementGetAllFunction::RunSync() { + ExtensionInfoList extensions; + ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context()); + + AddExtensionInfo(registry->enabled_extensions(), &extensions, + browser_context()); + AddExtensionInfo(registry->disabled_extensions(), &extensions, + browser_context()); + AddExtensionInfo(registry->terminated_extensions(), &extensions, + browser_context()); + + results_ = management::GetAll::Results::Create(extensions); + return true; +} + +bool ManagementGetFunction::RunSync() { + scoped_ptr<management::Get::Params> params( + management::Get::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context()); + + const Extension* extension = + registry->GetExtensionById(params->id, ExtensionRegistry::EVERYTHING); + if (!extension) { + error_ = + ErrorUtils::FormatErrorMessage(keys::kNoExtensionError, params->id); + return false; + } + + scoped_ptr<management::ExtensionInfo> info = + CreateExtensionInfo(*extension, browser_context()); + results_ = management::Get::Results::Create(*info); + + return true; +} + +bool ManagementGetSelfFunction::RunSync() { + scoped_ptr<management::ExtensionInfo> info = + CreateExtensionInfo(*extension_, browser_context()); + results_ = management::Get::Results::Create(*info); + + return true; +} + +bool ManagementGetPermissionWarningsByIdFunction::RunSync() { + scoped_ptr<management::GetPermissionWarningsById::Params> params( + management::GetPermissionWarningsById::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + + const Extension* extension = + ExtensionRegistry::Get(browser_context()) + ->GetExtensionById(params->id, ExtensionRegistry::EVERYTHING); + if (!extension) { + error_ = + ErrorUtils::FormatErrorMessage(keys::kNoExtensionError, params->id); + return false; + } + + std::vector<std::string> warnings = CreateWarningsList(extension); + results_ = management::GetPermissionWarningsById::Results::Create(warnings); + return true; +} + +bool ManagementGetPermissionWarningsByManifestFunction::RunAsync() { + scoped_ptr<management::GetPermissionWarningsByManifest::Params> params( + management::GetPermissionWarningsByManifest::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + + const ManagementAPIDelegate* delegate = ManagementAPI::GetFactoryInstance() + ->Get(browser_context()) + ->GetDelegate(); + + if (delegate) { + delegate->GetPermissionWarningsByManifestFunctionDelegate( + this, params->manifest_str); + + // Matched with a Release() in OnParseSuccess/Failure(). + AddRef(); + + // Response is sent async in OnParseSuccess/Failure(). + return true; + } else { + // TODO(lfg) add error string + OnParseFailure(""); + return false; + } +} + +void ManagementGetPermissionWarningsByManifestFunction::OnParseSuccess( + scoped_ptr<base::DictionaryValue> parsed_manifest) { + CHECK(parsed_manifest.get()); + + scoped_refptr<Extension> extension = + Extension::Create(base::FilePath(), Manifest::INVALID_LOCATION, + *parsed_manifest, Extension::NO_FLAGS, &error_); + if (!extension.get()) { + OnParseFailure(keys::kExtensionCreateError); + return; + } + + std::vector<std::string> warnings = CreateWarningsList(extension.get()); + results_ = + management::GetPermissionWarningsByManifest::Results::Create(warnings); + SendResponse(true); + + // Matched with AddRef() in RunAsync(). + Release(); +} + +void ManagementGetPermissionWarningsByManifestFunction::OnParseFailure( + const std::string& error) { + error_ = error; + SendResponse(false); + + // Matched with AddRef() in RunAsync(). + Release(); +} + +bool ManagementLaunchAppFunction::RunSync() { + scoped_ptr<management::LaunchApp::Params> params( + management::LaunchApp::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + const Extension* extension = + ExtensionRegistry::Get(browser_context()) + ->GetExtensionById(params->id, ExtensionRegistry::EVERYTHING); + if (!extension) { + error_ = + ErrorUtils::FormatErrorMessage(keys::kNoExtensionError, params->id); + return false; + } + if (!extension->is_app()) { + error_ = ErrorUtils::FormatErrorMessage(keys::kNotAnAppError, params->id); + return false; + } + + const ManagementAPIDelegate* delegate = ManagementAPI::GetFactoryInstance() + ->Get(browser_context()) + ->GetDelegate(); + return delegate->LaunchAppFunctionDelegate(extension, browser_context()); +} + +ManagementSetEnabledFunction::ManagementSetEnabledFunction() { +} + +ManagementSetEnabledFunction::~ManagementSetEnabledFunction() { +} + +bool ManagementSetEnabledFunction::RunAsync() { + scoped_ptr<management::SetEnabled::Params> params( + management::SetEnabled::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context()); + const ManagementAPIDelegate* delegate = ManagementAPI::GetFactoryInstance() + ->Get(browser_context()) + ->GetDelegate(); + + extension_id_ = params->id; + + const Extension* extension = + registry->GetExtensionById(extension_id_, ExtensionRegistry::EVERYTHING); + if (!extension || ShouldNotBeVisible(extension, browser_context())) { + error_ = + ErrorUtils::FormatErrorMessage(keys::kNoExtensionError, extension_id_); + return false; + } + + const ManagementPolicy* policy = + ExtensionSystem::Get(browser_context())->management_policy(); + if (!policy->UserMayModifySettings(extension, NULL) || + (!params->enabled && policy->MustRemainEnabled(extension, NULL)) || + (params->enabled && policy->MustRemainDisabled(extension, NULL, NULL))) { + error_ = ErrorUtils::FormatErrorMessage(keys::kUserCantModifyError, + extension_id_); + return false; + } + + bool currently_enabled = + registry->enabled_extensions().Contains(extension_id_) || + registry->terminated_extensions().Contains(extension_id_); + + if (!currently_enabled && params->enabled) { + ExtensionPrefs* prefs = ExtensionPrefs::Get(browser_context()); + if (prefs->DidExtensionEscalatePermissions(extension_id_)) { + if (!user_gesture()) { + SetError(keys::kGestureNeededForEscalationError); + return false; + } + AddRef(); // Matched in InstallUIProceed/InstallUIAbort + install_prompt_ = delegate->SetEnabledFunctionDelegate(this, extension); + return true; + } + delegate->EnableExtension(browser_context(), extension_id_); + } else if (currently_enabled && !params->enabled) { + delegate->DisableExtension(browser_context(), extension_id_, + Extension::DISABLE_USER_ACTION); + } + + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&ManagementSetEnabledFunction::SendResponse, this, true)); + + return true; +} + +void ManagementSetEnabledFunction::InstallUIProceed() { + ManagementAPI::GetFactoryInstance() + ->Get(browser_context()) + ->GetDelegate() + ->EnableExtension(browser_context(), extension_id_); + SendResponse(true); + Release(); +} + +void ManagementSetEnabledFunction::InstallUIAbort(bool user_initiated) { + error_ = keys::kUserDidNotReEnableError; + SendResponse(false); + Release(); +} + +ManagementUninstallFunctionBase::ManagementUninstallFunctionBase() { +} + +ManagementUninstallFunctionBase::~ManagementUninstallFunctionBase() { +} + +bool ManagementUninstallFunctionBase::Uninstall( + const std::string& target_extension_id, + bool show_confirm_dialog) { + const ManagementAPIDelegate* delegate = ManagementAPI::GetFactoryInstance() + ->Get(browser_context()) + ->GetDelegate(); + extension_id_ = target_extension_id; + const Extension* target_extension = + extensions::ExtensionRegistry::Get(browser_context()) + ->GetExtensionById(extension_id_, ExtensionRegistry::EVERYTHING); + if (!target_extension || + ShouldNotBeVisible(target_extension, browser_context())) { + error_ = + ErrorUtils::FormatErrorMessage(keys::kNoExtensionError, extension_id_); + return false; + } + + if (!ExtensionSystem::Get(browser_context()) + ->management_policy() + ->UserMayModifySettings(target_extension, NULL)) { + error_ = ErrorUtils::FormatErrorMessage(keys::kUserCantModifyError, + extension_id_); + return false; + } + + if (auto_confirm_for_test == DO_NOT_SKIP) { + if (show_confirm_dialog) { + AddRef(); // Balanced in ExtensionUninstallAccepted/Canceled + delegate->UninstallFunctionDelegate(this, target_extension_id); + } else { + Finish(true); + } + } else { + Finish(auto_confirm_for_test == PROCEED); + } + + return true; +} + +// static +void ManagementUninstallFunctionBase::SetAutoConfirmForTest( + bool should_proceed) { + auto_confirm_for_test = should_proceed ? PROCEED : ABORT; +} + +void ManagementUninstallFunctionBase::Finish(bool should_uninstall) { + if (should_uninstall) { + // The extension can be uninstalled in another window while the UI was + // showing. Do nothing in that case. + ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context()); + const Extension* extension = registry->GetExtensionById( + extension_id_, ExtensionRegistry::EVERYTHING); + if (!extension) { + error_ = ErrorUtils::FormatErrorMessage(keys::kNoExtensionError, + extension_id_); + SendResponse(false); + } else { + const ManagementAPIDelegate* delegate = + ManagementAPI::GetFactoryInstance() + ->Get(browser_context()) + ->GetDelegate(); + bool success = delegate->UninstallExtension( + browser_context(), extension_id_, + extensions::UNINSTALL_REASON_MANAGEMENT_API, + base::Bind(&base::DoNothing), NULL); + + // TODO set error_ if !success + SendResponse(success); + } + } else { + error_ = ErrorUtils::FormatErrorMessage(keys::kUninstallCanceledError, + extension_id_); + SendResponse(false); + } +} + +void ManagementUninstallFunctionBase::ExtensionUninstallAccepted() { + Finish(true); + Release(); +} + +void ManagementUninstallFunctionBase::ExtensionUninstallCanceled() { + Finish(false); + Release(); +} + +ManagementUninstallFunction::ManagementUninstallFunction() { +} + +ManagementUninstallFunction::~ManagementUninstallFunction() { +} + +bool ManagementUninstallFunction::RunAsync() { + scoped_ptr<management::Uninstall::Params> params( + management::Uninstall::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(extension_.get()); + EXTENSION_FUNCTION_VALIDATE(params.get()); + + bool show_confirm_dialog = true; + // By default confirmation dialog isn't shown when uninstalling self, but this + // can be overridden with showConfirmDialog. + if (params->id == extension_->id()) { + show_confirm_dialog = params->options.get() && + params->options->show_confirm_dialog.get() && + *params->options->show_confirm_dialog; + } + if (show_confirm_dialog && !user_gesture()) { + error_ = keys::kGestureNeededForUninstallError; + return false; + } + return Uninstall(params->id, show_confirm_dialog); +} + +ManagementUninstallSelfFunction::ManagementUninstallSelfFunction() { +} + +ManagementUninstallSelfFunction::~ManagementUninstallSelfFunction() { +} + +bool ManagementUninstallSelfFunction::RunAsync() { + scoped_ptr<management::UninstallSelf::Params> params( + management::UninstallSelf::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + + bool show_confirm_dialog = false; + if (params->options.get() && params->options->show_confirm_dialog.get()) + show_confirm_dialog = *params->options->show_confirm_dialog; + return Uninstall(extension_->id(), show_confirm_dialog); +} + +ManagementCreateAppShortcutFunction::ManagementCreateAppShortcutFunction() { +} + +ManagementCreateAppShortcutFunction::~ManagementCreateAppShortcutFunction() { +} + +// static +void ManagementCreateAppShortcutFunction::SetAutoConfirmForTest( + bool should_proceed) { + auto_confirm_for_test = should_proceed ? PROCEED : ABORT; +} + +void ManagementCreateAppShortcutFunction::OnCloseShortcutPrompt(bool created) { + if (!created) + error_ = keys::kCreateShortcutCanceledError; + SendResponse(created); + Release(); +} + +bool ManagementCreateAppShortcutFunction::RunAsync() { + if (!user_gesture()) { + error_ = keys::kGestureNeededForCreateAppShortcutError; + return false; + } + + scoped_ptr<management::CreateAppShortcut::Params> params( + management::CreateAppShortcut::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + const Extension* extension = + ExtensionRegistry::Get(browser_context()) + ->GetExtensionById(params->id, ExtensionRegistry::EVERYTHING); + if (!extension) { + error_ = + ErrorUtils::FormatErrorMessage(keys::kNoExtensionError, params->id); + return false; + } + + if (!extension->is_app()) { + error_ = ErrorUtils::FormatErrorMessage(keys::kNotAnAppError, params->id); + return false; + } + +#if defined(OS_MACOSX) + if (!extension->is_platform_app()) { + error_ = keys::kCreateOnlyPackagedAppShortcutMac; + return false; + } +#endif + + if (auto_confirm_for_test != DO_NOT_SKIP) { + // Matched with a Release() in OnCloseShortcutPrompt(). + AddRef(); + + OnCloseShortcutPrompt(auto_confirm_for_test == PROCEED); + + return true; + } + + if (ManagementAPI::GetFactoryInstance() + ->Get(browser_context()) + ->GetDelegate() + ->CreateAppShortcutFunctionDelegate(this, extension)) { + // Matched with a Release() in OnCloseShortcutPrompt(). + AddRef(); + } + + // Response is sent async in OnCloseShortcutPrompt(). + return true; +} + +bool ManagementSetLaunchTypeFunction::RunSync() { + if (!user_gesture()) { + error_ = keys::kGestureNeededForSetLaunchTypeError; + return false; + } + + scoped_ptr<management::SetLaunchType::Params> params( + management::SetLaunchType::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + const Extension* extension = + ExtensionRegistry::Get(browser_context()) + ->GetExtensionById(params->id, ExtensionRegistry::EVERYTHING); + const ManagementAPIDelegate* delegate = ManagementAPI::GetFactoryInstance() + ->Get(browser_context()) + ->GetDelegate(); + if (!extension) { + error_ = + ErrorUtils::FormatErrorMessage(keys::kNoExtensionError, params->id); + return false; + } + + if (!extension->is_app()) { + error_ = ErrorUtils::FormatErrorMessage(keys::kNotAnAppError, params->id); + return false; + } + + std::vector<management::LaunchType> available_launch_types = + GetAvailableLaunchTypes(*extension, delegate); + + management::LaunchType app_launch_type = params->launch_type; + if (std::find(available_launch_types.begin(), available_launch_types.end(), + app_launch_type) == available_launch_types.end()) { + error_ = keys::kLaunchTypeNotAvailableError; + return false; + } + + LaunchType launch_type = LAUNCH_TYPE_DEFAULT; + switch (app_launch_type) { + case management::LAUNCH_TYPE_OPEN_AS_PINNED_TAB: + launch_type = LAUNCH_TYPE_PINNED; + break; + case management::LAUNCH_TYPE_OPEN_AS_REGULAR_TAB: + launch_type = LAUNCH_TYPE_REGULAR; + break; + case management::LAUNCH_TYPE_OPEN_FULL_SCREEN: + launch_type = LAUNCH_TYPE_FULLSCREEN; + break; + case management::LAUNCH_TYPE_OPEN_AS_WINDOW: + launch_type = LAUNCH_TYPE_WINDOW; + break; + case management::LAUNCH_TYPE_NONE: + NOTREACHED(); + } + + delegate->SetLaunchType(browser_context(), params->id, launch_type); + + return true; +} + +ManagementGenerateAppForLinkFunction::ManagementGenerateAppForLinkFunction() { +} + +ManagementGenerateAppForLinkFunction::~ManagementGenerateAppForLinkFunction() { +} + +void ManagementGenerateAppForLinkFunction::FinishCreateBookmarkApp( + const Extension* extension, + const WebApplicationInfo& web_app_info) { + if (extension) { + scoped_ptr<management::ExtensionInfo> info = + CreateExtensionInfo(*extension, browser_context()); + results_ = management::GenerateAppForLink::Results::Create(*info); + + SendResponse(true); + Release(); + } else { + error_ = keys::kGenerateAppForLinkInstallError; + SendResponse(false); + Release(); + } +} + +bool ManagementGenerateAppForLinkFunction::RunAsync() { + if (!user_gesture()) { + error_ = keys::kGestureNeededForGenerateAppForLinkError; + return false; + } + + scoped_ptr<management::GenerateAppForLink::Params> params( + management::GenerateAppForLink::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + + GURL launch_url(params->url); + if (!launch_url.is_valid() || !launch_url.SchemeIsHTTPOrHTTPS()) { + error_ = + ErrorUtils::FormatErrorMessage(keys::kInvalidURLError, params->url); + return false; + } + + if (params->title.empty()) { + error_ = keys::kEmptyTitleError; + return false; + } + + app_for_link_delegate_ = + ManagementAPI::GetFactoryInstance() + ->Get(browser_context()) + ->GetDelegate() + ->GenerateAppForLinkFunctionDelegate(this, browser_context(), + params->title, launch_url); + + // Matched with a Release() in FinishCreateBookmarkApp(). + AddRef(); + + // Response is sent async in FinishCreateBookmarkApp(). + return true; +} + +ManagementEventRouter::ManagementEventRouter(content::BrowserContext* context) + : browser_context_(context), extension_registry_observer_(this) { + extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); +} + +ManagementEventRouter::~ManagementEventRouter() { +} + +void ManagementEventRouter::OnExtensionLoaded( + content::BrowserContext* browser_context, + const Extension* extension) { + BroadcastEvent(extension, management::OnEnabled::kEventName); +} + +void ManagementEventRouter::OnExtensionUnloaded( + content::BrowserContext* browser_context, + const Extension* extension, + UnloadedExtensionInfo::Reason reason) { + BroadcastEvent(extension, management::OnDisabled::kEventName); +} + +void ManagementEventRouter::OnExtensionInstalled( + content::BrowserContext* browser_context, + const Extension* extension, + bool is_update) { + BroadcastEvent(extension, management::OnInstalled::kEventName); +} + +void ManagementEventRouter::OnExtensionUninstalled( + content::BrowserContext* browser_context, + const Extension* extension, + extensions::UninstallReason reason) { + BroadcastEvent(extension, management::OnUninstalled::kEventName); +} + +void ManagementEventRouter::BroadcastEvent(const Extension* extension, + const char* event_name) { + if (ShouldNotBeVisible(extension, browser_context_)) + return; // Don't dispatch events for built-in extenions. + scoped_ptr<base::ListValue> args(new base::ListValue()); + if (event_name == management::OnUninstalled::kEventName) { + args->Append(new base::StringValue(extension->id())); + } else { + scoped_ptr<management::ExtensionInfo> info = + CreateExtensionInfo(*extension, browser_context_); + args->Append(info->ToValue().release()); + } + + EventRouter::Get(browser_context_) + ->BroadcastEvent(scoped_ptr<Event>(new Event(event_name, args.Pass()))); +} + +ManagementAPI::ManagementAPI(content::BrowserContext* context) + : browser_context_(context), + delegate_(ExtensionsAPIClient::Get()->CreateManagementAPIDelegate()) { + EventRouter* event_router = EventRouter::Get(browser_context_); + event_router->RegisterObserver(this, management::OnInstalled::kEventName); + event_router->RegisterObserver(this, management::OnUninstalled::kEventName); + event_router->RegisterObserver(this, management::OnEnabled::kEventName); + event_router->RegisterObserver(this, management::OnDisabled::kEventName); +} + +ManagementAPI::~ManagementAPI() { +} + +void ManagementAPI::Shutdown() { + EventRouter::Get(browser_context_)->UnregisterObserver(this); +} + +static base::LazyInstance<BrowserContextKeyedAPIFactory<ManagementAPI>> + g_factory = LAZY_INSTANCE_INITIALIZER; + +// static +BrowserContextKeyedAPIFactory<ManagementAPI>* +ManagementAPI::GetFactoryInstance() { + return g_factory.Pointer(); +} + +void ManagementAPI::OnListenerAdded(const EventListenerInfo& details) { + management_event_router_.reset(new ManagementEventRouter(browser_context_)); + EventRouter::Get(browser_context_)->UnregisterObserver(this); +} + +} // namespace extensions diff --git a/extensions/browser/api/management/management_api.h b/extensions/browser/api/management/management_api.h new file mode 100644 index 0000000..d12903b --- /dev/null +++ b/extensions/browser/api/management/management_api.h @@ -0,0 +1,292 @@ +// Copyright (c) 2012 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. + +#ifndef EXTENSIONS_BROWSER_API_MANAGEMENT_MANAGEMENT_API_H_ +#define EXTENSIONS_BROWSER_API_MANAGEMENT_MANAGEMENT_API_H_ + +#include "base/compiler_specific.h" +#include "base/scoped_observer.h" +#include "components/keyed_service/core/keyed_service.h" +#include "extensions/browser/api/management/management_api_delegate.h" +#include "extensions/browser/browser_context_keyed_api_factory.h" +#include "extensions/browser/event_router.h" +#include "extensions/browser/extension_function.h" +#include "extensions/browser/extension_registry_observer.h" + +class ExtensionRegistry; +class ExtensionUninstallDialog; +struct WebApplicationInfo; + +namespace extensions { +class ExtensionRegistry; + +class ManagementFunction : public SyncExtensionFunction { + protected: + ~ManagementFunction() override {} +}; + +class AsyncManagementFunction : public AsyncExtensionFunction { + protected: + ~AsyncManagementFunction() override {} +}; + +class ManagementGetAllFunction : public ManagementFunction { + public: + DECLARE_EXTENSION_FUNCTION("management.getAll", MANAGEMENT_GETALL) + + protected: + ~ManagementGetAllFunction() override {} + + // ExtensionFunction: + bool RunSync() override; +}; + +class ManagementGetFunction : public ManagementFunction { + public: + DECLARE_EXTENSION_FUNCTION("management.get", MANAGEMENT_GET) + + protected: + ~ManagementGetFunction() override {} + + // ExtensionFunction: + bool RunSync() override; +}; + +class ManagementGetSelfFunction : public ManagementFunction { + public: + DECLARE_EXTENSION_FUNCTION("management.getSelf", MANAGEMENT_GETSELF) + + protected: + ~ManagementGetSelfFunction() override {} + + // ExtensionFunction: + bool RunSync() override; +}; + +class ManagementGetPermissionWarningsByIdFunction : public ManagementFunction { + public: + DECLARE_EXTENSION_FUNCTION("management.getPermissionWarningsById", + MANAGEMENT_GETPERMISSIONWARNINGSBYID) + + protected: + ~ManagementGetPermissionWarningsByIdFunction() override {} + + // ExtensionFunction: + bool RunSync() override; +}; + +class ManagementGetPermissionWarningsByManifestFunction + : public AsyncExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION("management.getPermissionWarningsByManifest", + MANAGEMENT_GETPERMISSIONWARNINGSBYMANIFEST); + + // Called when utility process finishes. + void OnParseSuccess(scoped_ptr<base::DictionaryValue> parsed_manifest); + void OnParseFailure(const std::string& error); + + protected: + ~ManagementGetPermissionWarningsByManifestFunction() override {} + + // ExtensionFunction: + bool RunAsync() override; +}; + +class ManagementLaunchAppFunction : public ManagementFunction { + public: + DECLARE_EXTENSION_FUNCTION("management.launchApp", MANAGEMENT_LAUNCHAPP) + + protected: + ~ManagementLaunchAppFunction() override {} + + // ExtensionFunction: + bool RunSync() override; +}; + +class ManagementSetEnabledFunction : public AsyncManagementFunction { + public: + DECLARE_EXTENSION_FUNCTION("management.setEnabled", MANAGEMENT_SETENABLED) + + ManagementSetEnabledFunction(); + + void InstallUIProceed(); + void InstallUIAbort(bool user_initiated); + + protected: + ~ManagementSetEnabledFunction() override; + + // ExtensionFunction: + bool RunAsync() override; + + private: + std::string extension_id_; + + scoped_ptr<InstallPromptDelegate> install_prompt_; +}; + +class ManagementUninstallFunctionBase : public AsyncManagementFunction { + public: + ManagementUninstallFunctionBase(); + + static void SetAutoConfirmForTest(bool should_proceed); + + void ExtensionUninstallAccepted(); + void ExtensionUninstallCanceled(); + + protected: + ~ManagementUninstallFunctionBase() override; + + bool Uninstall(const std::string& extension_id, bool show_confirm_dialog); + + private: + // If should_uninstall is true, this method does the actual uninstall. + // If |show_uninstall_dialog|, then this function will be called by one of the + // Accepted/Canceled callbacks. Otherwise, it's called directly from RunAsync. + void Finish(bool should_uninstall); + + std::string extension_id_; + + scoped_ptr<UninstallDialogDelegate> uninstall_dialog_; +}; + +class ManagementUninstallFunction : public ManagementUninstallFunctionBase { + public: + DECLARE_EXTENSION_FUNCTION("management.uninstall", MANAGEMENT_UNINSTALL) + + ManagementUninstallFunction(); + + private: + ~ManagementUninstallFunction() override; + + bool RunAsync() override; +}; + +class ManagementUninstallSelfFunction : public ManagementUninstallFunctionBase { + public: + DECLARE_EXTENSION_FUNCTION("management.uninstallSelf", + MANAGEMENT_UNINSTALLSELF); + + ManagementUninstallSelfFunction(); + + private: + ~ManagementUninstallSelfFunction() override; + + bool RunAsync() override; +}; + +class ManagementCreateAppShortcutFunction : public AsyncManagementFunction { + public: + DECLARE_EXTENSION_FUNCTION("management.createAppShortcut", + MANAGEMENT_CREATEAPPSHORTCUT); + + ManagementCreateAppShortcutFunction(); + + void OnCloseShortcutPrompt(bool created); + + static void SetAutoConfirmForTest(bool should_proceed); + + protected: + ~ManagementCreateAppShortcutFunction() override; + + bool RunAsync() override; +}; + +class ManagementSetLaunchTypeFunction : public ManagementFunction { + public: + DECLARE_EXTENSION_FUNCTION("management.setLaunchType", + MANAGEMENT_SETLAUNCHTYPE); + + protected: + ~ManagementSetLaunchTypeFunction() override {} + + bool RunSync() override; +}; + +class ManagementGenerateAppForLinkFunction : public AsyncManagementFunction { + public: + DECLARE_EXTENSION_FUNCTION("management.generateAppForLink", + MANAGEMENT_GENERATEAPPFORLINK); + + ManagementGenerateAppForLinkFunction(); + + void FinishCreateBookmarkApp(const Extension* extension, + const WebApplicationInfo& web_app_info); + + protected: + ~ManagementGenerateAppForLinkFunction() override; + + bool RunAsync() override; + + private: + scoped_ptr<AppForLinkDelegate> app_for_link_delegate_; +}; + +class ManagementEventRouter : public ExtensionRegistryObserver { + public: + explicit ManagementEventRouter(content::BrowserContext* context); + ~ManagementEventRouter() override; + + private: + // ExtensionRegistryObserver implementation. + void OnExtensionLoaded(content::BrowserContext* browser_context, + const Extension* extension) override; + void OnExtensionUnloaded(content::BrowserContext* browser_context, + const Extension* extension, + UnloadedExtensionInfo::Reason reason) override; + void OnExtensionInstalled(content::BrowserContext* browser_context, + const Extension* extension, + bool is_update) override; + void OnExtensionUninstalled(content::BrowserContext* browser_context, + const Extension* extension, + extensions::UninstallReason reason) override; + + // Dispatches management api events to listening extensions. + void BroadcastEvent(const Extension* extension, const char* event_name); + + content::BrowserContext* browser_context_; + + ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> + extension_registry_observer_; + + DISALLOW_COPY_AND_ASSIGN(ManagementEventRouter); +}; + +class ManagementAPI : public BrowserContextKeyedAPI, + public EventRouter::Observer { + public: + explicit ManagementAPI(content::BrowserContext* context); + ~ManagementAPI() override; + + // KeyedService implementation. + void Shutdown() override; + + // BrowserContextKeyedAPI implementation. + static BrowserContextKeyedAPIFactory<ManagementAPI>* GetFactoryInstance(); + + // EventRouter::Observer implementation. + void OnListenerAdded(const EventListenerInfo& details) override; + + // Returns the ManagementAPI delegate. + const ManagementAPIDelegate* GetDelegate() const { return delegate_.get(); } + + private: + friend class BrowserContextKeyedAPIFactory<ManagementAPI>; + + content::BrowserContext* browser_context_; + + // BrowserContextKeyedAPI implementation. + static const char* service_name() { return "ManagementAPI"; } + static const bool kServiceIsNULLWhileTesting = true; + + // Created lazily upon OnListenerAdded. + scoped_ptr<ManagementEventRouter> management_event_router_; + + scoped_ptr<ManagementAPIDelegate> delegate_; + + DISALLOW_COPY_AND_ASSIGN(ManagementAPI); +}; + +} // namespace extensions + +#endif // EXTENSIONS_BROWSER_API_MANAGEMENT_MANAGEMENT_API_H_ diff --git a/extensions/browser/api/management/management_api_constants.cc b/extensions/browser/api/management/management_api_constants.cc new file mode 100644 index 0000000..f4fb8ff --- /dev/null +++ b/extensions/browser/api/management/management_api_constants.cc @@ -0,0 +1,47 @@ +// Copyright (c) 2012 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 "extensions/browser/api/management/management_api_constants.h" + +namespace extension_management_api_constants { + +const char kDisabledReasonKey[] = "disabledReason"; + +const char kDisabledReasonPermissionsIncrease[] = "permissions_increase"; + +const char kExtensionCreateError[] = + "Failed to create extension from manifest."; +const char kGestureNeededForEscalationError[] = + "Re-enabling an extension disabled due to permissions increase " + "requires a user gesture."; +const char kGestureNeededForUninstallError[] = + "chrome.management.uninstall requires a user gesture."; +const char kManifestParseError[] = "Failed to parse manifest."; +const char kNoExtensionError[] = "Failed to find extension with id *."; +const char kNotAnAppError[] = "Extension * is not an App."; +const char kUserCantModifyError[] = "Extension * cannot be modified by user."; +const char kUninstallCanceledError[] = + "Extension * uninstall canceled by user."; +const char kUserDidNotReEnableError[] = + "The user did not accept the re-enable dialog."; +const char kGestureNeededForCreateAppShortcutError[] = + "chrome.management.createAppShortcut requires a user gesture."; +const char kNoBrowserToCreateShortcut[] = + "There is no browser window to create shortcut."; +const char kCreateOnlyPackagedAppShortcutMac[] = + "Shortcuts can only be created for new-style packaged apps on Mac."; +const char kCreateShortcutCanceledError[] = + "App shortcuts creation canceled by user."; +const char kGestureNeededForSetLaunchTypeError[] = + "chrome.management.setLaunchType requires a user gesture."; +const char kLaunchTypeNotAvailableError[] = + "The launch type is not available for this app."; +const char kGestureNeededForGenerateAppForLinkError[] = + "chrome.management.generateAppForLink requires a user gesture."; +const char kInvalidURLError[] = "The URL \"*\" is invalid."; +const char kEmptyTitleError[] = "The title can not be empty."; +const char kGenerateAppForLinkInstallError[] = + "Failed to install the generated app."; + +} // namespace extension_management_api_constants diff --git a/extensions/browser/api/management/management_api_constants.h b/extensions/browser/api/management/management_api_constants.h new file mode 100644 index 0000000..faadae1 --- /dev/null +++ b/extensions/browser/api/management/management_api_constants.h @@ -0,0 +1,39 @@ +// Copyright (c) 2012 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. + +#ifndef EXTENSIONS_BROWSER_API_MANAGEMENT_MANAGEMENT_API_CONSTANTS_H_ +#define EXTENSIONS_BROWSER_API_MANAGEMENT_MANAGEMENT_API_CONSTANTS_H_ + +namespace extension_management_api_constants { + +// Keys used for incoming arguments and outgoing JSON data. +extern const char kDisabledReasonKey[]; + +// Values for outgoing JSON data. +extern const char kDisabledReasonPermissionsIncrease[]; + +// Error messages. +extern const char kExtensionCreateError[]; +extern const char kGestureNeededForEscalationError[]; +extern const char kGestureNeededForUninstallError[]; +extern const char kManifestParseError[]; +extern const char kNoExtensionError[]; +extern const char kNotAnAppError[]; +extern const char kUserCantModifyError[]; +extern const char kUninstallCanceledError[]; +extern const char kUserDidNotReEnableError[]; +extern const char kGestureNeededForCreateAppShortcutError[]; +extern const char kNoBrowserToCreateShortcut[]; +extern const char kCreateOnlyPackagedAppShortcutMac[]; +extern const char kCreateShortcutCanceledError[]; +extern const char kGestureNeededForSetLaunchTypeError[]; +extern const char kLaunchTypeNotAvailableError[]; +extern const char kGestureNeededForGenerateAppForLinkError[]; +extern const char kInvalidURLError[]; +extern const char kEmptyTitleError[]; +extern const char kGenerateAppForLinkInstallError[]; + +} // namespace extension_management_api_constants + +#endif // EXTENSIONS_BROWSER_API_MANAGEMENT_MANAGEMENT_API_CONSTANTS_H_ diff --git a/extensions/browser/api/management/management_api_delegate.h b/extensions/browser/api/management/management_api_delegate.h new file mode 100644 index 0000000..c81ef09 --- /dev/null +++ b/extensions/browser/api/management/management_api_delegate.h @@ -0,0 +1,128 @@ +// 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. + +#ifndef EXTENSIONS_BROWSER_API_MANAGEMENT_MANAGEMENT_API_DELEGATER_H_ +#define EXTENSIONS_BROWSER_API_MANAGEMENT_MANAGEMENT_API_DELEGATER_H_ + +#include "base/callback.h" +#include "extensions/browser/uninstall_reason.h" +#include "extensions/common/constants.h" +#include "extensions/common/extension.h" +#include "extensions/common/extension_icon_set.h" +#include "url/gurl.h" + +namespace content { +class BrowserContext; +} // namespace content + +namespace extensions { + +class Extension; +class ExtensionPrefs; +class ManagementCreateAppShortcutFunction; +class ManagementGenerateAppForLinkFunction; +class ManagementGetPermissionWarningsByManifestFunction; +class ManagementSetEnabledFunction; +class ManagementUninstallFunctionBase; + +// Manages the lifetime of the install prompt. +class InstallPromptDelegate { + public: + virtual ~InstallPromptDelegate() {} +}; + +// Manages the lifetime of the uninstall prompt. +class UninstallDialogDelegate { + public: + virtual ~UninstallDialogDelegate() {} +}; + +// Manages the lifetime of the bookmark app creation. +class AppForLinkDelegate { + public: + virtual ~AppForLinkDelegate() {} +}; + +class ManagementAPIDelegate { + public: + virtual ~ManagementAPIDelegate() {} + + // Launches the app |extension|. Returns true on success. + virtual bool LaunchAppFunctionDelegate( + const Extension* extension, + content::BrowserContext* context) const = 0; + + // Forwards the call to extensions::util::IsStreamlinedHostedAppsEnabled in + // chrome. + virtual bool IsStreamlinedHostedAppsEnabled() const = 0; + + // Forwards the call to AppLaunchInfo::GetFullLaunchURL in chrome. + virtual GURL GetFullLaunchURL(const Extension* extension) const = 0; + + // Forwards the call to launch_util::GetLaunchType in chrome. + virtual LaunchType GetLaunchType(const ExtensionPrefs* prefs, + const Extension* extension) const = 0; + + // Parses the manifest and calls back the + // ManagementGetPermissionWarningsByManifestFunction. + virtual void GetPermissionWarningsByManifestFunctionDelegate( + ManagementGetPermissionWarningsByManifestFunction* function, + const std::string& manifest_str) const = 0; + + // Used to show a dialog prompt in chrome when management.setEnabled extension + // function is called. + virtual scoped_ptr<InstallPromptDelegate> SetEnabledFunctionDelegate( + ManagementSetEnabledFunction* function, + const Extension* extension) const = 0; + + // Enables the extension identified by |extension_id|. + virtual void EnableExtension(content::BrowserContext* context, + const std::string& extension_id) const = 0; + + // Disables the extension identified by |extension_id|. + virtual void DisableExtension( + content::BrowserContext* context, + const std::string& extension_id, + Extension::DisableReason disable_reason) const = 0; + + // Used to show a confirmation dialog when uninstalling |target_extension_id|. + virtual scoped_ptr<UninstallDialogDelegate> UninstallFunctionDelegate( + ManagementUninstallFunctionBase* function, + const std::string& target_extension_id) const = 0; + + // Uninstalls the extension. + virtual bool UninstallExtension(content::BrowserContext* context, + const std::string& transient_extension_id, + UninstallReason reason, + const base::Closure& deletion_done_callback, + base::string16* error) const = 0; + + // Creates an app shortcut. + virtual bool CreateAppShortcutFunctionDelegate( + ManagementCreateAppShortcutFunction* function, + const Extension* extension) const = 0; + + // Forwards the call to launch_util::SetLaunchType in chrome. + virtual void SetLaunchType(content::BrowserContext* context, + const std::string& extension_id, + LaunchType launch_type) const = 0; + + // Creates a bookmark app for |launch_url|. + virtual scoped_ptr<AppForLinkDelegate> GenerateAppForLinkFunctionDelegate( + ManagementGenerateAppForLinkFunction* function, + content::BrowserContext* context, + const std::string& title, + const GURL& launch_url) const = 0; + + // Forwards the call to ExtensionIconSource::GetIconURL in chrome. + virtual GURL GetIconURL(const Extension* extension, + int icon_size, + ExtensionIconSet::MatchType match, + bool grayscale, + bool* exists) const = 0; +}; + +} // namespace extensions + +#endif // EXTENSIONS_BROWSER_API_MANAGEMENT_MANAGEMENT_API_DELEGATER_H_ diff --git a/extensions/browser/api/runtime/runtime_apitest.cc b/extensions/browser/api/runtime/runtime_apitest.cc index 764e22e..7f01ef3 100644 --- a/extensions/browser/api/runtime/runtime_apitest.cc +++ b/extensions/browser/api/runtime/runtime_apitest.cc @@ -3,12 +3,12 @@ // found in the LICENSE file. #include "chrome/browser/apps/app_browsertest_util.h" -#include "chrome/browser/extensions/api/management/management_api.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_function_test_utils.h" #include "chrome/browser/extensions/test_extension_dir.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/browser/notification_service.h" +#include "extensions/browser/api/management/management_api.h" #include "extensions/browser/api/runtime/runtime_api.h" #include "extensions/browser/extension_registry.h" #include "extensions/test/result_catcher.h" diff --git a/extensions/browser/browser_context_keyed_service_factories.cc b/extensions/browser/browser_context_keyed_service_factories.cc index 0f97641..e6cd44d 100644 --- a/extensions/browser/browser_context_keyed_service_factories.cc +++ b/extensions/browser/browser_context_keyed_service_factories.cc @@ -5,6 +5,7 @@ #include "extensions/browser/browser_context_keyed_service_factories.h" #include "extensions/browser/api/api_resource_manager.h" +#include "extensions/browser/api/management/management_api.h" #include "extensions/browser/api/runtime/runtime_api.h" #include "extensions/browser/api/serial/serial_connection.h" #include "extensions/browser/api/socket/socket.h" @@ -31,6 +32,7 @@ void EnsureBrowserContextKeyedServiceFactoriesBuilt() { core_api::TCPServerSocketEventDispatcher::GetFactoryInstance(); core_api::TCPSocketEventDispatcher::GetFactoryInstance(); core_api::UDPSocketEventDispatcher::GetFactoryInstance(); + extensions::ManagementAPI::GetFactoryInstance(); ExtensionPrefsFactory::GetInstance(); ProcessManagerFactory::GetInstance(); RendererStartupHelperFactory::GetInstance(); |