| Index: chrome/browser/extensions/extension_management_api.cc
|
| diff --git a/chrome/browser/extensions/extension_management_api.cc b/chrome/browser/extensions/extension_management_api.cc
|
| index 53906fac6d8411d88a67a916c219c471b9aa64be..361a4ae28a2d32183666544f3dfa7eac8a466117 100644
|
| --- a/chrome/browser/extensions/extension_management_api.cc
|
| +++ b/chrome/browser/extensions/extension_management_api.cc
|
| @@ -7,14 +7,15 @@
|
| #include <map>
|
| #include <string>
|
|
|
| -#include "base/bind.h"
|
| #include "base/basictypes.h"
|
| +#include "base/bind.h"
|
| #include "base/json/json_writer.h"
|
| #include "base/metrics/histogram.h"
|
| #include "base/string_number_conversions.h"
|
| #include "base/string_util.h"
|
| #include "chrome/browser/extensions/extension_event_names.h"
|
| #include "chrome/browser/extensions/extension_event_router.h"
|
| +#include "chrome/browser/extensions/extension_management_api_constants.h"
|
| #include "chrome/browser/extensions/extension_service.h"
|
| #include "chrome/browser/extensions/extension_updater.h"
|
| #include "chrome/browser/profiles/profile.h"
|
| @@ -32,61 +33,45 @@
|
|
|
| using base::IntToString;
|
| using content::BrowserThread;
|
| -namespace events = extension_event_names;
|
|
|
| -namespace {
|
| +namespace events = extension_event_names;
|
| +namespace keys = extension_management_api_constants;
|
|
|
| -const char kAppLaunchUrlKey[] = "appLaunchUrl";
|
| -const char kDescriptionKey[] = "description";
|
| -const char kEnabledKey[] = "enabled";
|
| -const char kHomepageUrlKey[] = "homepageUrl";
|
| -const char kIconsKey[] = "icons";
|
| -const char kIdKey[] = "id";
|
| -const char kIsAppKey[] = "isApp";
|
| -const char kNameKey[] = "name";
|
| -const char kOfflineEnabledKey[] = "offlineEnabled";
|
| -const char kOptionsUrlKey[] = "optionsUrl";
|
| -const char kPermissionsKey[] = "permissions";
|
| -const char kMayDisableKey[] = "mayDisable";
|
| -const char kSizeKey[] = "size";
|
| -const char kUpdateUrlKey[] = "updateUrl";
|
| -const char kUrlKey[] = "url";
|
| -const char kVersionKey[] = "version";
|
| -
|
| -const char kExtensionCreateError[] =
|
| - "Failed to create extension from manifest.";
|
| -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 kUserCantDisableError[] = "Extension * can not be disabled by user";
|
| +ExtensionService* ExtensionManagementFunction::service() {
|
| + return profile()->GetExtensionService();
|
| }
|
|
|
| -ExtensionService* ExtensionManagementFunction::service() {
|
| +ExtensionService* AsyncExtensionManagementFunction::service() {
|
| return profile()->GetExtensionService();
|
| }
|
|
|
| static DictionaryValue* CreateExtensionInfo(const Extension& extension,
|
| - bool enabled) {
|
| + bool enabled,
|
| + bool permissions_escalated) {
|
| DictionaryValue* info = new DictionaryValue();
|
| - info->SetString(kIdKey, extension.id());
|
| - info->SetBoolean(kIsAppKey, extension.is_app());
|
| - info->SetString(kNameKey, extension.name());
|
| - info->SetBoolean(kEnabledKey, enabled);
|
| - info->SetBoolean(kMayDisableKey,
|
| + info->SetString(keys::kIdKey, extension.id());
|
| + info->SetBoolean(keys::kIsAppKey, extension.is_app());
|
| + info->SetString(keys::kNameKey, extension.name());
|
| + info->SetBoolean(keys::kEnabledKey, enabled);
|
| + if (!enabled) {
|
| + const char* reason = permissions_escalated ?
|
| + keys::kDisabledReasonPermissionsIncrease : keys::kDisabledReasonUnknown;
|
| + info->SetString(keys::kDisabledReasonKey, reason);
|
| + }
|
| + info->SetBoolean(keys::kMayDisableKey,
|
| Extension::UserMayDisable(extension.location()));
|
| - info->SetBoolean(kOfflineEnabledKey, extension.offline_enabled());
|
| - info->SetString(kVersionKey, extension.VersionString());
|
| - info->SetString(kDescriptionKey, extension.description());
|
| - info->SetString(kOptionsUrlKey,
|
| + info->SetBoolean(keys::kOfflineEnabledKey, extension.offline_enabled());
|
| + info->SetString(keys::kVersionKey, extension.VersionString());
|
| + info->SetString(keys::kDescriptionKey, extension.description());
|
| + info->SetString(keys::kOptionsUrlKey,
|
| extension.options_url().possibly_invalid_spec());
|
| - info->SetString(kHomepageUrlKey,
|
| + info->SetString(keys::kHomepageUrlKey,
|
| extension.GetHomepageURL().possibly_invalid_spec());
|
| - if (!extension.update_url().is_empty()) {
|
| - info->SetString(kUpdateUrlKey,
|
| + if (!extension.update_url().is_empty())
|
| + info->SetString(keys::kUpdateUrlKey,
|
| extension.update_url().possibly_invalid_spec());
|
| - }
|
| if (extension.is_app())
|
| - info->SetString(kAppLaunchUrlKey,
|
| + info->SetString(keys::kAppLaunchUrlKey,
|
| extension.GetFullLaunchURL().possibly_invalid_spec());
|
|
|
| const ExtensionIconSet::IconMap& icons = extension.icons().map();
|
| @@ -98,8 +83,8 @@ static DictionaryValue* CreateExtensionInfo(const Extension& extension,
|
| Extension::Icons size = static_cast<Extension::Icons>(icon_iter->first);
|
| GURL url = ExtensionIconSource::GetIconURL(
|
| &extension, size, ExtensionIconSet::MATCH_EXACTLY, false, NULL);
|
| - icon_info->SetInteger(kSizeKey, icon_iter->first);
|
| - icon_info->SetString(kUrlKey, url.spec());
|
| + icon_info->SetInteger(keys::kSizeKey, icon_iter->first);
|
| + icon_info->SetString(keys::kUrlKey, url.spec());
|
| icon_list->Append(icon_info);
|
| }
|
| info->Set("icons", icon_list);
|
| @@ -139,7 +124,8 @@ static DictionaryValue* CreateExtensionInfo(const Extension& extension,
|
|
|
| static void AddExtensionInfo(ListValue* list,
|
| const ExtensionList& extensions,
|
| - bool enabled) {
|
| + bool enabled,
|
| + ExtensionPrefs* prefs) {
|
| for (ExtensionList::const_iterator i = extensions.begin();
|
| i != extensions.end(); ++i) {
|
| const Extension& extension = **i;
|
| @@ -147,7 +133,9 @@ static void AddExtensionInfo(ListValue* list,
|
| if (extension.location() == Extension::COMPONENT)
|
| continue; // Skip built-in extensions.
|
|
|
| - list->Append(CreateExtensionInfo(extension, enabled));
|
| + bool escalated =
|
| + prefs->DidExtensionEscalatePermissions(extension.id());
|
| + list->Append(CreateExtensionInfo(extension, enabled, escalated));
|
| }
|
| }
|
|
|
| @@ -155,8 +143,10 @@ bool GetAllExtensionsFunction::RunImpl() {
|
| ListValue* result = new ListValue();
|
| result_.reset(result);
|
|
|
| - AddExtensionInfo(result, *service()->extensions(), true);
|
| - AddExtensionInfo(result, *service()->disabled_extensions(), false);
|
| + ExtensionPrefs* prefs = service()->extension_prefs();
|
| + AddExtensionInfo(result, *service()->extensions(), true, prefs);
|
| + AddExtensionInfo(
|
| + result, *service()->disabled_extensions(), false, prefs);
|
|
|
| return true;
|
| }
|
| @@ -166,12 +156,14 @@ bool GetExtensionByIdFunction::RunImpl() {
|
| EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &extension_id));
|
| const Extension* extension = service()->GetExtensionById(extension_id, true);
|
| if (!extension) {
|
| - error_ = ExtensionErrorUtils::FormatErrorMessage(kNoExtensionError,
|
| + error_ = ExtensionErrorUtils::FormatErrorMessage(keys::kNoExtensionError,
|
| extension_id);
|
| return false;
|
| }
|
| bool enabled = service()->IsExtensionEnabled(extension_id);
|
| - DictionaryValue* result = CreateExtensionInfo(*extension, enabled);
|
| + ExtensionPrefs* prefs = service()->extension_prefs();
|
| + bool escalated = prefs->DidExtensionEscalatePermissions(extension_id);
|
| + DictionaryValue* result = CreateExtensionInfo(*extension, enabled, escalated);
|
| result_.reset(result);
|
|
|
| return true;
|
| @@ -183,7 +175,7 @@ bool GetPermissionWarningsByIdFunction::RunImpl() {
|
|
|
| const Extension* extension = service()->GetExtensionById(ext_id, true);
|
| if (!extension) {
|
| - error_ = ExtensionErrorUtils::FormatErrorMessage(kNoExtensionError,
|
| + error_ = ExtensionErrorUtils::FormatErrorMessage(keys::kNoExtensionError,
|
| ext_id);
|
| return false;
|
| }
|
| @@ -242,7 +234,7 @@ class SafeManifestJSONParser : public UtilityProcessHost::Client {
|
| if (value->IsType(Value::TYPE_DICTIONARY))
|
| parsed_manifest_.reset(static_cast<DictionaryValue*>(value)->DeepCopy());
|
| else
|
| - error_ = kManifestParseError;
|
| + error_ = keys::kManifestParseError;
|
|
|
| utility_host_ = NULL; // has already deleted itself
|
| BrowserThread::PostTask(
|
| @@ -310,7 +302,7 @@ void GetPermissionWarningsByManifestFunction::OnParseSuccess(
|
| FilePath(), Extension::INVALID, *parsed_manifest,
|
| Extension::STRICT_ERROR_CHECKS, &error_);
|
| if (!extension.get()) {
|
| - OnParseFailure(kExtensionCreateError);
|
| + OnParseFailure(keys::kExtensionCreateError);
|
| return;
|
| }
|
|
|
| @@ -340,12 +332,12 @@ bool LaunchAppFunction::RunImpl() {
|
| EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &extension_id));
|
| const Extension* extension = service()->GetExtensionById(extension_id, true);
|
| if (!extension) {
|
| - error_ = ExtensionErrorUtils::FormatErrorMessage(kNoExtensionError,
|
| + error_ = ExtensionErrorUtils::FormatErrorMessage(keys::kNoExtensionError,
|
| extension_id);
|
| return false;
|
| }
|
| if (!extension->is_app()) {
|
| - error_ = ExtensionErrorUtils::FormatErrorMessage(kNotAnAppError,
|
| + error_ = ExtensionErrorUtils::FormatErrorMessage(keys::kNotAnAppError,
|
| extension_id);
|
| return false;
|
| }
|
| @@ -365,40 +357,74 @@ bool LaunchAppFunction::RunImpl() {
|
| return true;
|
| }
|
|
|
| +SetEnabledFunction::SetEnabledFunction() {}
|
| +
|
| +SetEnabledFunction::~SetEnabledFunction() {}
|
| +
|
| bool SetEnabledFunction::RunImpl() {
|
| - std::string extension_id;
|
| bool enable;
|
| - EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &extension_id));
|
| + EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &extension_id_));
|
| EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(1, &enable));
|
|
|
| - const Extension* extension = service()->GetExtensionById(extension_id, true);
|
| + const Extension* extension = service()->GetExtensionById(extension_id_, true);
|
| if (!extension) {
|
| error_ = ExtensionErrorUtils::FormatErrorMessage(
|
| - kNoExtensionError, extension_id);
|
| + keys::kNoExtensionError, extension_id_);
|
| return false;
|
| }
|
|
|
| if (!Extension::UserMayDisable(extension->location())) {
|
| error_ = ExtensionErrorUtils::FormatErrorMessage(
|
| - kUserCantDisableError, extension_id);
|
| + keys::kUserCantDisableError, extension_id_);
|
| return false;
|
| }
|
|
|
| - if (!service()->IsExtensionEnabled(extension_id) && enable)
|
| - service()->EnableExtension(extension_id);
|
| - else if (service()->IsExtensionEnabled(extension_id) && !enable)
|
| - service()->DisableExtension(extension_id);
|
| + bool currently_enabled = service()->IsExtensionEnabled(extension_id_);
|
| +
|
| + if (!currently_enabled && enable) {
|
| + ExtensionPrefs* prefs = service()->extension_prefs();
|
| + if (prefs->DidExtensionEscalatePermissions(extension_id_)) {
|
| + if (!user_gesture()) {
|
| + error_ = keys::kGestureNeededForEscalationError;
|
| + return false;
|
| + }
|
| + AddRef(); // Matched in InstallUIProceed/InstallUIAbort
|
| + install_ui_.reset(new ExtensionInstallUI(profile_));
|
| + install_ui_->ConfirmReEnable(this, extension);
|
| + return true;
|
| + }
|
| + service()->EnableExtension(extension_id_);
|
| + } else if (currently_enabled && !enable) {
|
| + service()->DisableExtension(extension_id_);
|
| + }
|
| +
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI,
|
| + FROM_HERE,
|
| + base::Bind(&SetEnabledFunction::SendResponse, this, true));
|
|
|
| return true;
|
| }
|
|
|
| +void SetEnabledFunction::InstallUIProceed() {
|
| + service()->EnableExtension(extension_id_);
|
| + SendResponse(true);
|
| + Release();
|
| +}
|
| +
|
| +void SetEnabledFunction::InstallUIAbort(bool user_initiated) {
|
| + error_ = keys::kUserDidNotReEnableError;
|
| + SendResponse(false);
|
| + Release();
|
| +}
|
| +
|
| bool UninstallFunction::RunImpl() {
|
| std::string extension_id;
|
| EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &extension_id));
|
|
|
| if (!service()->GetExtensionById(extension_id, true)) {
|
| error_ = ExtensionErrorUtils::FormatErrorMessage(
|
| - kNoExtensionError, extension_id);
|
| + keys::kNoExtensionError, extension_id);
|
| return false;
|
| }
|
|
|
| @@ -407,7 +433,7 @@ bool UninstallFunction::RunImpl() {
|
| if (!Extension::UserMayDisable(
|
| prefs->GetInstalledExtensionInfo(extension_id)->extension_location)) {
|
| error_ = ExtensionErrorUtils::FormatErrorMessage(
|
| - kUserCantDisableError, extension_id);
|
| + keys::kUserCantDisableError, extension_id);
|
| return false;
|
| }
|
|
|
| @@ -477,8 +503,10 @@ void ExtensionManagementEventRouter::Observe(
|
| }
|
| CHECK(extension);
|
| ExtensionService* service = profile->GetExtensionService();
|
| + ExtensionPrefs* prefs = service->extension_prefs();
|
| bool enabled = service->GetExtensionById(extension->id(), false) != NULL;
|
| - args.Append(CreateExtensionInfo(*extension, enabled));
|
| + bool escalated = prefs ->DidExtensionEscalatePermissions(extension->id());
|
| + args.Append(CreateExtensionInfo(*extension, enabled, escalated));
|
| }
|
|
|
| std::string args_json;
|
|
|