summaryrefslogtreecommitdiffstats
path: root/ash/display/json_converter.cc
diff options
context:
space:
mode:
authorrobliao <robliao@chromium.org>2016-03-21 14:34:15 -0700
committerCommit bot <commit-bot@chromium.org>2016-03-21 21:35:59 +0000
commit8c912b533f434aa8509495bf0dd6e2dd177d0fce (patch)
tree03ccccfa410769f312a12aa645f264fd0dc00173 /ash/display/json_converter.cc
parentf47265dc3ede8dc8fc845fdb54502d35171407d0 (diff)
downloadchromium_src-8c912b533f434aa8509495bf0dd6e2dd177d0fce.zip
chromium_src-8c912b533f434aa8509495bf0dd6e2dd177d0fce.tar.gz
chromium_src-8c912b533f434aa8509495bf0dd6e2dd177d0fce.tar.bz2
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}
Diffstat (limited to 'ash/display/json_converter.cc')
-rw-r--r--ash/display/json_converter.cc197
1 files changed, 197 insertions, 0 deletions
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 <string>
+
+#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 <typename Getter, typename Output>
+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 <typename Output>
+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<DisplayPlacement>* 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<DisplayPlacement> 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<base::ListValue> placement_list(new base::ListValue);
+ for (const auto* placement : layout.placement_list) {
+ scoped_ptr<base::DictionaryValue> 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