Home | History | Annotate | Download | only in display
      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