From 8c912b533f434aa8509495bf0dd6e2dd177d0fce Mon Sep 17 00:00:00 2001 From: robliao Date: Mon, 21 Mar 2016 14:34:15 -0700 Subject: Refactor JSONValueConverter Out of DisplayLayout Separate the JSON processing code out of DisplayLayout in preparing to move to ui/gfx since ui/gfx has no JSON dependency. BUG=595498 Review URL: https://codereview.chromium.org/1808253004 Cr-Commit-Position: refs/heads/master@{#382398} --- ash/ash.gyp | 4 +- ash/display/display_layout.cc | 168 ++++++++-------------------- ash/display/display_layout.h | 25 ++--- ash/display/display_layout_unittest.cc | 93 ---------------- ash/display/json_converter.cc | 197 +++++++++++++++++++++++++++++++++ ash/display/json_converter.h | 26 +++++ ash/display/json_converter_unittest.cc | 92 +++++++++++++++ 7 files changed, 374 insertions(+), 231 deletions(-) delete mode 100644 ash/display/display_layout_unittest.cc create mode 100644 ash/display/json_converter.cc create mode 100644 ash/display/json_converter.h create mode 100644 ash/display/json_converter_unittest.cc (limited to 'ash') diff --git a/ash/ash.gyp b/ash/ash.gyp index cd1e630..e6d0ac8 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp @@ -91,6 +91,8 @@ 'display/extended_mouse_warp_controller.h', 'display/event_transformation_handler.cc', 'display/event_transformation_handler.h', + 'display/json_converter.cc', + 'display/json_converter.h', 'display/mirror_window_controller.cc', 'display/mirror_window_controller.h', 'display/mouse_cursor_event_filter.cc', @@ -824,11 +826,11 @@ 'display/display_color_manager_chromeos_unittest.cc', 'display/display_error_observer_chromeos_unittest.cc', 'display/display_info_unittest.cc', - 'display/display_layout_unittest.cc', 'display/display_layout_builder_unittest.cc', 'display/display_manager_unittest.cc', 'display/display_util_unittest.cc', 'display/extended_mouse_warp_controller_unittest.cc', + 'display/json_converter_unittest.cc', 'display/mirror_window_controller_unittest.cc', 'display/mouse_cursor_event_filter_unittest.cc', 'display/projecting_observer_chromeos_unittest.cc', diff --git a/ash/display/display_layout.cc b/ash/display/display_layout.cc index 23a0eeb..1897d76 100644 --- a/ash/display/display_layout.cc +++ b/ash/display/display_layout.cc @@ -10,10 +10,8 @@ #include "ash/ash_switches.h" #include "ash/display/display_pref_util.h" #include "ash/shell.h" -#include "base/json/json_value_converter.h" #include "base/logging.h" #include "base/strings/string_number_conversions.h" -#include "base/strings/string_piece.h" #include "base/strings/stringprintf.h" #include "base/values.h" #include "ui/gfx/display.h" @@ -21,50 +19,17 @@ namespace ash { namespace { +// DisplayPlacement Positions +const char kTop[] = "top"; +const char kRight[] = "right"; +const char kBottom[] = "bottom"; +const char kLeft[] = "left"; +const char kUnknown[] = "unknown"; + // The maximum value for 'offset' in DisplayLayout in case of outliers. Need // to change this value in case to support even larger displays. const int kMaxValidOffset = 10000; -// Persistent key names -const char kMirroredKey[] = "mirrored"; -const char kDefaultUnifiedKey[] = "default_unified"; -const char kPrimaryIdKey[] = "primary-id"; -const char kDisplayPlacementKey[] = "display_placement"; - -// DisplayPlacement -const char kPositionKey[] = "position"; -const char kOffsetKey[] = "offset"; -const char kDisplayPlacementDisplayIdKey[] = "display_id"; -const char kDisplayPlacementParentDisplayIdKey[] = "parent_display_id"; - -using PositionToStringMap = std::map; -using DisplayPlacementMap = std::unordered_map; - -const PositionToStringMap* GetPositionToStringMap() { - static const PositionToStringMap* map = CreateToStringMap( - DisplayPlacement::TOP, "top", DisplayPlacement::BOTTOM, "bottom", - DisplayPlacement::RIGHT, "right", DisplayPlacement::LEFT, "left"); - return map; -} - -std::string ToPositionString(DisplayPlacement::Position position) { - const PositionToStringMap* map = GetPositionToStringMap(); - PositionToStringMap::const_iterator iter = map->find(position); - return iter != map->end() ? iter->second : std::string("unknown"); -} - -bool GetPositionFromString(const base::StringPiece& position, - DisplayPlacement::Position* field) { - if (ReverseFind(GetPositionToStringMap(), position, field)) - return true; - LOG(ERROR) << "Invalid position value:" << position; - return false; -} - -bool GetDisplayIdFromString(const base::StringPiece& position, int64_t* field) { - return base::StringToInt64(position, field); -} - bool IsIdInList(int64_t id, const DisplayIdList& list) { const auto iter = std::find_if(list.begin(), list.end(), @@ -130,101 +95,64 @@ std::string DisplayPlacement::ToString() const { s << "id=" << display_id << ", "; if (parent_display_id != gfx::Display::kInvalidDisplayID) s << "parent=" << parent_display_id << ", "; - s << ToPositionString(position) << ", "; + s << PositionToString(position) << ", "; s << offset; return s.str(); } // static -void DisplayPlacement::RegisterJSONConverter( - base::JSONValueConverter* converter) { - converter->RegisterIntField(kOffsetKey, &DisplayPlacement::offset); - converter->RegisterCustomField( - kPositionKey, &DisplayPlacement::position, &GetPositionFromString); - converter->RegisterCustomField(kDisplayPlacementDisplayIdKey, - &DisplayPlacement::display_id, - &GetDisplayIdFromString); - converter->RegisterCustomField(kDisplayPlacementParentDisplayIdKey, - &DisplayPlacement::parent_display_id, - &GetDisplayIdFromString); +std::string DisplayPlacement::PositionToString(Position position) { + switch (position) { + case TOP: + return kTop; + case RIGHT: + return kRight; + case BOTTOM: + return kBottom; + case LEFT: + return kLeft; + } + return kUnknown; } -//////////////////////////////////////////////////////////////////////////////// -// DisplayLayout - -DisplayLayout::DisplayLayout() - : mirrored(false), - default_unified(true), - primary_id(gfx::Display::kInvalidDisplayID) {} - -DisplayLayout::~DisplayLayout() {} - // static -bool DisplayLayout::ConvertFromValue(const base::Value& value, - DisplayLayout* layout) { - layout->placement_list.clear(); - base::JSONValueConverter converter; - if (!converter.Convert(value, layout)) - return false; - if (layout->placement_list.size() != 0u) +bool DisplayPlacement::StringToPosition(const base::StringPiece& string, + Position* position) { + if (string == kTop) { + *position = TOP; return true; - // For compatibility with old format. - const base::DictionaryValue* dict_value = nullptr; - if (!value.GetAsDictionary(&dict_value) || dict_value == nullptr) - return false; - int offset; - if (dict_value->GetInteger(kOffsetKey, &offset)) { - DisplayPlacement::Position position; - std::string position_str; - if (!dict_value->GetString(kPositionKey, &position_str)) - return false; - GetPositionFromString(position_str, &position); - layout->placement_list.push_back(new DisplayPlacement(position, offset)); } - return true; -} -// static -bool DisplayLayout::ConvertToValue(const DisplayLayout& layout, - base::Value* value) { - base::DictionaryValue* dict_value = nullptr; - if (!value->GetAsDictionary(&dict_value) || dict_value == nullptr) - return false; + if (string == kRight) { + *position = RIGHT; + return true; + } - dict_value->SetBoolean(kMirroredKey, layout.mirrored); - dict_value->SetBoolean(kDefaultUnifiedKey, layout.default_unified); - dict_value->SetString(kPrimaryIdKey, base::Int64ToString(layout.primary_id)); + if (string == kBottom) { + *position = BOTTOM; + return true; + } - scoped_ptr placement_list(new base::ListValue); - for (const auto* placement : layout.placement_list) { - scoped_ptr placement_value( - new base::DictionaryValue); - placement_value->SetString(kPositionKey, - ToPositionString(placement->position)); - placement_value->SetInteger(kOffsetKey, placement->offset); - placement_value->SetString(kDisplayPlacementDisplayIdKey, - base::Int64ToString(placement->display_id)); - placement_value->SetString( - kDisplayPlacementParentDisplayIdKey, - base::Int64ToString(placement->parent_display_id)); - placement_list->Append(std::move(placement_value)); + if (string == kLeft) { + *position = LEFT; + return true; } - dict_value->Set(kDisplayPlacementKey, std::move(placement_list)); - return true; -} -// static -void DisplayLayout::RegisterJSONConverter( - base::JSONValueConverter* converter) { - converter->RegisterBoolField(kMirroredKey, &DisplayLayout::mirrored); - converter->RegisterBoolField(kDefaultUnifiedKey, - &DisplayLayout::default_unified); - converter->RegisterCustomField( - kPrimaryIdKey, &DisplayLayout::primary_id, &GetDisplayIdFromString); - converter->RegisterRepeatedMessage( - kDisplayPlacementKey, &DisplayLayout::placement_list); + LOG(ERROR) << "Invalid position value:" << string; + + return false; } +//////////////////////////////////////////////////////////////////////////////// +// DisplayLayout + +DisplayLayout::DisplayLayout() + : mirrored(false), + default_unified(true), + primary_id(gfx::Display::kInvalidDisplayID) {} + +DisplayLayout::~DisplayLayout() {} + // static bool DisplayLayout::Validate(const DisplayIdList& list, const DisplayLayout& layout) { diff --git a/ash/display/display_layout.h b/ash/display/display_layout.h index af80b68..136360b 100644 --- a/ash/display/display_layout.h +++ b/ash/display/display_layout.h @@ -14,16 +14,17 @@ #include "base/macros.h" #include "base/memory/scoped_ptr.h" #include "base/memory/scoped_vector.h" - -namespace gfx { -class Display; -} +#include "base/strings/string_piece.h" namespace base { class Value; template class JSONValueConverter; } +namespace gfx { +class Display; +} + namespace ash { // An identifier used to manage display layout in DisplayManager / @@ -68,10 +69,9 @@ struct ASH_EXPORT DisplayPlacement { std::string ToString() const; - // Used by JSONValueConverter to generate DisplayPlacement from a - // JSON value. See json_value_converter.h. - static void RegisterJSONConverter( - base::JSONValueConverter* converter); + static std::string PositionToString(Position position); + static bool StringToPosition(const base::StringPiece& string, + Position* position); }; class ASH_EXPORT DisplayLayout final { @@ -79,15 +79,6 @@ class ASH_EXPORT DisplayLayout final { DisplayLayout(); ~DisplayLayout(); - // Converter functions to/from base::Value. - static bool ConvertFromValue(const base::Value& value, DisplayLayout* layout); - static bool ConvertToValue(const DisplayLayout& layout, base::Value* value); - - // Used by JSONValueConverter to generate DisplayLayout from a - // JSON value. See json_value_converter.h. - static void RegisterJSONConverter( - base::JSONValueConverter* converter); - // Validates the layout object. static bool Validate(const DisplayIdList& list, const DisplayLayout& layout); diff --git a/ash/display/display_layout_unittest.cc b/ash/display/display_layout_unittest.cc deleted file mode 100644 index 7a614df..0000000 --- a/ash/display/display_layout_unittest.cc +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ash/display/display_layout.h" - -#include "base/json/json_reader.h" -#include "base/values.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace ash { - -typedef testing::Test DisplayLayoutTest; - -TEST_F(DisplayLayoutTest, ConvertFromToValue) { - DisplayLayout layout; - layout.primary_id = 1; - layout.mirrored = true; - layout.default_unified = false; - layout.placement_list.push_back(new DisplayPlacement); - layout.placement_list.push_back(new DisplayPlacement); - layout.placement_list[0]->display_id = 2; - layout.placement_list[0]->parent_display_id = 1; - layout.placement_list[0]->position = DisplayPlacement::BOTTOM; - - layout.placement_list[1]->display_id = 3; - layout.placement_list[1]->parent_display_id = 2; - layout.placement_list[1]->position = DisplayPlacement::LEFT; - layout.placement_list[1]->offset = 30; - - base::DictionaryValue value; - DisplayLayout::ConvertToValue(layout, &value); - - const char data[] = - "{\n" - " \"primary-id\": \"1\",\n" - " \"mirrored\": true,\n" - " \"default_unified\": false,\n" - " \"display_placement\": [{\n" - " \"display_id\": \"2\",\n" - " \"parent_display_id\": \"1\",\n" - " \"position\": \"bottom\",\n" - " \"offset\": 0\n" - " },{\n" - " \"display_id\": \"3\",\n" - " \"parent_display_id\": \"2\",\n" - " \"position\": \"left\",\n" - " \"offset\": 30\n" - " }]\n" - "}"; - int error_code = 0, error_line, error_column; - std::string error_msg; - scoped_ptr read_value(base::JSONReader::ReadAndReturnError( - data, 0, &error_code, &error_msg, &error_line, &error_column)); - ASSERT_EQ(0, error_code) << error_msg << " at " << error_line << ":" - << error_column; - EXPECT_TRUE(value.Equals(read_value.get())); - - DisplayLayout read_layout; - EXPECT_TRUE(DisplayLayout::ConvertFromValue(*read_value, &read_layout)); - EXPECT_EQ(read_layout.mirrored, layout.mirrored); - EXPECT_EQ(read_layout.primary_id, layout.primary_id); - EXPECT_EQ(read_layout.default_unified, layout.default_unified); - EXPECT_TRUE(read_layout.HasSamePlacementList(layout)); -} - -TEST_F(DisplayLayoutTest, ConvertFromOldJSON) { - const char data[] = - "{\n" - " \"primary-id\": \"1\",\n" - " \"mirrored\": true,\n" - " \"default_unified\": false,\n" - " \"position\": \"bottom\",\n" - " \"offset\": 20\n" - "}"; - int error_code = 0, error_line, error_column; - std::string error_msg; - scoped_ptr read_value(base::JSONReader::ReadAndReturnError( - data, 0, &error_code, &error_msg, &error_line, &error_column)); - ASSERT_EQ(0, error_code) << error_msg << " at " << error_line << ":" - << error_column; - - DisplayLayout read_layout; - EXPECT_TRUE(DisplayLayout::ConvertFromValue(*read_value, &read_layout)); - EXPECT_EQ(true, read_layout.mirrored); - EXPECT_EQ(1, read_layout.primary_id); - EXPECT_EQ(false, read_layout.default_unified); - ASSERT_EQ(1u, read_layout.placement_list.size()); - EXPECT_EQ(DisplayPlacement::BOTTOM, read_layout.placement_list[0]->position); - EXPECT_EQ(20, read_layout.placement_list[0]->offset); -} - -} // namespace ash diff --git a/ash/display/json_converter.cc b/ash/display/json_converter.cc new file mode 100644 index 0000000..91017b6 --- /dev/null +++ b/ash/display/json_converter.cc @@ -0,0 +1,197 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/display/json_converter.h" + +#include + +#include "ash/display/display_layout.h" +#include "ash/display/display_pref_util.h" +#include "base/logging.h" +#include "base/memory/scoped_vector.h" +#include "base/strings/string_number_conversions.h" +#include "base/values.h" + +namespace ash { + +namespace { + +// Persistent key names +const char kMirroredKey[] = "mirrored"; +const char kDefaultUnifiedKey[] = "default_unified"; +const char kPrimaryIdKey[] = "primary-id"; +const char kDisplayPlacementKey[] = "display_placement"; + +// DisplayPlacement key names +const char kPositionKey[] = "position"; +const char kOffsetKey[] = "offset"; +const char kDisplayPlacementDisplayIdKey[] = "display_id"; +const char kDisplayPlacementParentDisplayIdKey[] = "parent_display_id"; + +bool AddLegacyValuesFromValue(const base::Value& value, DisplayLayout* layout) { + const base::DictionaryValue* dict_value = nullptr; + if (!value.GetAsDictionary(&dict_value)) + return false; + int offset; + if (dict_value->GetInteger(kOffsetKey, &offset)) { + DisplayPlacement::Position position; + std::string position_str; + if (!dict_value->GetString(kPositionKey, &position_str)) + return false; + DisplayPlacement::StringToPosition(position_str, &position); + layout->placement_list.push_back(new DisplayPlacement(position, offset)); + } + return true; +} + +// Returns true if +// The key is missing - output is left unchanged +// The key matches the type - output is updated to the value. +template +bool UpdateFromDict(const base::DictionaryValue* dict_value, + const std::string& field_name, + Getter getter, + Output* output) { + const base::Value* field = nullptr; + if (!dict_value->Get(field_name, &field)) { + LOG(WARNING) << "Missing field: " << field_name; + return true; + } + + return (field->*getter)(output); +} + +// No implementation here as specialization is required. +template +bool UpdateFromDict(const base::DictionaryValue* dict_value, + const std::string& field_name, + Output* output); + +template <> +bool UpdateFromDict(const base::DictionaryValue* dict_value, + const std::string& field_name, + bool* output) { + return UpdateFromDict(dict_value, field_name, &base::Value::GetAsBoolean, + output); +} + +template <> +bool UpdateFromDict(const base::DictionaryValue* dict_value, + const std::string& field_name, + int* output) { + return UpdateFromDict(dict_value, field_name, &base::Value::GetAsInteger, + output); +} + +template <> +bool UpdateFromDict(const base::DictionaryValue* dict_value, + const std::string& field_name, + DisplayPlacement::Position* output) { + bool (base::Value::*getter)(std::string*) const = &base::Value::GetAsString; + std::string value; + if (!UpdateFromDict(dict_value, field_name, getter, &value)) + return false; + + return value.empty() ? true + : DisplayPlacement::StringToPosition(value, output); +} + +template <> +bool UpdateFromDict(const base::DictionaryValue* dict_value, + const std::string& field_name, + int64_t* output) { + bool (base::Value::*getter)(std::string*) const = &base::Value::GetAsString; + std::string value; + if (!UpdateFromDict(dict_value, field_name, getter, &value)) + return false; + + return value.empty() ? true : base::StringToInt64(value, output); +} + +template <> +bool UpdateFromDict(const base::DictionaryValue* dict_value, + const std::string& field_name, + ScopedVector* output) { + bool (base::Value::*getter)(const base::ListValue**) const = + &base::Value::GetAsList; + const base::ListValue* list = nullptr; + if (!UpdateFromDict(dict_value, field_name, getter, &list)) + return false; + + if (list == nullptr) + return true; + + output->reserve(list->GetSize()); + for (const auto& list_item : *list) { + const base::DictionaryValue* item_values = nullptr; + if (!list_item->GetAsDictionary(&item_values)) + return false; + + scoped_ptr item(new DisplayPlacement); + if (!UpdateFromDict(item_values, kOffsetKey, &item->offset) || + !UpdateFromDict(item_values, kPositionKey, &item->position) || + !UpdateFromDict(item_values, kDisplayPlacementDisplayIdKey, + &item->display_id) || + !UpdateFromDict(item_values, kDisplayPlacementParentDisplayIdKey, + &item->parent_display_id)) { + return false; + } + + output->push_back(std::move(item)); + } + return true; +} + +} // namespace + +bool JsonToDisplayLayout(const base::Value& value, DisplayLayout* layout) { + layout->placement_list.clear(); + const base::DictionaryValue* dict_value = nullptr; + if (!value.GetAsDictionary(&dict_value)) + return false; + + if (!UpdateFromDict(dict_value, kMirroredKey, &layout->mirrored) || + !UpdateFromDict(dict_value, kDefaultUnifiedKey, + &layout->default_unified) || + !UpdateFromDict(dict_value, kPrimaryIdKey, &layout->primary_id)) { + return false; + } + + UpdateFromDict(dict_value, kDisplayPlacementKey, &layout->placement_list); + + if (layout->placement_list.size() != 0u) + return true; + + // For compatibility with old format. + return AddLegacyValuesFromValue(value, layout); +} + +bool DisplayLayoutToJson(const DisplayLayout& layout, base::Value* value) { + base::DictionaryValue* dict_value = nullptr; + if (!value->GetAsDictionary(&dict_value)) + return false; + + dict_value->SetBoolean(kMirroredKey, layout.mirrored); + dict_value->SetBoolean(kDefaultUnifiedKey, layout.default_unified); + dict_value->SetString(kPrimaryIdKey, base::Int64ToString(layout.primary_id)); + + scoped_ptr placement_list(new base::ListValue); + for (const auto* placement : layout.placement_list) { + scoped_ptr placement_value( + new base::DictionaryValue); + placement_value->SetString( + kPositionKey, DisplayPlacement::PositionToString(placement->position)); + placement_value->SetInteger(kOffsetKey, placement->offset); + placement_value->SetString(kDisplayPlacementDisplayIdKey, + base::Int64ToString(placement->display_id)); + placement_value->SetString( + kDisplayPlacementParentDisplayIdKey, + base::Int64ToString(placement->parent_display_id)); + placement_list->Append(std::move(placement_value)); + } + dict_value->Set(kDisplayPlacementKey, std::move(placement_list)); + return true; +} + +} // namespace ash diff --git a/ash/display/json_converter.h b/ash/display/json_converter.h new file mode 100644 index 0000000..4c88eb0 --- /dev/null +++ b/ash/display/json_converter.h @@ -0,0 +1,26 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_DISPLAY_JSON_CONVERTER_H_ +#define ASH_DISPLAY_JSON_CONVERTER_H_ + +#include "ash/ash_export.h" + +namespace base { +class Value; +} + +namespace ash { + +class DisplayLayout; + +ASH_EXPORT bool JsonToDisplayLayout(const base::Value& value, + DisplayLayout* layout); + +ASH_EXPORT bool DisplayLayoutToJson(const DisplayLayout& layout, + base::Value* value); + +} // namespace ash + +#endif // ASH_DISPLAY_JSON_CONVERTER_H_ diff --git a/ash/display/json_converter_unittest.cc b/ash/display/json_converter_unittest.cc new file mode 100644 index 0000000..3c964d0 --- /dev/null +++ b/ash/display/json_converter_unittest.cc @@ -0,0 +1,92 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/display/json_converter.h" + +#include "ash/display/display_layout.h" +#include "base/json/json_reader.h" +#include "base/values.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace ash { + +TEST(JsonConverterTest, JsonFromToDisplayLayout) { + DisplayLayout layout; + layout.primary_id = 1; + layout.mirrored = true; + layout.default_unified = false; + layout.placement_list.push_back(new DisplayPlacement); + layout.placement_list.push_back(new DisplayPlacement); + layout.placement_list[0]->display_id = 2; + layout.placement_list[0]->parent_display_id = 1; + layout.placement_list[0]->position = DisplayPlacement::BOTTOM; + + layout.placement_list[1]->display_id = 3; + layout.placement_list[1]->parent_display_id = 2; + layout.placement_list[1]->position = DisplayPlacement::LEFT; + layout.placement_list[1]->offset = 30; + + base::DictionaryValue value; + DisplayLayoutToJson(layout, &value); + + const char data[] = + "{\n" + " \"primary-id\": \"1\",\n" + " \"mirrored\": true,\n" + " \"default_unified\": false,\n" + " \"display_placement\": [{\n" + " \"display_id\": \"2\",\n" + " \"parent_display_id\": \"1\",\n" + " \"position\": \"bottom\",\n" + " \"offset\": 0\n" + " },{\n" + " \"display_id\": \"3\",\n" + " \"parent_display_id\": \"2\",\n" + " \"position\": \"left\",\n" + " \"offset\": 30\n" + " }]\n" + "}"; + int error_code = 0, error_line, error_column; + std::string error_msg; + scoped_ptr read_value(base::JSONReader::ReadAndReturnError( + data, 0, &error_code, &error_msg, &error_line, &error_column)); + ASSERT_EQ(0, error_code) << error_msg << " at " << error_line << ":" + << error_column; + EXPECT_TRUE(value.Equals(read_value.get())); + + DisplayLayout read_layout; + EXPECT_TRUE(JsonToDisplayLayout(*read_value, &read_layout)); + EXPECT_EQ(read_layout.mirrored, layout.mirrored); + EXPECT_EQ(read_layout.primary_id, layout.primary_id); + EXPECT_EQ(read_layout.default_unified, layout.default_unified); + EXPECT_TRUE(read_layout.HasSamePlacementList(layout)); +} + +TEST(JsonConverterTest, OldJsonToDisplayLayout) { + const char data[] = + "{\n" + " \"primary-id\": \"1\",\n" + " \"mirrored\": true,\n" + " \"default_unified\": false,\n" + " \"position\": \"bottom\",\n" + " \"offset\": 20\n" + "}"; + int error_code = 0, error_line, error_column; + std::string error_msg; + scoped_ptr read_value(base::JSONReader::ReadAndReturnError( + data, 0, &error_code, &error_msg, &error_line, &error_column)); + ASSERT_EQ(0, error_code) << error_msg << " at " << error_line << ":" + << error_column; + + DisplayLayout read_layout; + EXPECT_TRUE(JsonToDisplayLayout(*read_value, &read_layout)); + EXPECT_EQ(true, read_layout.mirrored); + EXPECT_EQ(1, read_layout.primary_id); + EXPECT_EQ(false, read_layout.default_unified); + ASSERT_EQ(1u, read_layout.placement_list.size()); + EXPECT_EQ(DisplayPlacement::BOTTOM, read_layout.placement_list[0]->position); + EXPECT_EQ(20, read_layout.placement_list[0]->offset); +} + +} // namespace ash -- cgit v1.1