| Index: chrome/tools/build/generate_policy_source.py
|
| diff --git a/chrome/tools/build/generate_policy_source.py b/chrome/tools/build/generate_policy_source.py
|
| index 1051092ece054d10ab6d4524bdecdef07fd38091..6b2ee462b4a52be39e764d0a038c7cf856259728 100644
|
| --- a/chrome/tools/build/generate_policy_source.py
|
| +++ b/chrome/tools/build/generate_policy_source.py
|
| @@ -29,6 +29,12 @@ def main():
|
| parser.add_option("--pth", "--policy-type-header", dest="type_path",
|
| help="generate header file for policy type enumeration",
|
| metavar="FILE");
|
| + parser.add_option("--ppb", "--policy-protobuf", dest="proto_path",
|
| + help="generate cloud policy protobuf file",
|
| + metavar="FILE");
|
| + parser.add_option("--ppd", "--protobuf-decoder", dest="decoder_path",
|
| + help="generate C++ code decoding the policy protobuf",
|
| + metavar="FILE");
|
|
|
| (opts, args) = parser.parse_args();
|
|
|
| @@ -38,27 +44,45 @@ def main():
|
| sys.exit(2)
|
| template_file_contents = _LoadJSONFile(args[1]);
|
| if opts.header_path is not None:
|
| - _WritePolicyConstantHeader(template_file_contents,
|
| - args,
|
| - opts);
|
| + _WritePolicyConstantHeader(template_file_contents, args, opts);
|
| if opts.source_path is not None:
|
| - _WritePolicyConstantSource(template_file_contents,
|
| - args,
|
| - opts);
|
| + _WritePolicyConstantSource(template_file_contents, args, opts);
|
| if opts.type_path is not None:
|
| - _WritePolicyTypeEnumerationHeader(template_file_contents,
|
| - args,
|
| - opts);
|
| + _WritePolicyTypeEnumerationHeader(template_file_contents, args, opts);
|
| + if opts.proto_path is not None:
|
| + _WriteProtobuf(template_file_contents, args, opts.proto_path)
|
| + if opts.decoder_path is not None:
|
| + _WriteProtobufParser(template_file_contents, args, opts.decoder_path)
|
|
|
|
|
| +#------------------ shared helpers ---------------------------------#
|
| def _OutputGeneratedWarningForC(f, template_file_path):
|
| f.write('//\n'
|
| '// DO NOT MODIFY THIS FILE DIRECTLY!\n'
|
| '// IT IS GENERATED BY generate_policy_source.py\n'
|
| - '// FROM ' + template_file_path + ' \n'
|
| + '// FROM ' + template_file_path + '\n'
|
| '//\n\n')
|
|
|
|
|
| +def _GetPolicyNameList(template_file_contents):
|
| + policy_names = [];
|
| + for policy in template_file_contents['policy_definitions']:
|
| + if policy['type'] == 'group':
|
| + for sub_policy in policy['policies']:
|
| + policy_names.append(sub_policy['name'])
|
| + else:
|
| + policy_names.append(policy['name'])
|
| + policy_names.sort()
|
| + return policy_names
|
| +
|
| +
|
| +def _LoadJSONFile(json_file):
|
| + with open(json_file, "r") as f:
|
| + text = f.read()
|
| + return eval(text)
|
| +
|
| +
|
| +#------------------ policy constants header ------------------------#
|
| def _WritePolicyConstantHeader(template_file_contents, args, opts):
|
| platform = args[0];
|
| with open(opts.header_path, "w") as f:
|
| @@ -80,6 +104,7 @@ def _WritePolicyConstantHeader(template_file_contents, args, opts):
|
| '#endif // CHROME_COMMON_POLICY_CONSTANTS_H_\n')
|
|
|
|
|
| +#------------------ policy constants source ------------------------#
|
| def _WritePolicyConstantSource(template_file_contents, args, opts):
|
| platform = args[0];
|
| with open(opts.source_path, "w") as f:
|
| @@ -103,6 +128,7 @@ def _WritePolicyConstantSource(template_file_contents, args, opts):
|
| '} // namespace policy\n')
|
|
|
|
|
| +#------------------ policy type enumeration header -----------------#
|
| def _WritePolicyTypeEnumerationHeader(template_file_contents, args, opts):
|
| with open(opts.type_path, "w") as f:
|
| _OutputGeneratedWarningForC(f, args[1])
|
| @@ -120,23 +146,183 @@ def _WritePolicyTypeEnumerationHeader(template_file_contents, args, opts):
|
| '#endif // CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_TYPE_H_\n')
|
|
|
|
|
| -def _GetPolicyNameList(template_file_contents):
|
| - policy_names = [];
|
| - for policy in template_file_contents['policy_definitions']:
|
| - if policy['type'] == 'group':
|
| - for sub_policy in policy['policies']:
|
| - policy_names.append(sub_policy['name'])
|
| - else:
|
| - policy_names.append(policy['name'])
|
| - policy_names.sort()
|
| - return policy_names
|
| +#------------------ policy protobuf --------------------------------#
|
| +PROTO_HEAD = '''
|
| +syntax = "proto2";
|
|
|
| +option optimize_for = LITE_RUNTIME;
|
|
|
| -def _LoadJSONFile(json_file):
|
| - with open(json_file, "r") as f:
|
| - text = f.read()
|
| - return eval(text)
|
| +package enterprise_management;
|
| +
|
| +message StringList {
|
| + repeated string entries = 1;
|
| +}
|
| +
|
| +message PolicyOptions {
|
| + enum PolicyMode {
|
| + // The given settings are applied regardless of user choice.
|
| + MANDATORY = 0;
|
| + // The user may choose to override the given settings.
|
| + RECOMMENDED = 1;
|
| + }
|
| + optional PolicyMode mode = 1 [default = MANDATORY];
|
| +}
|
| +
|
| +'''
|
| +
|
| +
|
| +PROTOBUF_TYPE = {
|
| + 'main': 'bool',
|
| + 'string': 'string',
|
| + 'string-enum': 'string',
|
| + 'int': 'int64',
|
| + 'int-enum': 'int64',
|
| + 'list': 'StringList',
|
| +}
|
| +
|
| +
|
| +# Field IDs [1..RESERVED_IDS] will not be used in the wrapping protobuf.
|
| +RESERVED_IDS = 2
|
| +
|
| +
|
| +def _WritePolicyProto(file, policy, fields):
|
| + file.write('message %sProto {\n' % policy['name'])
|
| + file.write(' optional PolicyOptions policy_options = 1;\n')
|
| + file.write(' optional %s %s = 2;\n' %
|
| + (PROTOBUF_TYPE[policy['type']], policy['name']))
|
| + file.write('}\n\n')
|
| + fields += [' optional %sProto %s = %s;\n' %
|
| + (policy['name'], policy['name'], policy['id'] + RESERVED_IDS)]
|
| +
|
| +
|
| +def _WriteProtobuf(template_file_contents, args, outfilepath):
|
| + with open(outfilepath, 'w') as f:
|
| + _OutputGeneratedWarningForC(f, args[1])
|
| + f.write(PROTO_HEAD)
|
| +
|
| + fields = []
|
| + f.write('// PBs for individual settings.\n\n')
|
| + for policy in template_file_contents['policy_definitions']:
|
| + if policy['type'] == 'group':
|
| + for sub_policy in policy['policies']:
|
| + _WritePolicyProto(f, sub_policy, fields)
|
| + else:
|
| + _WritePolicyProto(f, policy, fields)
|
| +
|
| + f.write('// --------------------------------------------------\n'
|
| + '// Big wrapper PB containing the above groups.\n\n'
|
| + 'message CloudPolicySettings {\n')
|
| + f.write(''.join(fields))
|
| + f.write('}\n\n')
|
| +
|
| +
|
| +#------------------ protobuf decoder -------------------------------#
|
| +CPP_HEAD = '''
|
| +#include <limits>
|
| +#include <map>
|
| +#include <string>
|
| +
|
| +#include "base/logging.h"
|
| +#include "base/values.h"
|
| +#include "chrome/browser/policy/configuration_policy_provider.h"
|
| +#include "chrome/browser/policy/proto/device_management_backend.pb.h"
|
| +#include "policy/configuration_policy_type.h"
|
| +
|
| +using google::protobuf::RepeatedPtrField;
|
| +
|
| +namespace policy {
|
| +
|
| +namespace em = enterprise_management;
|
| +
|
| +Value* DecodeIntegerValue(google::protobuf::int64 value) {
|
| + if (value < std::numeric_limits<int>::min() ||
|
| + value > std::numeric_limits<int>::max()) {
|
| + LOG(WARNING) << "Integer value " << value
|
| + << " out of numeric limits, ignoring.";
|
| + return NULL;
|
| + }
|
| +
|
| + return Value::CreateIntegerValue(static_cast<int>(value));
|
| +}
|
| +
|
| +ListValue* DecodeStringList(const em::StringList& string_list) {
|
| + ListValue* list_value = new ListValue;
|
| + RepeatedPtrField<std::string>::const_iterator entry;
|
| + for (entry = string_list.entries().begin();
|
| + entry != string_list.entries().end(); ++entry) {
|
| + list_value->Append(Value::CreateStringValue(*entry));
|
| + }
|
| + return list_value;
|
| +}
|
| +
|
| +void DecodePolicy(const em::CloudPolicySettings& policy,
|
| + ConfigurationPolicyProvider::PolicyMapType* mandatory,
|
| + ConfigurationPolicyProvider::PolicyMapType* recommended) {
|
| + DCHECK(mandatory);
|
| + DCHECK(recommended);
|
| +'''
|
| +
|
| +
|
| +CPP_FOOT = '''}
|
| +
|
| +} // namespace policy
|
| +'''
|
| +
|
| +
|
| +def _CreateValue(type):
|
| + if type == 'main':
|
| + return "Value::CreateBooleanValue"
|
| + elif type in ('int', 'int-enum'):
|
| + return "DecodeIntegerValue"
|
| + elif type in ('string', 'string-enum'):
|
| + return "Value::CreateStringValue"
|
| + elif type == 'list':
|
| + return "DecodeStringList"
|
| + else:
|
| + raise NotImplementedError()
|
| +
|
| +
|
| +def _WritePolicyCode(file, policy):
|
| + membername = policy['name'].lower()
|
| + proto_type = "%sProto" % policy['name']
|
| + proto_name = "%s_proto" % membername
|
| + file.write(' if (policy.has_%s()) {\n' % membername)
|
| + file.write(' const em::%s& %s = policy.%s();\n' %
|
| + (proto_type, proto_name, membername))
|
| + file.write(' if (%s.has_%s()) {\n' % (proto_name, membername))
|
| + file.write(' Value* value = %s(%s.%s());\n' %
|
| + (_CreateValue(policy['type']), proto_name, membername))
|
| + file.write(' ConfigurationPolicyProvider::PolicyMapType* destination ='
|
| + ' mandatory;\n'
|
| + ' if (%s.has_policy_options()) {\n'
|
| + ' switch(%s.policy_options().mode()) {\n' %
|
| + (proto_name, proto_name))
|
| + file.write(' case em::PolicyOptions::RECOMMENDED:\n'
|
| + ' destination = recommended;\n'
|
| + ' break;\n'
|
| + ' case em::PolicyOptions::MANDATORY:\n'
|
| + ' break;\n'
|
| + ' }\n'
|
| + ' }\n'
|
| + ' destination->insert(std::make_pair(kPolicy%s, value));\n' %
|
| + policy['name'])
|
| + file.write(' }\n'
|
| + ' }\n')
|
| +
|
| +
|
| +def _WriteProtobufParser(template_file_contents, args, outfilepath):
|
| + with open(outfilepath, 'w') as f:
|
| + _OutputGeneratedWarningForC(f, args[1])
|
| + f.write(CPP_HEAD)
|
| + for policy in template_file_contents['policy_definitions']:
|
| + if policy['type'] == 'group':
|
| + for sub_policy in policy['policies']:
|
| + _WritePolicyCode(f, sub_policy)
|
| + else:
|
| + _WritePolicyCode(f, policy)
|
| + f.write(CPP_FOOT)
|
|
|
|
|
| +#------------------ main() -----------------------------------------#
|
| if __name__ == '__main__':
|
| main();
|
|
|