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 16 namespace ash { 17 namespace { 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. 21 const int kMaxValidOffset = 10000; 22 23 // Persistent key names 24 const char kPositionKey[] = "position"; 25 const char kOffsetKey[] = "offset"; 26 const char kMirroredKey[] = "mirrored"; 27 const char kPrimaryIdKey[] = "primary-id"; 28 29 typedef std::map<DisplayLayout::Position, std::string> PositionToStringMap; 30 31 const 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 40 bool 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 48 std::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 54 bool GetDisplayIdFromString(const base::StringPiece& position, int64* field) { 55 return base::StringToInt64(position, field); 56 } 57 58 } // namespace 59 60 //////////////////////////////////////////////////////////////////////////////// 61 // DisplayLayout 62 63 // static 64 DisplayLayout DisplayLayout::FromInts(int position, int offsets) { 65 return DisplayLayout(static_cast<Position>(position), offsets); 66 } 67 68 DisplayLayout::DisplayLayout() 69 : position(RIGHT), 70 offset(0), 71 mirrored(false), 72 primary_id(gfx::Display::kInvalidDisplayID) { 73 } 74 75 DisplayLayout::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 91 DisplayLayout 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 113 bool DisplayLayout::ConvertFromValue(const base::Value& value, 114 DisplayLayout* layout) { 115 base::JSONValueConverter<DisplayLayout> converter; 116 return converter.Convert(value, layout); 117 } 118 119 // static 120 bool 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 134 std::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 142 void 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