Use JSON schema compiler in chrome.management code

BUG=121174


Review URL: https://chromiumcodereview.appspot.com/10834160

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@151113 0039d316-1c4b-4281-b951-d872f2087c98
parent 6ee9f864
......@@ -6,13 +6,17 @@
#include <map>
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/bind.h"
#include "base/json/json_writer.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/extensions/api/management/management_api_constants.h"
#include "chrome/browser/extensions/event_names.h"
#include "chrome/browser/extensions/event_router.h"
......@@ -25,6 +29,7 @@
#include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_utility_messages.h"
#include "chrome/common/extensions/api/management.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/extension_error_utils.h"
......@@ -45,13 +50,18 @@ using content::BrowserThread;
using content::UtilityProcessHost;
using content::UtilityProcessHostClient;
using extensions::Extension;
using extensions::ExtensionSystem;
using extensions::PermissionMessages;
namespace events = extensions::event_names;
namespace keys = extension_management_api_constants;
namespace management = extensions::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,
......@@ -60,170 +70,186 @@ enum AutoConfirmForTest {
AutoConfirmForTest auto_confirm_for_test = DO_NOT_SKIP;
} // namespace
ExtensionService* ExtensionManagementFunction::service() {
return profile()->GetExtensionService();
}
std::vector<std::string> CreateWarningsList(const Extension* extension) {
std::vector<std::string> warnings_list;
PermissionMessages warnings = extension->GetPermissionMessages();
for (PermissionMessages::const_iterator iter = warnings.begin();
iter != warnings.end(); ++iter) {
warnings_list.push_back(UTF16ToUTF8(iter->message()));
}
ExtensionService* AsyncExtensionManagementFunction::service() {
return profile()->GetExtensionService();
return warnings_list;
}
static DictionaryValue* CreateExtensionInfo(const Extension& extension,
ExtensionService* service) {
DictionaryValue* info = new DictionaryValue();
bool enabled = service->IsExtensionEnabled(extension.id());
extension.GetBasicInfo(enabled, info);
const extensions::ManagementPolicy* policy = extensions::ExtensionSystem::Get(
service->profile())->management_policy();
info->SetBoolean(keys::kMayDisableKey,
policy->UserMayModifySettings(&extension, NULL));
info->SetBoolean(keys::kIsAppKey, extension.is_app());
if (!enabled) {
scoped_ptr<management::ExtensionInfo> CreateExtensionInfo(
const Extension& extension,
ExtensionSystem* system) {
scoped_ptr<management::ExtensionInfo> info(new management::ExtensionInfo());
ExtensionService* service = system->extension_service();
info->id = extension.id();
info->name = extension.name();
info->enabled = service->IsExtensionEnabled(info->id);
info->offline_enabled = extension.offline_enabled();
info->version = extension.VersionString();
info->description = extension.description();
info->options_url = extension.options_url().spec();
info->homepage_url.reset(new std::string(
extension.GetHomepageURL().spec()));
info->may_disable = system->management_policy()->
UserMayModifySettings(&extension, NULL);
info->is_app = extension.is_app();
if (info->enabled) {
info->disabled_reason = management::ExtensionInfo::DISABLED_REASON_NONE;
} else {
extensions::ExtensionPrefs* prefs = service->extension_prefs();
bool permissions_escalated =
prefs->DidExtensionEscalatePermissions(extension.id());
const char* reason = permissions_escalated ?
keys::kDisabledReasonPermissionsIncrease : keys::kDisabledReasonUnknown;
info->SetString(keys::kDisabledReasonKey, reason);
if (prefs->DidExtensionEscalatePermissions(extension.id())) {
info->disabled_reason =
management::ExtensionInfo::DISABLED_REASON_PERMISSIONS_INCREASE;
} else {
info->disabled_reason =
management::ExtensionInfo::DISABLED_REASON_UNKNOWN;
}
}
if (!extension.update_url().is_empty())
info->SetString(keys::kUpdateUrlKey,
extension.update_url().possibly_invalid_spec());
if (extension.is_app())
info->SetString(keys::kAppLaunchUrlKey,
extension.GetFullLaunchURL().possibly_invalid_spec());
if (!extension.update_url().is_empty()) {
info->update_url.reset(new std::string(
extension.update_url().spec()));
}
if (extension.is_app()) {
info->app_launch_url.reset(new std::string(
extension.GetFullLaunchURL().spec()));
}
const ExtensionIconSet::IconMap& icons = extension.icons().map();
if (!icons.empty()) {
ListValue* icon_list = new ListValue();
info->icons.reset(new IconInfoList());
std::map<ExtensionIconSet::Icons, std::string>::const_iterator icon_iter;
for (icon_iter = icons.begin(); icon_iter != icons.end(); ++icon_iter) {
DictionaryValue* icon_info = new DictionaryValue();
ExtensionIconSet::Icons size = icon_iter->first;
management::IconInfo* icon_info = new management::IconInfo();
icon_info->size = icon_iter->first;
GURL url = ExtensionIconSource::GetIconURL(
&extension, size, ExtensionIconSet::MATCH_EXACTLY, false, NULL);
icon_info->SetInteger(keys::kSizeKey, icon_iter->first);
icon_info->SetString(keys::kUrlKey, url.spec());
icon_list->Append(icon_info);
&extension, icon_info->size, ExtensionIconSet::MATCH_EXACTLY, false,
NULL);
icon_info->url = url.spec();
info->icons->push_back(make_linked_ptr<management::IconInfo>(icon_info));
}
info->Set(keys::kIconsKey, icon_list);
}
const std::set<std::string> perms =
extension.GetActivePermissions()->GetAPIsAsStrings();
ListValue* permission_list = new ListValue();
if (!perms.empty()) {
std::set<std::string>::const_iterator perms_iter;
for (perms_iter = perms.begin(); perms_iter != perms.end(); ++perms_iter) {
StringValue* permission_name = new StringValue(*perms_iter);
permission_list->Append(permission_name);
}
for (perms_iter = perms.begin(); perms_iter != perms.end(); ++perms_iter)
info->permissions.push_back(*perms_iter);
}
info->Set(keys::kPermissionsKey, permission_list);
ListValue* host_permission_list = new ListValue();
if (!extension.is_hosted_app()) {
// Skip host permissions for hosted apps.
const URLPatternSet host_perms =
extension.GetActivePermissions()->explicit_hosts();
if (!host_perms.is_empty()) {
URLPatternSet::const_iterator host_perms_iter;
for (host_perms_iter = host_perms.begin();
host_perms_iter != host_perms.end();
++host_perms_iter) {
StringValue* name = new StringValue(host_perms_iter->GetAsString());
host_permission_list->Append(name);
for (URLPatternSet::const_iterator iter = host_perms.begin();
iter != host_perms.end(); ++iter) {
info->host_permissions.push_back(iter->GetAsString());
}
}
}
info->Set(keys::kHostPermissionsKey, host_permission_list);
std::string install_type = keys::kInstallTypeOther;
switch (extension.location()) {
case Extension::INTERNAL:
install_type = keys::kInstallTypeNormal;
info->install_type = management::ExtensionInfo::INSTALL_TYPE_NORMAL;
break;
case Extension::LOAD:
install_type = keys::kInstallTypeDevelopment;
info->install_type = management::ExtensionInfo::INSTALL_TYPE_DEVELOPMENT;
break;
case Extension::EXTERNAL_PREF:
case Extension::EXTERNAL_REGISTRY:
case Extension::EXTERNAL_PREF_DOWNLOAD:
install_type = keys::kInstallTypeSideload;
info->install_type = management::ExtensionInfo::INSTALL_TYPE_SIDELOAD;
break;
case Extension::EXTERNAL_POLICY_DOWNLOAD:
install_type = keys::kInstallTypeAdmin;
info->install_type = management::ExtensionInfo::INSTALL_TYPE_ADMIN;
break;
default:
install_type = keys::kInstallTypeOther;
info->install_type = management::ExtensionInfo::INSTALL_TYPE_OTHER;
break;
}
info->SetString(keys::kInstallTypeKey, install_type);
return info;
return info.Pass();
}
static void AddExtensionInfo(ListValue* list,
const ExtensionSet& extensions,
ExtensionService* service) {
for (ExtensionSet::const_iterator i = extensions.begin();
i != extensions.end(); ++i) {
const Extension& extension = **i;
void AddExtensionInfo(const ExtensionSet& extensions,
ExtensionSystem* system,
ExtensionInfoList* extension_list) {
for (ExtensionSet::const_iterator iter = extensions.begin();
iter != extensions.end(); ++iter) {
const Extension& extension = **iter;
if (extension.location() == Extension::COMPONENT)
continue; // Skip built-in extensions.
list->Append(CreateExtensionInfo(extension, service));
extension_list->push_back(make_linked_ptr<management::ExtensionInfo>(
CreateExtensionInfo(extension, system).release()));
}
}
} // namespace
ExtensionService* ExtensionManagementFunction::service() {
return profile()->GetExtensionService();
}
ExtensionService* AsyncExtensionManagementFunction::service() {
return profile()->GetExtensionService();
}
bool GetAllExtensionsFunction::RunImpl() {
ListValue* result = new ListValue();
SetResult(result);
ExtensionInfoList extensions;
ExtensionSystem* system = ExtensionSystem::Get(profile());
AddExtensionInfo(result, *service()->extensions(), service());
AddExtensionInfo(result, *service()->disabled_extensions(), service());
AddExtensionInfo(*service()->extensions(), system, &extensions);
AddExtensionInfo(*service()->disabled_extensions(), system, &extensions);
results_ = management::GetAll::Results::Create(extensions);
return true;
}
bool GetExtensionByIdFunction::RunImpl() {
std::string extension_id;
EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &extension_id));
const Extension* extension = service()->GetExtensionById(extension_id, true);
scoped_ptr<management::Get::Params> params(
management::Get::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
const Extension* extension = service()->GetExtensionById(params->id, true);
if (!extension) {
error_ = ExtensionErrorUtils::FormatErrorMessage(keys::kNoExtensionError,
extension_id);
params->id);
return false;
}
DictionaryValue* result = CreateExtensionInfo(*extension, service());
SetResult(result);
scoped_ptr<management::ExtensionInfo> info = CreateExtensionInfo(
*extension, ExtensionSystem::Get(profile()));
results_ = management::Get::Results::Create(*info);
return true;
}
bool GetPermissionWarningsByIdFunction::RunImpl() {
std::string ext_id;
EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &ext_id));
scoped_ptr<management::GetPermissionWarningsById::Params> params(
management::GetPermissionWarningsById::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
const Extension* extension = service()->GetExtensionById(ext_id, true);
const Extension* extension = service()->GetExtensionById(params->id, true);
if (!extension) {
error_ = ExtensionErrorUtils::FormatErrorMessage(keys::kNoExtensionError,
ext_id);
params->id);
return false;
}
PermissionMessages warnings = extension->GetPermissionMessages();
ListValue* result = new ListValue();
for (PermissionMessages::const_iterator i = warnings.begin();
i < warnings.end(); ++i)
result->Append(Value::CreateStringValue(i->message()));
SetResult(result);
std::vector<std::string> warnings = CreateWarningsList(extension);
results_ = management::GetPermissionWarningsById::Results::Create(warnings);
return true;
}
......@@ -317,11 +343,12 @@ class SafeManifestJSONParser : public UtilityProcessHostClient {
} // namespace
bool GetPermissionWarningsByManifestFunction::RunImpl() {
std::string manifest_str;
EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &manifest_str));
scoped_ptr<management::GetPermissionWarningsByManifest::Params> params(
management::GetPermissionWarningsByManifest::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
scoped_refptr<SafeManifestJSONParser> parser =
new SafeManifestJSONParser(this, manifest_str);
new SafeManifestJSONParser(this, params->manifest_str);
parser->Start();
// Matched with a Release() in OnParseSuccess/Failure().
......@@ -343,12 +370,9 @@ void GetPermissionWarningsByManifestFunction::OnParseSuccess(
return;
}
PermissionMessages warnings = extension->GetPermissionMessages();
ListValue* result = new ListValue();
for (PermissionMessages::const_iterator i = warnings.begin();
i < warnings.end(); ++i)
result->Append(Value::CreateStringValue(i->message()));
SetResult(result);
std::vector<std::string> warnings = CreateWarningsList(extension);
results_ = management::GetPermissionWarningsByManifest::Results::Create(
warnings);
SendResponse(true);
// Matched with AddRef() in RunImpl().
......@@ -365,17 +389,18 @@ void GetPermissionWarningsByManifestFunction::OnParseFailure(
}
bool LaunchAppFunction::RunImpl() {
std::string extension_id;
EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &extension_id));
const Extension* extension = service()->GetExtensionById(extension_id, true);
scoped_ptr<management::LaunchApp::Params> params(
management::LaunchApp::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
const Extension* extension = service()->GetExtensionById(params->id, true);
if (!extension) {
error_ = ExtensionErrorUtils::FormatErrorMessage(keys::kNoExtensionError,
extension_id);
params->id);
return false;
}
if (!extension->is_app()) {
error_ = ExtensionErrorUtils::FormatErrorMessage(keys::kNotAnAppError,
extension_id);
params->id);
return false;
}
......@@ -402,9 +427,11 @@ SetEnabledFunction::~SetEnabledFunction() {
}
bool SetEnabledFunction::RunImpl() {
bool enable;
EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &extension_id_));
EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(1, &enable));
scoped_ptr<management::SetEnabled::Params> params(
management::SetEnabled::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
extension_id_ = params->id;
const Extension* extension = service()->GetExtensionById(extension_id_, true);
if (!extension) {
......@@ -423,7 +450,7 @@ bool SetEnabledFunction::RunImpl() {
bool currently_enabled = service()->IsExtensionEnabled(extension_id_);
if (!currently_enabled && enable) {
if (!currently_enabled && params->enabled) {
extensions::ExtensionPrefs* prefs = service()->extension_prefs();
if (prefs->DidExtensionEscalatePermissions(extension_id_)) {
if (!user_gesture()) {
......@@ -437,7 +464,7 @@ bool SetEnabledFunction::RunImpl() {
return true;
}
service()->EnableExtension(extension_id_);
} else if (currently_enabled && !enable) {
} else if (currently_enabled && !params->enabled) {
service()->DisableExtension(extension_id_, Extension::DISABLE_USER_ACTION);
}
......@@ -468,19 +495,15 @@ UninstallFunction::~UninstallFunction() {
}
bool UninstallFunction::RunImpl() {
bool show_confirm_dialog = false;
EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &extension_id_));
scoped_ptr<management::Uninstall::Params> params(
management::Uninstall::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
if (HasOptionalArgument(1)) {
DictionaryValue* options = NULL;
EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &options));
extension_id_ = params->id;
if (options->HasKey(keys::kShowConfirmDialogKey)) {
EXTENSION_FUNCTION_VALIDATE(options->GetBoolean(
keys::kShowConfirmDialogKey, &show_confirm_dialog));
}
}
bool show_confirm_dialog = false;
if (params->options.get() && params->options->show_confirm_dialog.get())
show_confirm_dialog = *params->options->show_confirm_dialog;
const Extension* extension = service()->GetExtensionById(extension_id_, true);
if (!extension) {
......@@ -595,7 +618,7 @@ void ExtensionManagementEventRouter::Observe(
scoped_ptr<ListValue> args(new ListValue());
if (event_name == events::kOnExtensionUninstalled) {
args->Append(Value::CreateStringValue(
content::Details<const extensions::Extension>(details).ptr()->id()));
content::Details<const Extension>(details).ptr()->id()));
} else {
const Extension* extension = NULL;
if (event_name == events::kOnExtensionDisabled) {
......@@ -605,8 +628,9 @@ void ExtensionManagementEventRouter::Observe(
extension = content::Details<const Extension>(details).ptr();
}
CHECK(extension);
ExtensionService* service = profile->GetExtensionService();
args->Append(CreateExtensionInfo(*extension, service));
scoped_ptr<management::ExtensionInfo> info = CreateExtensionInfo(
*extension, ExtensionSystem::Get(profile));
args->Append(info->ToValue().release());
}
profile->GetExtensionEventRouter()->DispatchEventToRenderers(
......
......@@ -28,6 +28,7 @@
'i18n.json',
'font_settings.json',
'history.json',
'management.json',
'page_capture.json',
'permissions.json',
'storage.json',
......
......@@ -100,8 +100,9 @@
}
},
"installType": {
"description": "How the extension was installed (\"admin\", \"development\", \"normal\", \"sideload\", \"other\"). \"admin\" means the extension was installed because of an administrative policy. \"development\" means the extension was loaded unpacked in developer mode. \"normal\" means the extension was installed normally via a .crx file. \"sideload\" means the extension was installed by other software on the machine. \"other\" means the extension was installed by other means.",
"type": "string"
"description": "How the extension was installed. One of<br><var>admin</var>: The extension was installed because of an administrative policy,<br><var>development</var>: The extension was loaded unpacked in developer mode,<br><var>normal</var>: The extension was installed normally via a .crx file,<br><var>sideload</var>: The extension was installed by other software on the machine,<br><var>other</var>: The extension was installed by other means.",
"type": "string",
"enum": ["admin", "development", "normal", "sideload", "other"]
}
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment