// Copyright 2016 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ui/display/manager/json_converter.h" #include #include #include "base/logging.h" #include "base/strings/string_number_conversions.h" #include "base/values.h" #include "ui/display/display_layout.h" namespace display { namespace { // Persistent key names 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::Dict& dict, DisplayLayout* layout) { absl::optional optional_offset = dict.FindInt(kOffsetKey); if (optional_offset) { DisplayPlacement::Position position; const std::string* position_str = dict.FindString(kPositionKey); if (!position_str) return false; DisplayPlacement::StringToPosition(*position_str, &position); layout->placement_list.emplace_back(position, *optional_offset); } return true; } // Returns true if // The key is missing - output is left unchanged // The key matches the type - output is updated to the dict. bool UpdateFromDict(const base::Value::Dict& dict, const std::string& field_name, bool* output) { const base::Value* field = dict.Find(field_name); if (!field) { LOG(WARNING) << "Missing field: " << field_name; return true; } absl::optional field_value = field->GetIfBool(); if (!field_value) return false; *output = *field_value; return true; } // Returns true if // The key is missing - output is left unchanged // The key matches the type - output is updated to the dict. bool UpdateFromDict(const base::Value::Dict& dict, const std::string& field_name, int* output) { const base::Value* field = dict.Find(field_name); if (!field) { LOG(WARNING) << "Missing field: " << field_name; return true; } absl::optional field_value = field->GetIfInt(); if (!field_value) return false; *output = *field_value; return true; } // Returns true if // The key is missing - output is left unchanged // The key matches the type - output is updated to the dict. bool UpdateFromDict(const base::Value::Dict& dict, const std::string& field_name, DisplayPlacement::Position* output) { const base::Value* field = dict.Find(field_name); if (!field) { LOG(WARNING) << "Missing field: " << field_name; return true; } const std::string* field_value = field->GetIfString(); if (!field_value) return false; return field_value->empty() ? true : DisplayPlacement::StringToPosition(*field_value, output); } // Returns true if // The key is missing - output is left unchanged // The key matches the type - output is updated to the dict. bool UpdateFromDict(const base::Value::Dict& dict, const std::string& field_name, int64_t* output) { const base::Value* field = dict.Find(field_name); if (!field) { LOG(WARNING) << "Missing field: " << field_name; return true; } const std::string* field_value = field->GetIfString(); if (!field_value) return false; return field_value->empty() ? true : base::StringToInt64(*field_value, output); } // Returns true if // The key is missing - output is left unchanged // The key matches the type - output is updated to the dict. bool UpdateFromDict(const base::Value::Dict& dict, const std::string& field_name, std::vector* output) { const base::Value* field = dict.Find(field_name); if (!field) { LOG(WARNING) << "Missing field: " << field_name; return true; } if (!field->is_list()) return false; const base::Value::ConstListView list = field->GetListDeprecated(); output->reserve(list.size()); for (const base::Value& list_item : list) { if (!list_item.is_dict()) return false; DisplayPlacement item; if (!UpdateFromDict(list_item.GetDict(), kOffsetKey, &item.offset) || !UpdateFromDict(list_item.GetDict(), kPositionKey, &item.position) || !UpdateFromDict(list_item.GetDict(), kDisplayPlacementDisplayIdKey, &item.display_id) || !UpdateFromDict(list_item.GetDict(), kDisplayPlacementParentDisplayIdKey, &item.parent_display_id)) { return false; } output->push_back(item); } return true; } } // namespace bool JsonToDisplayLayout(const base::Value& value, DisplayLayout* layout) { if (!value.is_dict()) return false; return JsonToDisplayLayout(value.GetDict(), layout); } bool JsonToDisplayLayout(const base::Value::Dict& dict, DisplayLayout* layout) { layout->placement_list.clear(); if (!UpdateFromDict(dict, kDefaultUnifiedKey, &layout->default_unified) || !UpdateFromDict(dict, kPrimaryIdKey, &layout->primary_id)) { return false; } UpdateFromDict(dict, kDisplayPlacementKey, &layout->placement_list); if (layout->placement_list.size() != 0u) return true; // For compatibility with old format. return AddLegacyValuesFromValue(dict, layout); } void DisplayLayoutToJson(const DisplayLayout& layout, base::Value::Dict& dict) { dict.Set(kDefaultUnifiedKey, layout.default_unified); dict.Set(kPrimaryIdKey, base::NumberToString(layout.primary_id)); base::Value::List placement_list; for (const auto& placement : layout.placement_list) { base::Value::Dict placement_value; placement_value.Set(kPositionKey, DisplayPlacement::PositionToString(placement.position)); placement_value.Set(kOffsetKey, placement.offset); placement_value.Set(kDisplayPlacementDisplayIdKey, base::NumberToString(placement.display_id)); placement_value.Set(kDisplayPlacementParentDisplayIdKey, base::NumberToString(placement.parent_display_id)); placement_list.Append(std::move(placement_value)); } dict.Set(kDisplayPlacementKey, std::move(placement_list)); } } // namespace display