• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GetPositionToStringMap()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 
GetPositionFromString(const base::StringPiece & position,DisplayLayout::Position * field)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 
GetStringFromPosition(DisplayLayout::Position position)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 
GetDisplayIdFromString(const base::StringPiece & position,int64 * field)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
FromInts(int position,int offsets)64 DisplayLayout DisplayLayout::FromInts(int position, int offsets) {
65   return DisplayLayout(static_cast<Position>(position), offsets);
66 }
67 
DisplayLayout()68 DisplayLayout::DisplayLayout()
69     : position(RIGHT),
70       offset(0),
71       mirrored(false),
72       primary_id(gfx::Display::kInvalidDisplayID) {
73 }
74 
DisplayLayout(DisplayLayout::Position position,int offset)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 
Invert() const91 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
ConvertFromValue(const base::Value & value,DisplayLayout * layout)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
ConvertToValue(const DisplayLayout & layout,base::Value * value)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 
ToString() const134 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
RegisterJSONConverter(base::JSONValueConverter<DisplayLayout> * converter)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