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