Merge tools/grit from https://chromium.googlesource.com/external/grit-i18n.git at 740badd5e3e44434a9a47b5d16749daac1e8ea80

This commit was generated by merge_from_chromium.py.

Change-Id: I9eef239f60f69820f1390b0894595afd8c9764be
diff --git a/grit/format/policy_templates/writer_configuration.py b/grit/format/policy_templates/writer_configuration.py
index 00da0cc..88de6b5 100644
--- a/grit/format/policy_templates/writer_configuration.py
+++ b/grit/format/policy_templates/writer_configuration.py
@@ -33,6 +33,7 @@
       'win_recommended_category_path': ['chromium_recommended'],
       'admx_namespace': 'Chromium.Policies.Chromium',
       'admx_prefix': 'chromium',
+      'linux_policy_path': '/etc/chromium/policies/',
     }
   elif '_google_chrome' in defines:
     config = {
@@ -47,6 +48,7 @@
       'win_recommended_category_path': ['google', 'googlechrome_recommended'],
       'admx_namespace': 'Google.Policies.Chrome',
       'admx_prefix': 'chrome',
+      'linux_policy_path': '/etc/opt/chrome/policies/',
     }
   else:
     raise Exception('Unknown build')
diff --git a/grit/format/policy_templates/writers/adm_writer.py b/grit/format/policy_templates/writers/adm_writer.py
index 6a2f8b2..bffbeb5 100644
--- a/grit/format/policy_templates/writers/adm_writer.py
+++ b/grit/format/policy_templates/writers/adm_writer.py
@@ -153,9 +153,10 @@
     builder.AddLine()
 
   def WritePolicy(self, policy):
-    self._WritePolicy(policy,
-                      self.config['win_reg_mandatory_key_name'],
-                      self.policies)
+    if self.CanBeMandatory(policy):
+      self._WritePolicy(policy,
+                        self.config['win_reg_mandatory_key_name'],
+                        self.policies)
 
   def WriteRecommendedPolicy(self, policy):
     self._WritePolicy(policy,
diff --git a/grit/format/policy_templates/writers/adm_writer_unittest.py b/grit/format/policy_templates/writers/adm_writer_unittest.py
index 52e4aee..82374bb 100644
--- a/grit/format/policy_templates/writers/adm_writer_unittest.py
+++ b/grit/format/policy_templates/writers/adm_writer_unittest.py
@@ -147,6 +147,70 @@
 MainPolicy_Explain="Description of main."''')
     self.CompareOutputs(output, expected_output)
 
+  def testMainPolicyRecommendedOnly(self):
+    # Tests a policy group with a single policy of type 'main'.
+    grd = self.PrepareTest('''
+      {
+        'policy_definitions': [
+          {
+            'name': 'MainPolicy',
+            'type': 'main',
+            'supported_on': ['chrome.win:8-'],
+            'features': {
+              'can_be_recommended': True,
+              'can_be_mandatory': False
+            },
+            'caption': 'Caption of main.',
+            'desc': 'Description of main.',
+          },
+        ],
+        'placeholders': [],
+        'messages': {
+          'win_supported_winxpsp2': {
+            'text': 'At least Windows 3.12', 'desc': 'blah'
+          },
+          'doc_recommended': {
+            'text': 'Recommended', 'desc': 'bleh'
+          }
+        }
+      }''')
+    output = self.GetOutput(grd, 'fr', {'_google_chrome' : '1'}, 'adm', 'en')
+    expected_output = self.ConstructOutput(
+        ['MACHINE', 'USER'], '''
+  CATEGORY !!google
+    CATEGORY !!googlechrome
+      KEYNAME "Software\\Policies\\Google\\Chrome"
+
+    END CATEGORY
+  END CATEGORY
+
+  CATEGORY !!google
+    CATEGORY !!googlechrome_recommended
+      KEYNAME "Software\\Policies\\Google\\Chrome\\Recommended"
+
+      POLICY !!MainPolicy_Policy
+        #if version >= 4
+          SUPPORTED !!SUPPORTED_WINXPSP2
+        #endif
+        EXPLAIN !!MainPolicy_Explain
+        VALUENAME "MainPolicy"
+        VALUEON NUMERIC 1
+        VALUEOFF NUMERIC 0
+      END POLICY
+
+    END CATEGORY
+  END CATEGORY
+
+
+''', '''[Strings]
+SUPPORTED_WINXPSP2="At least Windows 3.12"
+google="Google"
+googlechrome="Google Chrome"
+googlechrome_recommended="Google Chrome - Recommended"
+MainPolicy_Policy="Caption of main."
+MainPolicy_Explain="Description of main."''')
+    self.CompareOutputs(output, expected_output)
+
   def testStringPolicy(self):
     # Tests a policy group with a single policy of type 'string'.
     grd = self.PrepareTest('''
diff --git a/grit/format/policy_templates/writers/admx_writer.py b/grit/format/policy_templates/writers/admx_writer.py
index bc33c19..0d4394b 100644
--- a/grit/format/policy_templates/writers/admx_writer.py
+++ b/grit/format/policy_templates/writers/admx_writer.py
@@ -295,10 +295,11 @@
       raise Exception('Unknown policy type %s.' % policy_type)
 
   def WritePolicy(self, policy):
-    self._WritePolicy(policy,
-                      policy['name'],
-                      self.config['win_reg_mandatory_key_name'],
-                      self._active_mandatory_policy_group_name)
+    if self.CanBeMandatory(policy):
+      self._WritePolicy(policy,
+                        policy['name'],
+                        self.config['win_reg_mandatory_key_name'],
+                        self._active_mandatory_policy_group_name)
 
   def WriteRecommendedPolicy(self, policy):
     self._WritePolicy(policy,
diff --git a/grit/format/policy_templates/writers/admx_writer_unittest.py b/grit/format/policy_templates/writers/admx_writer_unittest.py
index a573f26..cb3d39e 100644
--- a/grit/format/policy_templates/writers/admx_writer_unittest.py
+++ b/grit/format/policy_templates/writers/admx_writer_unittest.py
@@ -219,6 +219,46 @@
 
     self.AssertXMLEquals(output, expected_output)
 
+  def testRecommendedOnlyPolicy(self):
+    main_policy = {
+      'name': 'DummyMainPolicy',
+      'type': 'main',
+      'features': {
+        'can_be_recommended': True,
+        'can_be_mandatory': False,
+      }
+    }
+
+    policy_group = {
+      'name': 'PolicyGroup',
+      'policies': [main_policy],
+    }
+    self.writer.BeginTemplate()
+    self.writer.BeginRecommendedPolicyGroup(policy_group)
+
+    self.writer.WritePolicy(main_policy)
+    self.writer.WriteRecommendedPolicy(main_policy)
+
+    output = self.GetXMLOfChildren(self._GetPoliciesElement(self.writer._doc))
+    expected_output = (
+        '<policy class="TestClass" displayName="$(string.DummyMainPolicy)"'
+        ' explainText="$(string.DummyMainPolicy_Explain)"'
+        ' key="Software\\Policies\\Test\\Recommended"'
+        ' name="DummyMainPolicy_recommended"'
+        ' presentation="$(presentation.DummyMainPolicy)"'
+        ' valueName="DummyMainPolicy">\n'
+        '  <parentCategory ref="PolicyGroup_recommended"/>\n'
+        '  <supportedOn ref="SUPPORTED_TESTOS"/>\n'
+        '  <enabledValue>\n'
+        '    <decimal value="1"/>\n'
+        '  </enabledValue>\n'
+        '  <disabledValue>\n'
+        '    <decimal value="0"/>\n'
+        '  </disabledValue>\n'
+        '</policy>')
+
+    self.AssertXMLEquals(output, expected_output)
+
   def testStringPolicy(self):
     string_policy = {
       'name': 'SampleStringPolicy',
diff --git a/grit/format/policy_templates/writers/doc_writer.py b/grit/format/policy_templates/writers/doc_writer.py
index 62c762f..d8f108d 100644
--- a/grit/format/policy_templates/writers/doc_writer.py
+++ b/grit/format/policy_templates/writers/doc_writer.py
@@ -180,7 +180,10 @@
     win = self._AddStyledElement(parent, 'dd', ['.monospace', '.pre'])
     win_text = []
     cnt = 1
-    key_name = self.config['win_reg_mandatory_key_name']
+    if self.CanBeRecommended(policy) and not self.CanBeMandatory(policy):
+      key_name = self.config['win_reg_recommended_key_name']
+    else:
+      key_name = self.config['win_reg_mandatory_key_name']
     for item in example_value:
       win_text.append(
           '%s\\%s\\%d = "%s"' %
@@ -287,7 +290,10 @@
     '''
     self.AddElement(parent, 'dt', {}, 'Windows:')
     win = self._AddStyledElement(parent, 'dd', ['.monospace', '.pre'])
-    key_name = self.config['win_reg_mandatory_key_name']
+    if self.CanBeRecommended(policy) and not self.CanBeMandatory(policy):
+      key_name = self.config['win_reg_recommended_key_name']
+    else:
+      key_name = self.config['win_reg_mandatory_key_name']
     example = json.dumps(policy['example_value'])
     self.AddText(win, '%s\\%s = %s' % (key_name, policy['name'], example))
 
@@ -459,10 +465,14 @@
     if policy['type'] != 'external':
       # All types except 'external' can be set through platform policy.
       if self.IsPolicySupportedOnPlatform(policy, 'win'):
+        if self.CanBeRecommended(policy) and not self.CanBeMandatory(policy):
+          key_name = self.config['win_reg_recommended_key_name']
+        else:
+          key_name = self.config['win_reg_mandatory_key_name']
         self._AddPolicyAttribute(
             dl,
             'win_reg_loc',
-            self.config['win_reg_mandatory_key_name'] + '\\' + policy['name'],
+            key_name + '\\' + policy['name'],
             ['.monospace'])
       if (self.IsPolicySupportedOnPlatform(policy, 'linux') or
           self.IsPolicySupportedOnPlatform(policy, 'mac')):
diff --git a/grit/format/policy_templates/writers/doc_writer_unittest.py b/grit/format/policy_templates/writers/doc_writer_unittest.py
index 1508082..15d8b85 100644
--- a/grit/format/policy_templates/writers/doc_writer_unittest.py
+++ b/grit/format/policy_templates/writers/doc_writer_unittest.py
@@ -38,6 +38,7 @@
         'frame_name': 'Chrome Frame',
         'os_name': 'Chrome OS',
         'win_reg_mandatory_key_name': 'MockKey',
+        'win_reg_recommended_key_name': 'MockKeyRec',
       })
     self.writer.messages = {
       'doc_back_to_top': {'text': '_test_back_to_top'},
@@ -50,6 +51,7 @@
       'doc_example_value': {'text': '_test_example_value'},
       'doc_feature_dynamic_refresh': {'text': '_test_feature_dynamic_refresh'},
       'doc_feature_can_be_recommended': {'text': '_test_feature_recommended'},
+      'doc_feature_can_be_mandatory': {'text': '_test_feature_mandatory'},
       'doc_intro': {'text': '_test_intro'},
       'doc_mac_linux_pref_name': {'text': '_test_mac_linux_pref_name'},
       'doc_note': {'text': '_test_note'},
@@ -471,6 +473,62 @@
         '</dd>'
       '</dl></root>')
 
+  def testAddPolicyDetailsRecommendedOnly(self):
+    policy = {
+      'type': 'main',
+      'name': 'TestPolicyName',
+      'caption': 'TestPolicyCaption',
+      'desc': 'TestPolicyDesc',
+      'supported_on': [{
+        'product': 'chrome',
+        'platforms': ['win', 'mac', 'linux'],
+        'since_version': '8',
+        'until_version': '',
+      }, {
+        'product': 'chrome',
+        'platforms': ['android'],
+        'since_version': '30',
+        'until_version': '',
+      }, {
+        'product': 'chrome',
+        'platforms': ['ios'],
+        'since_version': '34',
+        'until_version': '',
+      }],
+      'features': {
+        'dynamic_refresh': False,
+        'can_be_mandatory': False,
+        'can_be_recommended': True
+      },
+      'example_value': False
+    }
+    self.writer.messages['doc_since_version'] = {'text': '...$6...'}
+    self.writer._AddPolicyDetails(self.doc_root, policy)
+    self.assertEquals(
+      self.doc_root.toxml(),
+      '<root><dl>'
+      '<dt style="style_dt;">_test_data_type</dt><dd>Boolean (REG_DWORD)</dd>'
+      '<dt style="style_dt;">_test_win_reg_loc</dt>'
+      '<dd style="style_.monospace;">MockKeyRec\TestPolicyName</dd>'
+      '<dt style="style_dt;">_test_mac_linux_pref_name</dt>'
+        '<dd style="style_.monospace;">TestPolicyName</dd>'
+      '<dt style="style_dt;">_test_supported_on</dt>'
+      '<dd>'
+        '<ul style="style_ul;">'
+          '<li>Chrome (Windows, Mac, Linux) ...8...</li>'
+          '<li>Chrome (Android) ...30...</li>'
+          '<li>Chrome (iOS) ...34...</li>'
+        '</ul>'
+      '</dd>'
+      '<dt style="style_dt;">_test_supported_features</dt>'
+        '<dd>_test_feature_mandatory: _test_not_supported,'
+        ' _test_feature_recommended: _test_supported,'
+        ' _test_feature_dynamic_refresh: _test_not_supported</dd>'
+      '<dt style="style_dt;">_test_description</dt><dd>TestPolicyDesc</dd>'
+      '<dt style="style_dt;">_test_example_value</dt>'
+        '<dd>0x00000000 (Windows), false (Linux), &lt;false /&gt; (Mac)</dd>'
+      '</dl></root>')
+
   def testAddPolicyNote(self):
     # TODO(jkummerow): The functionality tested by this test is currently not
     # used for anything and will probably soon be removed.
diff --git a/grit/format/policy_templates/writers/json_writer.py b/grit/format/policy_templates/writers/json_writer.py
index 673bbf7..f5af8c1 100644
--- a/grit/format/policy_templates/writers/json_writer.py
+++ b/grit/format/policy_templates/writers/json_writer.py
@@ -49,6 +49,13 @@
     if not self._first_written:
       self._out[-2] += ','
 
+    if not self.CanBeMandatory(policy) and self.CanBeRecommended(policy):
+      line = '  // Note: this policy is supported only in recommended mode.'
+      self._out.append(line)
+      line = '  // The JSON file should be placed in %srecommended.' % \
+             self.config['linux_policy_path']
+      self._out.append(line)
+
     line = '  // %s' % policy['caption']
     self._out.append(line)
     self._out.append(HEADER_DELIMETER)
diff --git a/grit/format/policy_templates/writers/json_writer_unittest.py b/grit/format/policy_templates/writers/json_writer_unittest.py
index 05ae255..b2ed1ef 100644
--- a/grit/format/policy_templates/writers/json_writer_unittest.py
+++ b/grit/format/policy_templates/writers/json_writer_unittest.py
@@ -86,6 +86,40 @@
         '}')
     self.CompareOutputs(output, expected_output)
 
+  def testRecommendedOnlyPolicy(self):
+    # Tests a policy group with a single policy of type 'main'.
+    grd = self.PrepareTest(
+        '{'
+        '  "policy_definitions": ['
+        '    {'
+        '      "name": "MainPolicy",'
+        '      "type": "main",'
+        '      "caption": "Example Main Policy",'
+        '      "desc": "Example Main Policy",'
+        '      "features": {'
+        '        "can_be_recommended": True,'
+        '        "can_be_mandatory": False'
+        '      },'
+        '      "supported_on": ["chrome.linux:8-"],'
+        '      "example_value": True'
+        '    },'
+        '  ],'
+        '  "placeholders": [],'
+        '  "messages": {},'
+        '}')
+    output = self.GetOutput(grd, 'fr', {'_google_chrome' : '1'}, 'json', 'en')
+    expected_output = (
+        TEMPLATE_HEADER +
+        '  // Note: this policy is supported only in recommended mode.\n' +
+        '  // The JSON file should be placed in' +
+        ' /etc/opt/chrome/policies/recommended.\n' +
+        '  // Example Main Policy\n' +
+        HEADER_DELIMETER +
+        '  // Example Main Policy\n\n'
+        '  //"MainPolicy": true\n\n'
+        '}')
+    self.CompareOutputs(output, expected_output)
+
   def testStringPolicy(self):
     # Tests a policy group with a single policy of type 'string'.
     grd = self.PrepareTest(
diff --git a/grit/format/policy_templates/writers/plist_writer.py b/grit/format/policy_templates/writers/plist_writer.py
index 6ca905b..6d929d6 100644
--- a/grit/format/policy_templates/writers/plist_writer.py
+++ b/grit/format/policy_templates/writers/plist_writer.py
@@ -67,7 +67,7 @@
     self.AddElement(parent, 'key', {}, key_string)
     self.AddElement(parent, 'string', {}, value_string)
 
-  def _AddTargets(self, parent):
+  def _AddTargets(self, parent, policy):
     '''Adds the following XML snippet to an XML element:
       <key>pfm_targets</key>
       <array>
@@ -78,7 +78,10 @@
         parent: The parent XML element where the snippet will be added.
     '''
     array = self._AddKeyValuePair(parent, 'pfm_targets', 'array')
-    self.AddElement(array, 'string', {}, 'user-managed')
+    if self.CanBeRecommended(policy):
+      self.AddElement(array, 'string', {}, 'user')
+    if self.CanBeMandatory(policy):
+      self.AddElement(array, 'string', {}, 'user-managed')
 
   def PreprocessPolicies(self, policy_list):
     return self.FlattenGroupsAndSortPolicies(policy_list)
@@ -97,7 +100,7 @@
     # Those files are generated by plist_strings_writer.
     self._AddStringKeyValuePair(dict, 'pfm_description', '')
     self._AddStringKeyValuePair(dict, 'pfm_title', '')
-    self._AddTargets(dict)
+    self._AddTargets(dict, policy)
     self._AddStringKeyValuePair(dict, 'pfm_type',
                                 self.TYPE_TO_INPUT[policy_type])
     if policy_type in ('int-enum', 'string-enum'):
diff --git a/grit/format/policy_templates/writers/plist_writer_unittest.py b/grit/format/policy_templates/writers/plist_writer_unittest.py
index f76db73..ddbdbfe 100644
--- a/grit/format/policy_templates/writers/plist_writer_unittest.py
+++ b/grit/format/policy_templates/writers/plist_writer_unittest.py
@@ -118,6 +118,108 @@
     </array>''')
     self.assertEquals(output.strip(), expected_output.strip())
 
+  def testRecommendedPolicy(self):
+    # Tests a policy group with a single policy of type 'main'.
+    grd = self.PrepareTest('''
+      {
+        'policy_definitions': [
+          {
+            'name': 'MainGroup',
+            'type': 'group',
+            'policies': [{
+              'name': 'MainPolicy',
+              'type': 'main',
+              'desc': '',
+              'caption': '',
+              'features': {
+                'can_be_recommended' : True
+              },
+              'supported_on': ['chrome.mac:8-'],
+            }],
+            'desc': '',
+            'caption': '',
+          },
+        ],
+        'placeholders': [],
+        'messages': {}
+      }''')
+    output = self.GetOutput(
+        grd,
+        'fr',
+        {'_chromium' : '1', 'mac_bundle_id': 'com.example.Test'},
+        'plist',
+        'en')
+    expected_output = self._GetExpectedOutputs(
+        'Chromium', 'com.example.Test', '''<array>
+      <dict>
+        <key>pfm_name</key>
+        <string>MainPolicy</string>
+        <key>pfm_description</key>
+        <string/>
+        <key>pfm_title</key>
+        <string/>
+        <key>pfm_targets</key>
+        <array>
+          <string>user</string>
+          <string>user-managed</string>
+        </array>
+        <key>pfm_type</key>
+        <string>boolean</string>
+      </dict>
+    </array>''')
+    self.assertEquals(output.strip(), expected_output.strip())
+
+  def testRecommendedOnlyPolicy(self):
+    # Tests a policy group with a single policy of type 'main'.
+    grd = self.PrepareTest('''
+      {
+        'policy_definitions': [
+          {
+            'name': 'MainGroup',
+            'type': 'group',
+            'policies': [{
+              'name': 'MainPolicy',
+              'type': 'main',
+              'desc': '',
+              'caption': '',
+              'features': {
+                'can_be_recommended' : True,
+                'can_be_mandatory' : False
+              },
+              'supported_on': ['chrome.mac:8-'],
+            }],
+            'desc': '',
+            'caption': '',
+          },
+        ],
+        'placeholders': [],
+        'messages': {}
+      }''')
+    output = self.GetOutput(
+        grd,
+        'fr',
+        {'_chromium' : '1', 'mac_bundle_id': 'com.example.Test'},
+        'plist',
+        'en')
+    expected_output = self._GetExpectedOutputs(
+        'Chromium', 'com.example.Test', '''<array>
+      <dict>
+        <key>pfm_name</key>
+        <string>MainPolicy</string>
+        <key>pfm_description</key>
+        <string/>
+        <key>pfm_title</key>
+        <string/>
+        <key>pfm_targets</key>
+        <array>
+          <string>user</string>
+        </array>
+        <key>pfm_type</key>
+        <string>boolean</string>
+      </dict>
+    </array>''')
+    self.assertEquals(output.strip(), expected_output.strip())
+
   def testStringPolicy(self):
     # Tests a policy group with a single policy of type 'string'.
     grd = self.PrepareTest('''
diff --git a/grit/format/policy_templates/writers/reg_writer.py b/grit/format/policy_templates/writers/reg_writer.py
index dcb70f4..ad83046 100644
--- a/grit/format/policy_templates/writers/reg_writer.py
+++ b/grit/format/policy_templates/writers/reg_writer.py
@@ -83,9 +83,10 @@
       list.append('"%s"=%s' % (policy['name'], example_value_str))
 
   def WritePolicy(self, policy):
-    self._WritePolicy(policy,
-                      self.config['win_reg_mandatory_key_name'],
-                      self._mandatory)
+    if self.CanBeMandatory(policy):
+      self._WritePolicy(policy,
+                        self.config['win_reg_mandatory_key_name'],
+                        self._mandatory)
 
   def WriteRecommendedPolicy(self, policy):
     self._WritePolicy(policy,
diff --git a/grit/format/policy_templates/writers/reg_writer_unittest.py b/grit/format/policy_templates/writers/reg_writer_unittest.py
index f698cb4..88fb2e2 100644
--- a/grit/format/policy_templates/writers/reg_writer_unittest.py
+++ b/grit/format/policy_templates/writers/reg_writer_unittest.py
@@ -77,6 +77,35 @@
         '"MainPolicy"=dword:00000001'])
     self.CompareOutputs(output, expected_output)
 
+  def testRecommendedMainPolicy(self):
+    # Tests a policy group with a single policy of type 'main'.
+    grd = self.PrepareTest(
+        '{'
+        '  "policy_definitions": ['
+        '    {'
+        '      "name": "MainPolicy",'
+        '      "type": "main",'
+        '      "features": {'
+        '        "can_be_recommended": True,'
+        '        "can_be_mandatory": False '
+        '      },'
+        '      "caption": "",'
+        '      "desc": "",'
+        '      "supported_on": ["chrome.win:8-"],'
+        '      "example_value": True'
+        '    },'
+        '  ],'
+        '  "placeholders": [],'
+        '  "messages": {},'
+        '}')
+    output = self.GetOutput(grd, 'fr', {'_google_chrome' : '1'}, 'reg', 'en')
+    expected_output = self.NEWLINE.join([
+        'Windows Registry Editor Version 5.00',
+        '',
+        '[HKEY_LOCAL_MACHINE\\Software\\Policies\\Google\\Chrome\\Recommended]',
+        '"MainPolicy"=dword:00000001'])
+    self.CompareOutputs(output, expected_output)
+
   def testStringPolicy(self):
     # Tests a policy group with a single policy of type 'string'.
     grd = self.PrepareTest(
diff --git a/grit/format/policy_templates/writers/template_writer.py b/grit/format/policy_templates/writers/template_writer.py
index 2a8b548..bd48425 100644
--- a/grit/format/policy_templates/writers/template_writer.py
+++ b/grit/format/policy_templates/writers/template_writer.py
@@ -87,6 +87,10 @@
     '''Checks if the given policy can be recommended.'''
     return policy.get('features', {}).get('can_be_recommended', False)
 
+  def CanBeMandatory(self, policy):
+    '''Checks if the given policy can be mandatory.'''
+    return policy.get('features', {}).get('can_be_mandatory', True)
+
   def IsPolicySupportedOnPlatform(self, policy, platform):
     '''Checks if |policy| is supported on |platform|.