Commit 0107c327 authored by alemate's avatar alemate Committed by Commit bot

about_flags::ReportCustomFlags() should use signed 32-bit IDs.

On 32-bit architectures UMA Histogram IDs (enum
LoginCustomFlags) are negative. So HistogramBase::Sample
(which is int32_t) should be used.

BUG=408196
TEST=manual

Review URL: https://codereview.chromium.org/509923003

Cr-Commit-Position: refs/heads/master@{#293062}
parent 49690368
...@@ -67,7 +67,7 @@ using base::UserMetricsAction; ...@@ -67,7 +67,7 @@ using base::UserMetricsAction;
namespace about_flags { namespace about_flags {
const uint32_t kBadSwitchFormatHistogramId = 0; const base::HistogramBase::Sample kBadSwitchFormatHistogramId = 0;
// Macros to simplify specifying the type. // Macros to simplify specifying the type.
#define SINGLE_VALUE_TYPE_AND_VALUE(command_line_switch, switch_value) \ #define SINGLE_VALUE_TYPE_AND_VALUE(command_line_switch, switch_value) \
...@@ -2265,8 +2265,9 @@ void RecordUMAStatistics(FlagsStorage* flags_storage) { ...@@ -2265,8 +2265,9 @@ void RecordUMAStatistics(FlagsStorage* flags_storage) {
content::RecordAction(UserMetricsAction("StartupTick")); content::RecordAction(UserMetricsAction("StartupTick"));
} }
uint32_t GetSwitchUMAId(const std::string& switch_name) { base::HistogramBase::Sample GetSwitchUMAId(const std::string& switch_name) {
return static_cast<uint32_t>(metrics::HashMetricName(switch_name)); return static_cast<base::HistogramBase::Sample>(
metrics::HashMetricName(switch_name));
} }
void ReportCustomFlags(const std::string& uma_histogram_hame, void ReportCustomFlags(const std::string& uma_histogram_hame,
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <string> #include <string>
#include "base/command_line.h" #include "base/command_line.h"
#include "base/metrics/histogram_base.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
class PrefService; class PrefService;
...@@ -26,7 +27,7 @@ class FlagsStorage; ...@@ -26,7 +27,7 @@ class FlagsStorage;
// This value is reported as switch histogram ID if switch name has unknown // This value is reported as switch histogram ID if switch name has unknown
// format. // format.
extern const uint32_t kBadSwitchFormatHistogramId; extern const base::HistogramBase::Sample kBadSwitchFormatHistogramId;
// Enumeration of OSs. // Enumeration of OSs.
// This is exposed only for testing. // This is exposed only for testing.
...@@ -171,7 +172,7 @@ int GetCurrentPlatform(); ...@@ -171,7 +172,7 @@ int GetCurrentPlatform();
void RecordUMAStatistics(FlagsStorage* flags_storage); void RecordUMAStatistics(FlagsStorage* flags_storage);
// Returns the UMA id for the specified switch name. // Returns the UMA id for the specified switch name.
uint32_t GetSwitchUMAId(const std::string& switch_name); base::HistogramBase::Sample GetSwitchUMAId(const std::string& switch_name);
// Sends stats (as UMA histogram) about command_line_difference. // Sends stats (as UMA histogram) about command_line_difference.
// This is used on ChromeOS to report flags that lead to browser restart. // This is used on ChromeOS to report flags that lead to browser restart.
......
...@@ -41,19 +41,20 @@ const char kValueForMultiSwitch2[] = "value_for_multi_switch2"; ...@@ -41,19 +41,20 @@ const char kValueForMultiSwitch2[] = "value_for_multi_switch2";
const char kEnableDisableValue1[] = "value1"; const char kEnableDisableValue1[] = "value1";
const char kEnableDisableValue2[] = "value2"; const char kEnableDisableValue2[] = "value2";
typedef std::map<std::string, uint32_t> SwitchToIdMap; typedef base::HistogramBase::Sample Sample;
typedef std::map<std::string, Sample> SwitchToIdMap;
// This is a helper function to the ReadEnumFromHistogramsXml(). // This is a helper function to the ReadEnumFromHistogramsXml().
// Extracts single enum (with integer values) from histograms.xml. // Extracts single enum (with integer values) from histograms.xml.
// Expects |reader| to point at given enum. // Expects |reader| to point at given enum.
// Returns map { value => label }. // Returns map { value => label }.
// Returns empty map on error. // Returns empty map on error.
std::map<uint32_t, std::string> ParseEnumFromHistogramsXml( std::map<Sample, std::string> ParseEnumFromHistogramsXml(
const std::string& enum_name, const std::string& enum_name,
XmlReader* reader) { XmlReader* reader) {
int entries_index = -1; int entries_index = -1;
std::map<uint32_t, std::string> result; std::map<Sample, std::string> result;
bool success = true; bool success = true;
while (true) { while (true) {
...@@ -80,8 +81,8 @@ std::map<uint32_t, std::string> ParseEnumFromHistogramsXml( ...@@ -80,8 +81,8 @@ std::map<uint32_t, std::string> ParseEnumFromHistogramsXml(
success = false; success = false;
} }
uint32_t value; Sample value;
if (has_value && !base::StringToUint(value_str, &value)) { if (has_value && !base::StringToInt(value_str, &value)) {
ADD_FAILURE() << "Bad " << enum_name << " enum entry (at index " ADD_FAILURE() << "Bad " << enum_name << " enum entry (at index "
<< entries_index << ", label='" << label << entries_index << ", label='" << label
<< "', value_str='" << value_str << "', value_str='" << value_str
...@@ -105,7 +106,7 @@ std::map<uint32_t, std::string> ParseEnumFromHistogramsXml( ...@@ -105,7 +106,7 @@ std::map<uint32_t, std::string> ParseEnumFromHistogramsXml(
// until possible. // until possible.
reader->Next(); reader->Next();
} }
return (success ? result : std::map<uint32_t, std::string>()); return (success ? result : std::map<Sample, std::string>());
} }
// Find and read given enum (with integer values) from histograms.xml. // Find and read given enum (with integer values) from histograms.xml.
...@@ -117,10 +118,10 @@ std::map<uint32_t, std::string> ParseEnumFromHistogramsXml( ...@@ -117,10 +118,10 @@ std::map<uint32_t, std::string> ParseEnumFromHistogramsXml(
// becomes: // becomes:
// { 9 => "enable-pinch-virtual-viewport" } // { 9 => "enable-pinch-virtual-viewport" }
// Returns empty map on error. // Returns empty map on error.
std::map<uint32_t, std::string> ReadEnumFromHistogramsXml( std::map<Sample, std::string> ReadEnumFromHistogramsXml(
const std::string& enum_name, const std::string& enum_name,
XmlReader* histograms_xml) { XmlReader* histograms_xml) {
std::map<uint32_t, std::string> login_custom_flags; std::map<Sample, std::string> login_custom_flags;
// Implement simple depth first search. // Implement simple depth first search.
while (true) { while (true) {
...@@ -131,7 +132,7 @@ std::map<uint32_t, std::string> ReadEnumFromHistogramsXml( ...@@ -131,7 +132,7 @@ std::map<uint32_t, std::string> ReadEnumFromHistogramsXml(
if (!login_custom_flags.empty()) { if (!login_custom_flags.empty()) {
EXPECT_TRUE(login_custom_flags.empty()) EXPECT_TRUE(login_custom_flags.empty())
<< "Duplicate enum '" << enum_name << "' found in histograms.xml"; << "Duplicate enum '" << enum_name << "' found in histograms.xml";
return std::map<uint32_t, std::string>(); return std::map<Sample, std::string>();
} }
const bool got_into_enum = histograms_xml->Read(); const bool got_into_enum = histograms_xml->Read();
...@@ -147,7 +148,7 @@ std::map<uint32_t, std::string> ReadEnumFromHistogramsXml( ...@@ -147,7 +148,7 @@ std::map<uint32_t, std::string> ReadEnumFromHistogramsXml(
<< "' (looks empty) found in histograms.xml."; << "' (looks empty) found in histograms.xml.";
} }
if (login_custom_flags.empty()) if (login_custom_flags.empty())
return std::map<uint32_t, std::string>(); return std::map<Sample, std::string>();
} }
} }
// Go deeper if possible (stops at the closing tag of the deepest node). // Go deeper if possible (stops at the closing tag of the deepest node).
...@@ -676,9 +677,9 @@ class AboutFlagsHistogramTest : public ::testing::Test { ...@@ -676,9 +677,9 @@ class AboutFlagsHistogramTest : public ::testing::Test {
// This is a helper function to check that all IDs in enum LoginCustomFlags in // This is a helper function to check that all IDs in enum LoginCustomFlags in
// histograms.xml are unique. // histograms.xml are unique.
void SetSwitchToHistogramIdMapping(const std::string& switch_name, void SetSwitchToHistogramIdMapping(const std::string& switch_name,
const uint32_t switch_histogram_id, const Sample switch_histogram_id,
std::map<std::string, uint32_t>* out_map) { std::map<std::string, Sample>* out_map) {
const std::pair<std::map<std::string, uint32_t>::iterator, bool> status = const std::pair<std::map<std::string, Sample>::iterator, bool> status =
out_map->insert(std::make_pair(switch_name, switch_histogram_id)); out_map->insert(std::make_pair(switch_name, switch_histogram_id));
if (!status.second) { if (!status.second) {
EXPECT_TRUE(status.first->second == switch_histogram_id) EXPECT_TRUE(status.first->second == switch_histogram_id)
...@@ -690,9 +691,9 @@ class AboutFlagsHistogramTest : public ::testing::Test { ...@@ -690,9 +691,9 @@ class AboutFlagsHistogramTest : public ::testing::Test {
// This method generates a hint for the user for what string should be added // This method generates a hint for the user for what string should be added
// to the enum LoginCustomFlags to make in consistent. // to the enum LoginCustomFlags to make in consistent.
std::string GetHistogramEnumEntryText(const std::string& switch_name, std::string GetHistogramEnumEntryText(const std::string& switch_name,
uint32_t value) { Sample value) {
return base::StringPrintf( return base::StringPrintf(
"<int value=\"%u\" label=\"%s\"/>", value, switch_name.c_str()); "<int value=\"%d\" label=\"%s\"/>", value, switch_name.c_str());
} }
}; };
...@@ -708,7 +709,7 @@ TEST_F(AboutFlagsHistogramTest, CheckHistograms) { ...@@ -708,7 +709,7 @@ TEST_F(AboutFlagsHistogramTest, CheckHistograms) {
XmlReader histograms_xml; XmlReader histograms_xml;
ASSERT_TRUE(histograms_xml.LoadFile( ASSERT_TRUE(histograms_xml.LoadFile(
FilePathStringTypeToString(histograms_xml_file_path.value()))); FilePathStringTypeToString(histograms_xml_file_path.value())));
std::map<uint32_t, std::string> login_custom_flags = std::map<Sample, std::string> login_custom_flags =
ReadEnumFromHistogramsXml("LoginCustomFlags", &histograms_xml); ReadEnumFromHistogramsXml("LoginCustomFlags", &histograms_xml);
ASSERT_TRUE(login_custom_flags.size()) ASSERT_TRUE(login_custom_flags.size())
<< "Error reading enum 'LoginCustomFlags' from histograms.xml."; << "Error reading enum 'LoginCustomFlags' from histograms.xml.";
...@@ -722,7 +723,7 @@ TEST_F(AboutFlagsHistogramTest, CheckHistograms) { ...@@ -722,7 +723,7 @@ TEST_F(AboutFlagsHistogramTest, CheckHistograms) {
"Consider adding entry:\n" "Consider adding entry:\n"
<< " " << GetHistogramEnumEntryText("BAD_FLAG_FORMAT", 0); << " " << GetHistogramEnumEntryText("BAD_FLAG_FORMAT", 0);
// Check that all LoginCustomFlags entries have correct values. // Check that all LoginCustomFlags entries have correct values.
for (std::map<uint32_t, std::string>::const_iterator it = for (std::map<Sample, std::string>::const_iterator it =
login_custom_flags.begin(); login_custom_flags.begin();
it != login_custom_flags.end(); it != login_custom_flags.end();
++it) { ++it) {
...@@ -732,7 +733,7 @@ TEST_F(AboutFlagsHistogramTest, CheckHistograms) { ...@@ -732,7 +733,7 @@ TEST_F(AboutFlagsHistogramTest, CheckHistograms) {
"", it->first, &histograms_xml_switches_ids); "", it->first, &histograms_xml_switches_ids);
continue; continue;
} }
const uint32_t uma_id = GetSwitchUMAId(it->second); const Sample uma_id = GetSwitchUMAId(it->second);
EXPECT_EQ(uma_id, it->first) EXPECT_EQ(uma_id, it->first)
<< "histograms.xml enum LoginCustomFlags " << "histograms.xml enum LoginCustomFlags "
"entry '" << it->second << "' has incorrect value=" << it->first "entry '" << it->second << "' has incorrect value=" << it->first
...@@ -750,7 +751,7 @@ TEST_F(AboutFlagsHistogramTest, CheckHistograms) { ...@@ -750,7 +751,7 @@ TEST_F(AboutFlagsHistogramTest, CheckHistograms) {
// Skip empty placeholders. // Skip empty placeholders.
if (it->empty()) if (it->empty())
continue; continue;
const uint32_t uma_id = GetSwitchUMAId(*it); const Sample uma_id = GetSwitchUMAId(*it);
EXPECT_NE(kBadSwitchFormatHistogramId, uma_id) EXPECT_NE(kBadSwitchFormatHistogramId, uma_id)
<< "Command-line switch '" << *it << "Command-line switch '" << *it
<< "' from about_flags.cc has UMA ID equal to reserved value " << "' from about_flags.cc has UMA ID equal to reserved value "
......
This diff is collapsed.
...@@ -80,14 +80,27 @@ def TransformByAlphabetizing(node): ...@@ -80,14 +80,27 @@ def TransformByAlphabetizing(node):
# Put subnodes in a list of node,key pairs to allow for custom sorting. # Put subnodes in a list of node,key pairs to allow for custom sorting.
subtag, key_function = ALPHABETIZATION_RULES[node.tagName] subtag, key_function = ALPHABETIZATION_RULES[node.tagName]
subnodes = [] subnodes = []
last_key = -1 sort_key = -1
pending_node_indices = []
for c in node.childNodes: for c in node.childNodes:
if (c.nodeType == xml.dom.minidom.Node.ELEMENT_NODE and if (c.nodeType == xml.dom.minidom.Node.ELEMENT_NODE and
c.tagName == subtag): c.tagName == subtag):
last_key = key_function(c) sort_key = key_function(c)
# Subnodes that we don't want to rearrange use the last node's key, # Replace sort keys for delayed nodes.
for idx in pending_node_indices:
subnodes[idx][1] = sort_key
pending_node_indices = []
else:
# Subnodes that we don't want to rearrange use the next node's key,
# so they stay in the same relative position. # so they stay in the same relative position.
subnodes.append( (c, last_key) ) # Therefore we delay setting key until the next node is found.
pending_node_indices.append(len(subnodes))
subnodes.append( [c, sort_key] )
# Use last sort key for trailing unknown nodes.
for idx in pending_node_indices:
subnodes[idx][1] = sort_key
# Sort the subnode list. # Sort the subnode list.
subnodes.sort(key=lambda pair: pair[1]) subnodes.sort(key=lambda pair: pair[1])
......
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