summaryrefslogtreecommitdiffstats
path: root/extensions/browser
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/browser')
-rw-r--r--extensions/browser/BUILD.gn9
-rw-r--r--extensions/browser/api/extensions_api_client.cc5
-rw-r--r--extensions/browser/api/extensions_api_client.h4
-rw-r--r--extensions/browser/api/management/management_api.cc899
-rw-r--r--extensions/browser/api/management/management_api.h292
-rw-r--r--extensions/browser/api/management/management_api_constants.cc47
-rw-r--r--extensions/browser/api/management/management_api_constants.h39
-rw-r--r--extensions/browser/api/management/management_api_delegate.h128
-rw-r--r--extensions/browser/api/runtime/runtime_apitest.cc2
-rw-r--r--extensions/browser/browser_context_keyed_service_factories.cc2
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();