1// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "ash/display/display_layout.h" 6 7#include "ash/display/display_pref_util.h" 8#include "base/json/json_value_converter.h" 9#include "base/logging.h" 10#include "base/strings/string_number_conversions.h" 11#include "base/strings/string_piece.h" 12#include "base/strings/stringprintf.h" 13#include "base/values.h" 14#include "ui/gfx/display.h" 15 16namespace ash { 17namespace { 18 19// The maximum value for 'offset' in DisplayLayout in case of outliers. Need 20// to change this value in case to support even larger displays. 21const int kMaxValidOffset = 10000; 22 23// Persistent key names 24const char kPositionKey[] = "position"; 25const char kOffsetKey[] = "offset"; 26const char kMirroredKey[] = "mirrored"; 27const char kPrimaryIdKey[] = "primary-id"; 28 29typedef std::map<DisplayLayout::Position, std::string> PositionToStringMap; 30 31const PositionToStringMap* GetPositionToStringMap() { 32 static const PositionToStringMap* map = CreateToStringMap( 33 DisplayLayout::TOP, "top", 34 DisplayLayout::BOTTOM, "bottom", 35 DisplayLayout::RIGHT, "right", 36 DisplayLayout::LEFT, "left"); 37 return map; 38} 39 40bool GetPositionFromString(const base::StringPiece& position, 41 DisplayLayout::Position* field) { 42 if (ReverseFind(GetPositionToStringMap(), position, field)) 43 return true; 44 LOG(ERROR) << "Invalid position value:" << position; 45 return false; 46} 47 48std::string GetStringFromPosition(DisplayLayout::Position position) { 49 const PositionToStringMap* map = GetPositionToStringMap(); 50 PositionToStringMap::const_iterator iter = map->find(position); 51 return iter != map->end() ? iter->second : std::string("unknown"); 52} 53 54bool GetDisplayIdFromString(const base::StringPiece& position, int64* field) { 55 return base::StringToInt64(position, field); 56} 57 58} // namespace 59 60//////////////////////////////////////////////////////////////////////////////// 61// DisplayLayout 62 63// static 64DisplayLayout DisplayLayout::FromInts(int position, int offsets) { 65 return DisplayLayout(static_cast<Position>(position), offsets); 66} 67 68DisplayLayout::DisplayLayout() 69 : position(RIGHT), 70 offset(0), 71 mirrored(false), 72 primary_id(gfx::Display::kInvalidDisplayID) { 73} 74 75DisplayLayout::DisplayLayout(DisplayLayout::Position position, int offset) 76 : position(position), 77 offset(offset), 78 mirrored(false), 79 primary_id(gfx::Display::kInvalidDisplayID) { 80 DCHECK_LE(TOP, position); 81 DCHECK_GE(LEFT, position); 82 83 // Set the default value to |position| in case position is invalid. DCHECKs 84 // above doesn't stop in Release builds. 85 if (TOP > position || LEFT < position) 86 this->position = RIGHT; 87 88 DCHECK_GE(kMaxValidOffset, abs(offset)); 89} 90 91DisplayLayout DisplayLayout::Invert() const { 92 Position inverted_position = RIGHT; 93 switch (position) { 94 case TOP: 95 inverted_position = BOTTOM; 96 break; 97 case BOTTOM: 98 inverted_position = TOP; 99 break; 100 case RIGHT: 101 inverted_position = LEFT; 102 break; 103 case LEFT: 104 inverted_position = RIGHT; 105 break; 106 } 107 DisplayLayout ret = DisplayLayout(inverted_position, -offset); 108 ret.primary_id = primary_id; 109 return ret; 110} 111 112// static 113bool DisplayLayout::ConvertFromValue(const base::Value& value, 114 DisplayLayout* layout) { 115 base::JSONValueConverter<DisplayLayout> converter; 116 return converter.Convert(value, layout); 117} 118 119// static 120bool DisplayLayout::ConvertToValue(const DisplayLayout& layout, 121 base::Value* value) { 122 base::DictionaryValue* dict_value = NULL; 123 if (!value->GetAsDictionary(&dict_value) || dict_value == NULL) 124 return false; 125 126 const std::string position_str = GetStringFromPosition(layout.position); 127 dict_value->SetString(kPositionKey, position_str); 128 dict_value->SetInteger(kOffsetKey, layout.offset); 129 dict_value->SetBoolean(kMirroredKey, layout.mirrored); 130 dict_value->SetString(kPrimaryIdKey, base::Int64ToString(layout.primary_id)); 131 return true; 132} 133 134std::string DisplayLayout::ToString() const { 135 const std::string position_str = GetStringFromPosition(position); 136 return base::StringPrintf( 137 "%s, %d%s", 138 position_str.c_str(), offset, mirrored ? ", mirrored" : ""); 139} 140 141// static 142void DisplayLayout::RegisterJSONConverter( 143 base::JSONValueConverter<DisplayLayout>* converter) { 144 converter->RegisterCustomField<Position>( 145 kPositionKey, &DisplayLayout::position, &GetPositionFromString); 146 converter->RegisterIntField(kOffsetKey, &DisplayLayout::offset); 147 converter->RegisterBoolField(kMirroredKey, &DisplayLayout::mirrored); 148 converter->RegisterCustomField<int64>( 149 kPrimaryIdKey, &DisplayLayout::primary_id, &GetDisplayIdFromString); 150} 151 152} // namespace ash 153